diff options
Diffstat (limited to 'nis/nss_compat')
-rw-r--r-- | nis/nss_compat/compat-pwd.c | 379 |
1 files changed, 195 insertions, 184 deletions
diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c index f4e0720fb9..88594139a6 100644 --- a/nis/nss_compat/compat-pwd.c +++ b/nis/nss_compat/compat-pwd.c @@ -494,7 +494,8 @@ getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent, return NSS_STATUS_TRYAGAIN; } - if (parse_res) + if (parse_res && !in_blacklist (result->pw_name, + strlen (result->pw_name), ent)) { /* Store the User in the blacklist for the "+" at the end of /etc/passwd */ @@ -590,7 +591,8 @@ getpwent_next_nisplus_netgr (const char *name, struct passwd *result, } nis_freeresult (nisres); - if (parse_res) + if (parse_res && !in_blacklist (result->pw_name, + strlen (result->pw_name), ent)) { /* Store the User in the blacklist for the "+" at the end of /etc/passwd */ @@ -812,8 +814,8 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer, /* This function handle the +user entrys in /etc/passwd */ static enum nss_status -getpwnam_plususer (const char *name, struct passwd *result, char *buffer, - size_t buflen, int *errnop) +getpwnam_plususer (const char *name, struct passwd *result, ent_t *ent, + char *buffer, size_t buflen, int *errnop) { struct parser_data *data = (void *) buffer; struct passwd pwd; @@ -850,13 +852,20 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer, } parse_res = _nss_nisplus_parse_pwent (res, result, buffer, buflen, errnop); + + nis_freeresult (res); + if (parse_res == -1) { - nis_freeresult (res); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - nis_freeresult (res); + + if (in_blacklist (result->pw_name, strlen (result->pw_name), ent)) + { + *errnop = ENOENT; + return NSS_STATUS_NOTFOUND; + } } else /* Use NIS */ { @@ -886,13 +895,22 @@ getpwnam_plususer (const char *name, struct passwd *result, char *buffer, *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } + ptr = strncpy (buffer, outval, buflen); free (outval); + while (isspace (*ptr)) ptr++; + parse_res = _nss_files_parse_pwent (ptr, result, data, buflen, errnop); if (parse_res == -1) return NSS_STATUS_TRYAGAIN; + + if (in_blacklist (result->pw_name, strlen (result->pw_name), ent)) + { + *errnop = ENOENT; + return NSS_STATUS_NOTFOUND; + } } if (parse_res > 0) @@ -989,7 +1007,7 @@ getpwent_next_file (struct passwd *result, ent_t *ent, if (result->pw_name[0] == '+' && result->pw_name[1] == '@' && result->pw_name[2] != '\0') { - int status; + enum nss_status status; ent->netgroup = TRUE; ent->first = TRUE; @@ -1025,13 +1043,16 @@ getpwent_next_file (struct passwd *result, ent_t *ent, if (result->pw_name[0] == '+' && result->pw_name[1] != '\0' && result->pw_name[1] != '@') { + char buf[strlen (result->pw_name)]; enum nss_status status; /* Store the User in the blacklist for the "+" at the end of /etc/passwd */ - blacklist_store_name (&result->pw_name[1], ent); - status = getpwnam_plususer (&result->pw_name[1], result, buffer, - buflen, errnop); + strcpy (buf, &result->pw_name[1]); + status = getpwnam_plususer (&result->pw_name[1], result, ent, + buffer, buflen, errnop); + blacklist_store_name (buf, ent); + if (status == NSS_STATUS_SUCCESS) /* We found the entry. */ break; else @@ -1074,7 +1095,7 @@ internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer, { if (ent->netgroup) { - int status; + enum nss_status status; /* We are searching members in a netgroup */ /* Since this is not the first call, we don't need the group name */ @@ -1191,21 +1212,8 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent, if (result->pw_name[0] == '-' && result->pw_name[1] == '@' && result->pw_name[2] != '\0') { - /* XXX Do not use fixed length buffers. */ - char buf2[1024]; - char *user, *host, *domain; - struct __netgrent netgrdata; - - bzero (&netgrdata, sizeof (struct __netgrent)); - __internal_setnetgrent (&result->pw_name[2], &netgrdata); - while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata, - buf2, sizeof (buf2), errnop)) - { - if (user != NULL && user[0] != '-') - if (strcmp (user, name) == 0) - return NSS_STATUS_NOTFOUND; - } - __internal_endnetgrent (&netgrdata); + if (innetgr (&result->pw_name[2], NULL, name, NULL)) + return NSS_STATUS_NOTFOUND; continue; } @@ -1213,29 +1221,18 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent, if (result->pw_name[0] == '+' && result->pw_name[1] == '@' && result->pw_name[2] != '\0') { - char buf[strlen (result->pw_name)]; - int status; - - strcpy (buf, &result->pw_name[2]); - ent->netgroup = TRUE; - ent->first = TRUE; - copy_pwd_changes (&ent->pwd, result, NULL, 0); + enum nss_status status; - do + if (innetgr (&result->pw_name[2], NULL, name, NULL)) { - if (use_nisplus) - status = getpwent_next_nisplus_netgr (name, result, ent, buf, - buffer, buflen, errnop); - else - status = getpwent_next_nis_netgr (name, result, ent, buf, - buffer, buflen, errnop); - if (status == NSS_STATUS_RETURN) - continue; + status = getpwnam_plususer (name, result, ent, buffer, + buflen, errnop); - if (status == NSS_STATUS_SUCCESS && - strcmp (result->pw_name, name) == 0) - return NSS_STATUS_SUCCESS; - } while (status == NSS_STATUS_SUCCESS); + if (status == NSS_STATUS_RETURN) + continue; + + return status; + } continue; } @@ -1260,7 +1257,7 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent, { enum nss_status status; - status = getpwnam_plususer (name, result, buffer, buflen, + status = getpwnam_plususer (name, result, ent, buffer, buflen, errnop); if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */ @@ -1275,7 +1272,8 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent, { enum nss_status status; - status = getpwnam_plususer (name, result, buffer, buflen, errnop); + status = getpwnam_plususer (name, result, ent, + buffer, buflen, errnop); if (status == NSS_STATUS_SUCCESS) /* We found the entry. */ break; else @@ -1326,7 +1324,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd, /* This function handle the + entry in /etc/passwd for getpwuid */ static enum nss_status getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer, - size_t buflen, int *errnop) + size_t buflen, int *errnop) { struct parser_data *data = (void *) buffer; struct passwd pwd; @@ -1355,19 +1353,19 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer, snprintf(buf, sizeof (buf), "[uid=%d],%s", uid, pwdtable); res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); if (niserr2nss (res->status) != NSS_STATUS_SUCCESS) - { - enum nss_status status = niserr2nss (res->status); + { + enum nss_status status = niserr2nss (res->status); - nis_freeresult (res); - return status; - } + nis_freeresult (res); + return status; + } if ((parse_res = _nss_nisplus_parse_pwent (res, result, buffer, - buflen, errnop)) == -1) - { - nis_freeresult (res); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + buflen, errnop)) == -1) + { + nis_freeresult (res); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } nis_freeresult (res); } else /* Use NIS */ @@ -1377,42 +1375,42 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer, int outvallen; if (yp_get_default_domain (&domain) != YPERR_SUCCESS) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + { + *errnop = errno; + return NSS_STATUS_TRYAGAIN; + } sprintf (buf, "%d", uid); if (yp_match (domain, "passwd.byuid", buf, strlen (buf), - &outval, &outvallen) - != YPERR_SUCCESS) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + &outval, &outvallen) + != YPERR_SUCCESS) + { + *errnop = errno; + return NSS_STATUS_TRYAGAIN; + } if (insert_passwd_adjunct (&outval, &outvallen, domain, errnop) - != NSS_STATUS_SUCCESS) - { - free (outval); - return NSS_STATUS_TRYAGAIN; - } + != NSS_STATUS_SUCCESS) + { + free (outval); + return NSS_STATUS_TRYAGAIN; + } if (buflen < ((size_t) outvallen + 1)) - { - free (outval); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + { + free (outval); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } ptr = strncpy (buffer, outval, buflen); free (outval); while (isspace (*ptr)) - ptr++; + ptr++; parse_res = _nss_files_parse_pwent (ptr, result, data, buflen, errnop); if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; + return NSS_STATUS_TRYAGAIN; } if (parse_res > 0) @@ -1434,7 +1432,7 @@ getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer, /* Searches in /etc/passwd and the NIS/NIS+ map for a special user id */ static enum nss_status internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent, - char *buffer, size_t buflen, int *errnop) + char *buffer, size_t buflen, int *errnop) { struct parser_data *data = (void *) buffer; @@ -1445,148 +1443,161 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent, int parse_res; do - { - fgetpos (ent->stream, &pos); - buffer[buflen - 1] = '\xff'; - p = fgets (buffer, buflen, ent->stream); - if (p == NULL && feof (ent->stream)) - return NSS_STATUS_NOTFOUND; - if (p == NULL || buffer[buflen - 1] != '\xff') - { - fsetpos (ent->stream, &pos); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - /* Terminate the line for any case. */ - buffer[buflen - 1] = '\0'; - - /* Skip leading blanks. */ - while (isspace (*p)) - ++p; - } + { + fgetpos (ent->stream, &pos); + buffer[buflen - 1] = '\xff'; + p = fgets (buffer, buflen, ent->stream); + if (p == NULL && feof (ent->stream)) + return NSS_STATUS_NOTFOUND; + if (p == NULL || buffer[buflen - 1] != '\xff') + { + fsetpos (ent->stream, &pos); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + /* Terminate the line for any case. */ + buffer[buflen - 1] = '\0'; + + /* Skip leading blanks. */ + while (isspace (*p)) + ++p; + } while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */ - /* Parse the line. If it is invalid, loop to - get the next line of the file to parse. */ - !(parse_res = _nss_files_parse_pwent (p, result, data, buflen, - errnop))); + /* Parse the line. If it is invalid, loop to + get the next line of the file to parse. */ + !(parse_res = _nss_files_parse_pwent (p, result, data, buflen, + errnop))); if (parse_res == -1) - { - /* The parser ran out of space. */ - fsetpos (ent->stream, &pos); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + { + /* The parser ran out of space. */ + fsetpos (ent->stream, &pos); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } /* This is a real entry. */ if (result->pw_name[0] != '+' && result->pw_name[0] != '-') - { - if (result->pw_uid == uid) - return NSS_STATUS_SUCCESS; - else - continue; - } + { + if (result->pw_uid == uid) + return NSS_STATUS_SUCCESS; + else + continue; + } /* -@netgroup */ if (result->pw_name[0] == '-' && result->pw_name[1] == '@' - && result->pw_name[2] != '\0') - { - /* XXX Do not use fixed length buffers. */ - char buf2[1024]; - char *user, *host, *domain; - struct __netgrent netgrdata; + && result->pw_name[2] != '\0') + { + char buf[strlen (result->pw_name)]; + enum nss_status status; - bzero (&netgrdata, sizeof (struct __netgrent)); - __internal_setnetgrent (&result->pw_name[2], &netgrdata); - while (__internal_getnetgrent_r (&host, &user, &domain, &netgrdata, - buf2, sizeof (buf2), errnop)) - { - if (user != NULL && user[0] != '-') - blacklist_store_name (user, ent); - } - __internal_endnetgrent (&netgrdata); - continue; - } + strcpy (buf, &result->pw_name[2]); + + status = getpwuid_plususer (uid, result, buffer, buflen, errnop); + if (status == NSS_STATUS_SUCCESS && + innetgr (buf, NULL, result->pw_name, NULL)) + return NSS_STATUS_NOTFOUND; + continue; + } /* +@netgroup */ if (result->pw_name[0] == '+' && result->pw_name[1] == '@' - && result->pw_name[2] != '\0') - { + && result->pw_name[2] != '\0') + { char buf[strlen (result->pw_name)]; - int status; + enum nss_status status; strcpy (buf, &result->pw_name[2]); - ent->netgroup = TRUE; - ent->first = TRUE; - copy_pwd_changes (&ent->pwd, result, NULL, 0); - do - { - if (use_nisplus) - status = getpwent_next_nisplus_netgr (NULL, result, ent, buf, - buffer, buflen, errnop); - else - status = getpwent_next_nis_netgr (NULL, result, ent, buf, - buffer, buflen, errnop); - if (status == NSS_STATUS_RETURN) - continue; + status = getpwuid_plususer (uid, result, buffer, buflen, errnop); + + if (status == NSS_STATUS_RETURN) + continue; - if (status == NSS_STATUS_SUCCESS && uid == result->pw_uid) + if (status == NSS_STATUS_SUCCESS) + { + if (innetgr (buf, NULL, result->pw_name, NULL)) return NSS_STATUS_SUCCESS; - } while (status == NSS_STATUS_SUCCESS); - continue; + } + else + if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */ + return NSS_STATUS_NOTFOUND; + else + return status; + + continue; } /* -user */ if (result->pw_name[0] == '-' && result->pw_name[1] != '\0' - && result->pw_name[1] != '@') - { - blacklist_store_name (&result->pw_name[1], ent); + && result->pw_name[1] != '@') + { + char buf[strlen (result->pw_name)]; + enum nss_status status; + + strcpy (buf, &result->pw_name[1]); + + status = getpwuid_plususer (uid, result, buffer, buflen, errnop); + if (status == NSS_STATUS_SUCCESS && + innetgr (buf, NULL, result->pw_name, NULL)) + return NSS_STATUS_NOTFOUND; continue; - } + } /* +user */ if (result->pw_name[0] == '+' && result->pw_name[1] != '\0' - && result->pw_name[1] != '@') - { + && result->pw_name[1] != '@') + { + char buf[strlen (result->pw_name)]; enum nss_status status; - /* Store the User in the blacklist for the "+" at the end of - /etc/passwd */ - blacklist_store_name (&result->pw_name[1], ent); - status = getpwnam_plususer (&result->pw_name[1], result, buffer, - buflen, errnop); - if (status == NSS_STATUS_SUCCESS && result->pw_uid == uid) - break; - else + strcpy (buf, &result->pw_name[1]); + + status = getpwuid_plususer (uid, result, buffer, buflen, errnop); + + if (status == NSS_STATUS_RETURN) continue; - } + + if (status == NSS_STATUS_SUCCESS) + { + if (strcmp (buf, result->pw_name) == 0) + return NSS_STATUS_SUCCESS; + } + else + if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */ + return NSS_STATUS_NOTFOUND; + else + return status; + + continue; + } /* +:... */ if (result->pw_name[0] == '+' && result->pw_name[1] == '\0') - { - enum nss_status status; - - status = getpwuid_plususer (uid, result, buffer, buflen, errnop); - if (status == NSS_STATUS_SUCCESS) /* We found the entry. */ - break; - else - if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */ - return NSS_STATUS_NOTFOUND; - else - return status; - } + { + enum nss_status status; + + status = getpwuid_plususer (uid, result, buffer, buflen, errnop); + if (status == NSS_STATUS_SUCCESS) /* We found the entry. */ + break; + else + if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */ + return NSS_STATUS_NOTFOUND; + else + return status; + } } return NSS_STATUS_SUCCESS; } enum nss_status _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd, - char *buffer, size_t buflen, int *errnop) + char *buffer, size_t buflen, int *errnop) { ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}, - {NULL, NULL, 0, 0, NULL, NULL, NULL}}; + {NULL, NULL, 0, 0, NULL, NULL, NULL}}; enum nss_status status; __libc_lock_lock (lock); |