| OLD | NEW |
| 1 #include <pthread.h> | 1 #include <pthread.h> |
| 2 #include <byteswap.h> | 2 #include <byteswap.h> |
| 3 #include <string.h> | 3 #include <string.h> |
| 4 #include <unistd.h> | 4 #include <unistd.h> |
| 5 #include "pwf.h" | 5 #include "pwf.h" |
| 6 #include "nscd.h" | 6 #include "nscd.h" |
| 7 | 7 |
| 8 static char *itoa(char *p, uint32_t x) | 8 static char *itoa(char *p, uint32_t x) |
| 9 { | 9 { |
| 10 // number of digits in a uint32_t + NUL | 10 // number of digits in a uint32_t + NUL |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); | 28 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
| 29 | 29 |
| 30 f = fopen("/etc/passwd", "rbe"); | 30 f = fopen("/etc/passwd", "rbe"); |
| 31 if (!f) { | 31 if (!f) { |
| 32 rv = errno; | 32 rv = errno; |
| 33 goto done; | 33 goto done; |
| 34 } | 34 } |
| 35 | 35 |
| 36 while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) { | 36 while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) { |
| 37 » » if (name && !strcmp(name, (*res)->pw_name) | 37 » » if ((name && !strcmp(name, (*res)->pw_name)) |
| 38 » » || !name && (*res)->pw_uid == uid) | 38 » » || (!name && (*res)->pw_uid == uid)) |
| 39 break; | 39 break; |
| 40 } | 40 } |
| 41 fclose(f); | 41 fclose(f); |
| 42 | 42 |
| 43 if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) { | 43 if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) { |
| 44 int32_t req = name ? GETPWBYNAME : GETPWBYUID; | 44 int32_t req = name ? GETPWBYNAME : GETPWBYUID; |
| 45 const char *key; | 45 const char *key; |
| 46 int32_t passwdbuf[PW_LEN] = {0}; | 46 int32_t passwdbuf[PW_LEN] = {0}; |
| 47 size_t len = 0; | 47 size_t len = 0; |
| 48 char uidbuf[11] = {0}; | 48 char uidbuf[11] = {0}; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 /* Don't assume that nscd made sure to null terminate strings. | 115 /* Don't assume that nscd made sure to null terminate strings. |
| 116 * It's supposed to, but malicious nscd should be ignored | 116 * It's supposed to, but malicious nscd should be ignored |
| 117 * rather than causing a crash. | 117 * rather than causing a crash. |
| 118 */ | 118 */ |
| 119 if (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1] | 119 if (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1] |
| 120 || pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) { | 120 || pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) { |
| 121 rv = EIO; | 121 rv = EIO; |
| 122 goto cleanup_f; | 122 goto cleanup_f; |
| 123 } | 123 } |
| 124 | 124 |
| 125 » » if (name && strcmp(name, pw->pw_name) | 125 » » if ((name && strcmp(name, pw->pw_name)) |
| 126 » » || !name && uid != pw->pw_uid) { | 126 » » || (!name && uid != pw->pw_uid)) { |
| 127 rv = EIO; | 127 rv = EIO; |
| 128 goto cleanup_f; | 128 goto cleanup_f; |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 *res = pw; | 132 *res = pw; |
| 133 cleanup_f: | 133 cleanup_f: |
| 134 fclose(f); | 134 fclose(f); |
| 135 goto done; | 135 goto done; |
| 136 } | 136 } |
| 137 | 137 |
| 138 done: | 138 done: |
| 139 pthread_setcancelstate(cs, 0); | 139 pthread_setcancelstate(cs, 0); |
| 140 if (rv) errno = rv; | 140 if (rv) errno = rv; |
| 141 return rv; | 141 return rv; |
| 142 } | 142 } |
| OLD | NEW |