| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | #include <errno.h> | 
|  | 2 | #include <nss.h> | 
|  | 3 | #include <pthread.h> | 
|  | 4 | #include <string.h> | 
|  | 5 |  | 
|  | 6 |  | 
|  | 7 | #define COPY_IF_ROOM(s) \ | 
|  | 8 | ({ size_t len_ = strlen (s) + 1;		\ | 
|  | 9 | char *start_ = cp;				\ | 
|  | 10 | buflen - (cp - buffer) < len_		\ | 
|  | 11 | ? NULL					\ | 
|  | 12 | : (cp = mempcpy (cp, s, len_), start_); }) | 
|  | 13 |  | 
|  | 14 |  | 
|  | 15 | /* Password handling.  */ | 
|  | 16 | #include <pwd.h> | 
|  | 17 |  | 
|  | 18 | static struct passwd pwd_data[] = | 
|  | 19 | { | 
|  | 20 | #define PWD(u) \ | 
|  | 21 | { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u,  \ | 
|  | 22 | .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*",	      \ | 
|  | 23 | .pw_shell = (char *) "*" } | 
|  | 24 | PWD (100), | 
|  | 25 | PWD (30), | 
|  | 26 | PWD (200), | 
|  | 27 | PWD (60), | 
|  | 28 | PWD (20000) | 
|  | 29 | }; | 
|  | 30 | #define npwd_data (sizeof (pwd_data) / sizeof (pwd_data[0])) | 
|  | 31 |  | 
|  | 32 | static size_t pwd_iter; | 
|  | 33 | #define CURPWD pwd_data[pwd_iter] | 
|  | 34 |  | 
|  | 35 | static pthread_mutex_t pwd_lock = PTHREAD_MUTEX_INITIALIZER; | 
|  | 36 |  | 
|  | 37 |  | 
|  | 38 | enum nss_status | 
|  | 39 | _nss_test1_setpwent (int stayopen) | 
|  | 40 | { | 
|  | 41 | pwd_iter = 0; | 
|  | 42 | return NSS_STATUS_SUCCESS; | 
|  | 43 | } | 
|  | 44 |  | 
|  | 45 |  | 
|  | 46 | enum nss_status | 
|  | 47 | _nss_test1_endpwent (void) | 
|  | 48 | { | 
|  | 49 | return NSS_STATUS_SUCCESS; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 |  | 
|  | 53 | enum nss_status | 
|  | 54 | _nss_test1_getpwent_r (struct passwd *result, char *buffer, size_t buflen, | 
|  | 55 | int *errnop) | 
|  | 56 | { | 
|  | 57 | char *cp = buffer; | 
|  | 58 | int res = NSS_STATUS_SUCCESS; | 
|  | 59 |  | 
|  | 60 | pthread_mutex_lock (&pwd_lock); | 
|  | 61 |  | 
|  | 62 | if (pwd_iter >= npwd_data) | 
|  | 63 | res = NSS_STATUS_NOTFOUND; | 
|  | 64 | else | 
|  | 65 | { | 
|  | 66 | result->pw_name = COPY_IF_ROOM (CURPWD.pw_name); | 
|  | 67 | result->pw_passwd = COPY_IF_ROOM (CURPWD.pw_passwd); | 
|  | 68 | result->pw_uid = CURPWD.pw_uid; | 
|  | 69 | result->pw_gid = CURPWD.pw_gid; | 
|  | 70 | result->pw_gecos = COPY_IF_ROOM (CURPWD.pw_gecos); | 
|  | 71 | result->pw_dir = COPY_IF_ROOM (CURPWD.pw_dir); | 
|  | 72 | result->pw_shell = COPY_IF_ROOM (CURPWD.pw_shell); | 
|  | 73 |  | 
|  | 74 | if (result->pw_name == NULL || result->pw_passwd == NULL | 
|  | 75 | || result->pw_gecos == NULL || result->pw_dir == NULL | 
|  | 76 | || result->pw_shell == NULL) | 
|  | 77 | { | 
|  | 78 | *errnop = ERANGE; | 
|  | 79 | res = NSS_STATUS_TRYAGAIN; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | ++pwd_iter; | 
|  | 83 | } | 
|  | 84 |  | 
|  | 85 | pthread_mutex_unlock (&pwd_lock); | 
|  | 86 |  | 
|  | 87 | return res; | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 |  | 
|  | 91 | enum nss_status | 
|  | 92 | _nss_test1_getpwuid_r (uid_t uid, struct passwd *result, char *buffer, | 
|  | 93 | size_t buflen, int *errnop) | 
|  | 94 | { | 
|  | 95 | for (size_t idx = 0; idx < npwd_data; ++idx) | 
|  | 96 | if (pwd_data[idx].pw_uid == uid) | 
|  | 97 | { | 
|  | 98 | char *cp = buffer; | 
|  | 99 | int res = NSS_STATUS_SUCCESS; | 
|  | 100 |  | 
|  | 101 | result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name); | 
|  | 102 | result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd); | 
|  | 103 | result->pw_uid = pwd_data[idx].pw_uid; | 
|  | 104 | result->pw_gid = pwd_data[idx].pw_gid; | 
|  | 105 | result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos); | 
|  | 106 | result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir); | 
|  | 107 | result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell); | 
|  | 108 |  | 
|  | 109 | if (result->pw_name == NULL || result->pw_passwd == NULL | 
|  | 110 | || result->pw_gecos == NULL || result->pw_dir == NULL | 
|  | 111 | || result->pw_shell == NULL) | 
|  | 112 | { | 
|  | 113 | *errnop = ERANGE; | 
|  | 114 | res = NSS_STATUS_TRYAGAIN; | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | return res; | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | return NSS_STATUS_NOTFOUND; | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 |  | 
|  | 124 | enum nss_status | 
|  | 125 | _nss_test1_getpwnam_r (const char *name, struct passwd *result, char *buffer, | 
|  | 126 | size_t buflen, int *errnop) | 
|  | 127 | { | 
|  | 128 | for (size_t idx = 0; idx < npwd_data; ++idx) | 
|  | 129 | if (strcmp (pwd_data[idx].pw_name, name) == 0) | 
|  | 130 | { | 
|  | 131 | char *cp = buffer; | 
|  | 132 | int res = NSS_STATUS_SUCCESS; | 
|  | 133 |  | 
|  | 134 | result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name); | 
|  | 135 | result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd); | 
|  | 136 | result->pw_uid = pwd_data[idx].pw_uid; | 
|  | 137 | result->pw_gid = pwd_data[idx].pw_gid; | 
|  | 138 | result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos); | 
|  | 139 | result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir); | 
|  | 140 | result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell); | 
|  | 141 |  | 
|  | 142 | if (result->pw_name == NULL || result->pw_passwd == NULL | 
|  | 143 | || result->pw_gecos == NULL || result->pw_dir == NULL | 
|  | 144 | || result->pw_shell == NULL) | 
|  | 145 | { | 
|  | 146 | *errnop = ERANGE; | 
|  | 147 | res = NSS_STATUS_TRYAGAIN; | 
|  | 148 | } | 
|  | 149 |  | 
|  | 150 | return res; | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | return NSS_STATUS_NOTFOUND; | 
|  | 154 | } |