- Timestamp:
- Jun 7, 2011, 12:58:14 PM (13 years ago)
- Location:
- branches/fc15-dev
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/fc15-dev
- Property svn:mergeinfo changed
/trunk (added) merged: 1811,1813-1819,1821-1825,1838,1848-1856,1858-1872,1877
- Property svn:mergeinfo changed
-
branches/fc15-dev/server/common/oursrc/nss_nonlocal/nonlocal-passwd.c
r1553 r1878 50 50 51 51 52 static service_user * 53 nss_passwd_nonlocal_database(void) 54 { 55 static service_user *nip = NULL; 56 if (nip == NULL) 57 __nss_database_lookup("passwd_nonlocal", NULL, "", &nip); 58 59 return nip; 52 static service_user *__nss_passwd_nonlocal_database; 53 54 static int 55 internal_function 56 __nss_passwd_nonlocal_lookup(service_user **ni, const char *fct_name, 57 void **fctp) 58 { 59 if (__nss_passwd_nonlocal_database == NULL 60 && __nss_database_lookup("passwd_nonlocal", NULL, NULL, 61 &__nss_passwd_nonlocal_database) < 0) 62 return -1; 63 64 *ni = __nss_passwd_nonlocal_database; 65 66 *fctp = __nss_lookup_function(*ni, fct_name); 67 return 0; 60 68 } 61 69 … … 64 72 check_nonlocal_uid(const char *user, uid_t uid, int *errnop) 65 73 { 66 static const char *fct_name = "getpwuid_r"; 67 static service_user *startp = NULL; 68 static void *fct_start = NULL; 69 enum nss_status status; 70 service_user *nip; 71 union { 72 enum nss_status (*l)(uid_t uid, struct passwd *pwd, 73 char *buffer, size_t buflen, int *errnop); 74 void *ptr; 75 } fct; 74 enum nss_status status; 76 75 struct passwd pwbuf; 77 int old_errno = errno; 78 76 char *buf; 79 77 size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); 80 char *buf = malloc(buflen); 81 if (buf == NULL) { 82 *errnop = ENOMEM; 83 errno = old_errno; 84 return NSS_STATUS_TRYAGAIN; 85 } 86 87 if (fct_start == NULL && 88 __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) { 89 free(buf); 90 return NSS_STATUS_UNAVAIL; 91 } 92 nip = startp; 93 fct.ptr = fct_start; 94 do { 95 morebuf: 96 if (fct.l == _nss_nonlocal_getpwuid_r) 97 status = NSS_STATUS_NOTFOUND; 98 else 99 status = DL_CALL_FCT(fct.l, (uid, &pwbuf, buf, buflen, errnop)); 100 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) { 101 free(buf); 102 buflen *= 2; 103 buf = malloc(buflen); 104 if (buf == NULL) { 105 *errnop = ENOMEM; 106 errno = old_errno; 107 return NSS_STATUS_TRYAGAIN; 108 } 109 goto morebuf; 110 } 111 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0); 78 const struct walk_nss w = { 79 .lookup = &__nss_passwd_lookup, .fct_name = "getpwuid_r", 80 .status = &status, .errnop = errnop, .buf = &buf, .buflen = &buflen 81 }; 82 const __typeof__(&_nss_nonlocal_getpwuid_r) self = &_nss_nonlocal_getpwuid_r; 83 #define args (uid, &pwbuf, buf, buflen, errnop) 84 #include "walk_nss.h" 85 #undef args 112 86 113 87 if (status == NSS_STATUS_SUCCESS) { 114 88 syslog(LOG_ERR, "nss_nonlocal: possible spoofing attack: non-local user %s has same UID as local user %s!\n", user, pwbuf.pw_name); 89 free(buf); 115 90 status = NSS_STATUS_NOTFOUND; 116 91 } else if (status != NSS_STATUS_TRYAGAIN) { … … 118 93 } 119 94 120 free(buf);121 95 return status; 122 96 } … … 132 106 errno = 0; 133 107 uid = strtoul(pwd->pw_name, &end, 10); 134 if (errno == 0 && *end == '\0' && (uid_t)uid == uid) 108 if (errno == 0 && *end == '\0' && (uid_t)uid == uid) { 109 errno = old_errno; 135 110 status = check_nonlocal_uid(user, uid, errnop); 136 errno = old_errno; 111 } else { 112 errno = old_errno; 113 } 137 114 if (status != NSS_STATUS_SUCCESS) 138 115 return status; … … 144 121 check_nonlocal_user(const char *user, int *errnop) 145 122 { 146 static const char *fct_name = "getpwnam_r"; 147 static service_user *startp = NULL; 148 static void *fct_start = NULL; 149 enum nss_status status; 150 service_user *nip; 151 union { 152 enum nss_status (*l)(const char *name, struct passwd *pwd, 153 char *buffer, size_t buflen, int *errnop); 154 void *ptr; 155 } fct; 123 enum nss_status status; 156 124 struct passwd pwbuf; 157 int old_errno = errno; 158 125 char *buf; 159 126 size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); 160 char *buf = malloc(buflen); 161 if (buf == NULL) { 162 *errnop = ENOMEM; 163 errno = old_errno; 164 return NSS_STATUS_TRYAGAIN; 165 } 166 167 if (fct_start == NULL && 168 __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) { 127 const struct walk_nss w = { 128 .lookup = __nss_passwd_lookup, .fct_name = "getpwnam_r", 129 .status = &status, .errnop = errnop, .buf = &buf, .buflen = &buflen 130 }; 131 const __typeof__(&_nss_nonlocal_getpwnam_r) self = &_nss_nonlocal_getpwnam_r; 132 #define args (user, &pwbuf, buf, buflen, errnop) 133 #include "walk_nss.h" 134 #undef args 135 136 if (status == NSS_STATUS_SUCCESS) { 169 137 free(buf); 170 return NSS_STATUS_UNAVAIL;171 }172 nip = startp;173 fct.ptr = fct_start;174 do {175 morebuf:176 if (fct.l == _nss_nonlocal_getpwnam_r)177 status = NSS_STATUS_NOTFOUND;178 else179 status = DL_CALL_FCT(fct.l, (user, &pwbuf, buf, buflen, errnop));180 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {181 free(buf);182 buflen *= 2;183 buf = malloc(buflen);184 if (buf == NULL) {185 *errnop = ENOMEM;186 errno = old_errno;187 return NSS_STATUS_TRYAGAIN;188 }189 goto morebuf;190 }191 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);192 193 if (status == NSS_STATUS_SUCCESS)194 138 status = NSS_STATUS_NOTFOUND; 195 else if (status != NSS_STATUS_TRYAGAIN)139 } else if (status != NSS_STATUS_TRYAGAIN) { 196 140 status = NSS_STATUS_SUCCESS; 197 198 free(buf); 141 } 142 199 143 return status; 200 144 } 201 145 202 203 static service_user *pwent_nip = NULL; 146 enum nss_status 147 get_nonlocal_passwd(const char *name, struct passwd *pwd, char **buffer, 148 int *errnop) 149 { 150 enum nss_status status; 151 size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); 152 const struct walk_nss w = { 153 .lookup = __nss_passwd_nonlocal_lookup, .fct_name = "getpwnam_r", 154 .status = &status, .errnop = errnop, .buf = buffer, .buflen = &buflen 155 }; 156 const __typeof__(&_nss_nonlocal_getpwnam_r) self = NULL; 157 #define args (name, pwd, *buffer, buflen, errnop) 158 #include "walk_nss.h" 159 #undef args 160 return status; 161 } 162 163 164 static service_user *pwent_startp, *pwent_nip; 204 165 static void *pwent_fct_start; 205 166 static union { … … 213 174 _nss_nonlocal_setpwent(int stayopen) 214 175 { 215 static const char *fct_name = "setpwent"; 216 static void *fct_start = NULL; 217 enum nss_status status; 218 service_user *nip; 219 union { 220 enum nss_status (*l)(int stayopen); 221 void *ptr; 222 } fct; 223 224 nip = nss_passwd_nonlocal_database(); 225 if (nip == NULL) 226 return NSS_STATUS_UNAVAIL; 227 if (fct_start == NULL) 228 fct_start = __nss_lookup_function(nip, fct_name); 229 fct.ptr = fct_start; 230 do { 231 if (fct.ptr == NULL) 232 status = NSS_STATUS_UNAVAIL; 233 else 234 status = DL_CALL_FCT(fct.l, (stayopen)); 235 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0); 236 if (status != NSS_STATUS_SUCCESS) 237 return status; 238 239 pwent_nip = nip; 176 enum nss_status status; 177 const struct walk_nss w = { 178 .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "setpwent", 179 .status = &status 180 }; 181 const __typeof__(&_nss_nonlocal_setpwent) self = NULL; 182 #define args (stayopen) 183 #include "walk_nss.h" 184 #undef args 185 if (status != NSS_STATUS_SUCCESS) 186 return status; 187 240 188 if (pwent_fct_start == NULL) 241 pwent_fct_start = __nss_lookup_function(nip, pwent_fct_name); 189 __nss_passwd_nonlocal_lookup(&pwent_startp, pwent_fct_name, 190 &pwent_fct_start); 191 pwent_nip = pwent_startp; 242 192 pwent_fct.ptr = pwent_fct_start; 243 193 return NSS_STATUS_SUCCESS; … … 247 197 _nss_nonlocal_endpwent(void) 248 198 { 249 static const char *fct_name = "endpwent"; 250 static void *fct_start = NULL; 251 enum nss_status status; 252 service_user *nip; 253 union { 254 enum nss_status (*l)(void); 255 void *ptr; 256 } fct; 199 enum nss_status status; 200 const struct walk_nss w = { 201 .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "endpwent", 202 .status = &status 203 }; 204 const __typeof__(&_nss_nonlocal_endpwent) self = NULL; 257 205 258 206 pwent_nip = NULL; 259 207 260 nip = nss_passwd_nonlocal_database(); 261 if (nip == NULL) 262 return NSS_STATUS_UNAVAIL; 263 if (fct_start == NULL) 264 fct_start = __nss_lookup_function(nip, fct_name); 265 fct.ptr = fct_start; 266 do { 267 if (fct.ptr == NULL) 268 status = NSS_STATUS_UNAVAIL; 269 else 270 status = DL_CALL_FCT(fct.l, ()); 271 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0); 208 #define args () 209 #include "walk_nss.h" 210 #undef args 272 211 return status; 273 212 } … … 314 253 char *buffer, size_t buflen, int *errnop) 315 254 { 316 static const char *fct_name = "getpwnam_r"; 317 static void *fct_start = NULL; 318 enum nss_status status; 319 service_user *nip; 320 union { 321 enum nss_status (*l)(const char *name, struct passwd *pwd, 322 char *buffer, size_t buflen, int *errnop); 323 void *ptr; 324 } fct; 255 enum nss_status status; 325 256 int group_errno; 257 const struct walk_nss w = { 258 .lookup = __nss_passwd_nonlocal_lookup, .fct_name = "getpwnam_r", 259 .status = &status, .errnop = errnop 260 }; 261 const __typeof__(&_nss_nonlocal_getpwnam_r) self = NULL; 326 262 327 263 char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV); … … 329 265 return NSS_STATUS_UNAVAIL; 330 266 331 nip = nss_passwd_nonlocal_database(); 332 if (nip == NULL) 333 return NSS_STATUS_UNAVAIL; 334 if (fct_start == NULL) 335 fct_start = __nss_lookup_function(nip, fct_name); 336 fct.ptr = fct_start; 337 do { 338 if (fct.ptr == NULL) 339 status = NSS_STATUS_UNAVAIL; 340 else 341 status = DL_CALL_FCT(fct.l, (name, pwd, buffer, buflen, errnop)); 342 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) 343 break; 344 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0); 267 #define args (name, pwd, buffer, buflen, errnop) 268 #include "walk_nss.h" 269 #undef args 345 270 if (status != NSS_STATUS_SUCCESS) 346 271 return status; … … 355 280 return status; 356 281 357 if (check_nonlocal_gid(name, pwd->pw_gid, &group_errno) !=282 if (check_nonlocal_gid(name, NULL, pwd->pw_gid, &group_errno) != 358 283 NSS_STATUS_SUCCESS) 359 284 pwd->pw_gid = 65534 /* nogroup */; … … 365 290 char *buffer, size_t buflen, int *errnop) 366 291 { 367 static const char *fct_name = "getpwuid_r"; 368 static void *fct_start = NULL; 369 enum nss_status status; 370 service_user *nip; 371 union { 372 enum nss_status (*l)(uid_t uid, struct passwd *pwd, 373 char *buffer, size_t buflen, int *errnop); 374 void *ptr; 375 } fct; 292 enum nss_status status; 376 293 int group_errno; 294 const struct walk_nss w = { 295 .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "getpwuid_r", 296 .status = &status, .errnop = errnop 297 }; 298 const __typeof__(&_nss_nonlocal_getpwuid_r) self = NULL; 377 299 378 300 char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV); … … 380 302 return NSS_STATUS_UNAVAIL; 381 303 382 nip = nss_passwd_nonlocal_database(); 383 if (nip == NULL) 384 return NSS_STATUS_UNAVAIL; 385 if (fct_start == NULL) 386 fct_start = __nss_lookup_function(nip, fct_name); 387 fct.ptr = fct_start; 388 do { 389 if (fct.ptr == NULL) 390 status = NSS_STATUS_UNAVAIL; 391 else 392 status = DL_CALL_FCT(fct.l, (uid, pwd, buffer, buflen, errnop)); 393 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) 394 break; 395 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0); 304 #define args (uid, pwd, buffer, buflen, errnop) 305 #include "walk_nss.h" 306 #undef args 396 307 if (status != NSS_STATUS_SUCCESS) 397 308 return status; … … 406 317 return status; 407 318 408 if (check_nonlocal_gid(pwd->pw_name, pwd->pw_gid, &group_errno) !=319 if (check_nonlocal_gid(pwd->pw_name, NULL, pwd->pw_gid, &group_errno) != 409 320 NSS_STATUS_SUCCESS) 410 321 pwd->pw_gid = 65534 /* nogroup */;
Note: See TracChangeset
for help on using the changeset viewer.