int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) { int i, ngroups = 0, ret = 0, maxgroups = *grpcnt, bail; int needyp = 0, foundyp = 0; int *skipyp = &foundyp; extern struct group *_getgrent_yp(int *); struct group *grp; /* * install primary group */ if (ngroups >= maxgroups) { *grpcnt = ngroups; return (-1); } groups[ngroups++] = agroup; /* * Scan the group file to find additional groups. */ setgrent(); while ((grp = _getgrent_yp(skipyp)) || foundyp) { if (foundyp) { if (foundyp > 0) needyp = 1; else skipyp = NULL; foundyp = 0; continue; } if (grp->gr_gid == agroup) continue; for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) if (groups[i] == grp->gr_gid) bail = 1; if (bail) continue; for (i = 0; grp->gr_mem[i]; i++) { if (!strcmp(grp->gr_mem[i], uname)) { if (ngroups >= maxgroups) { ret = -1; goto out; } groups[ngroups++] = grp->gr_gid; break; } } } #ifdef YP /* * If we were told that there is a YP marker, look at netid data. */ if (skipyp && needyp) { char buf[MAXLINELENGTH], *ypdata = NULL, *key; static char *__ypdomain; struct passwd pwstore; int ypdatalen; /* Construct the netid key to look up. */ if (getpwnam_r(uname, &pwstore, buf, sizeof buf, NULL) || (!__ypdomain && yp_get_default_domain(&__ypdomain))) goto out; asprintf(&key, "unix.%u@%s", pwstore.pw_uid, __ypdomain); if (key == NULL) goto out; /* First scan the static netid file. */ switch (_read_netid(key, pwstore.pw_uid, groups, &ngroups, maxgroups)) { case -1: ret = -1; /* FALLTHROUGH */ case 1: free(key); goto out; default: break; } /* Only access YP when there is no static entry. */ if (!yp_bind(__ypdomain) && !yp_match(__ypdomain, "netid.byname", key, (int)strlen(key), &ypdata, &ypdatalen)) if (_parse_netid(ypdata, pwstore.pw_uid, groups, &ngroups, maxgroups) == -1) ret = -1; free(key); free(ypdata); } #endif /* YP */ out: endgrent(); *grpcnt = ngroups; return (ret); }
struct group * getgrent(void) { return (_getgrent_yp(NULL)); }