static enum nss_status internal_setgrent (int *errnop) { enum nss_status status = NSS_STATUS_SUCCESS; if (grp_tablename_val == NULL) status = _nss_grp_create_tablename (errnop); if (status == NSS_STATUS_SUCCESS) { ibreq = __create_ib_request (grp_tablename_val, 0); if (ibreq == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } nis_error retcode = __prepare_niscall (grp_tablename_val, &dir, &bptr, 0); if (retcode != NIS_SUCCESS) { nis_free_request (ibreq); ibreq = NULL; status = niserr2nss (retcode); } } return status; }
enum nss_status _nss_nisplus_getgrnam_r (const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop) { int parse_res; if (grp_tablename_val == NULL) { enum nss_status status = _nss_grp_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } if (name == NULL) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } nis_result *result; char buf[strlen (name) + 9 + grp_tablename_len]; int olderr = errno; snprintf (buf, sizeof (buf), "[name=%s],%s", name, grp_tablename_val); result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); if (result == NULL) { *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS)) { enum nss_status status = niserr2nss (result->status); nis_freeresult (result); return status; } parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); nis_freeresult (result); if (__glibc_unlikely (parse_res < 1)) { if (parse_res == -1) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } else { __set_errno (olderr); return NSS_STATUS_NOTFOUND; } } return NSS_STATUS_SUCCESS; }
enum nss_status _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop) { if (grp_tablename_val == NULL) { enum nss_status status = _nss_grp_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } int parse_res; nis_result *result; char buf[8 + 3 * sizeof (unsigned long int) + grp_tablename_len]; int olderr = errno; snprintf (buf, sizeof (buf), "[gid=%lu],%s", (unsigned long int) gid, grp_tablename_val); result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); if (result == NULL) { *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS)) { enum nss_status status = niserr2nss (result->status); __set_errno (olderr); nis_freeresult (result); return status; } parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); nis_freeresult (result); if (__glibc_unlikely (parse_res < 1)) { __set_errno (olderr); if (parse_res == -1) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } else return NSS_STATUS_NOTFOUND; } return NSS_STATUS_SUCCESS; }
enum nss_status _nss_nisplus_initgroups_dyn (const char *user, gid_t group, long int *start, long int *size, gid_t **groupsp, long int limit, int *errnop) { if (grp_tablename_val == NULL) { enum nss_status status = _nss_grp_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } nis_result *result; char buf[strlen (user) + 12 + grp_tablename_len]; snprintf (buf, sizeof (buf), "[members=%s],%s", user, grp_tablename_val); result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | ALL_RESULTS, NULL, NULL); if (result == NULL) { *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) { enum nss_status status = niserr2nss (result->status); nis_freeresult (result); return status; } if (NIS_RES_NUMOBJ (result) == 0) { errout: nis_freeresult (result); return NSS_STATUS_NOTFOUND; } gid_t *groups = *groupsp; nis_object *obj = NIS_RES_OBJECT (result); for (unsigned int cnt = 0; cnt < NIS_RES_NUMOBJ (result); ++cnt, ++obj) { if (__type_of (obj) != NIS_ENTRY_OBJ || strcmp (obj->EN_data.en_type, "group_tbl") != 0 || obj->EN_data.en_cols.en_cols_len < 4) continue; char *numstr = NISOBJVAL (2, obj); size_t len = NISOBJLEN (2, obj); if (len == 0 || numstr[0] == '\0') continue; gid_t gid; char *endp; if (__builtin_expect (numstr[len - 1] != '\0', 0)) { char numstrbuf[len + 1]; memcpy (numstrbuf, numstr, len); numstrbuf[len] = '\0'; gid = strtoul (numstrbuf, &endp, 10); if (*endp) continue; } else { gid = strtoul (numstr, &endp, 10); if (*endp) continue; } if (gid == group) continue; /* Insert this group. */ if (*start == *size) { /* Need a bigger buffer. */ long int newsize; if (limit > 0 && *size == limit) /* We reached the maximum. */ break; if (limit <= 0) newsize = 2 * *size; else newsize = MIN (limit, 2 * *size); gid_t *newgroups = realloc (groups, newsize * sizeof (*groups)); if (newgroups == NULL) goto errout; *groupsp = groups = newgroups; *size = newsize; } groups[*start] = gid; *start += 1; } nis_freeresult (result); return NSS_STATUS_SUCCESS; }