static void showgroups(struct passwd *pw) { struct group *gr; static gid_t *groups = NULL; int ngroups; int i; if (groups == NULL) { if ((groups = (gid_t *)calloc((uint_t)ngroups_max, sizeof (gid_t))) == 0) { (void) fprintf(stderr, "allocation of %d bytes failed\n", ngroups_max * sizeof (gid_t)); exit(1); } } groups[0] = pw->pw_gid; ngroups = _getgroupsbymember(pw->pw_name, groups, ngroups_max, 1); if (gr = getgrgid(groups[0])) (void) printf("%s", gr->gr_name); else (void) printf("%d", (int)pw->pw_gid); for (i = 1; i < ngroups; i++) { if ((gr = getgrgid(groups[i]))) (void) printf(" %s", gr->gr_name); else (void) printf(" %d", (int)groups[i]); } (void) printf("\n"); }
static void initcred(void) { struct passwd *pwd; if ((groups = malloc(ngroups_max * sizeof (gid_t))) == NULL) { (void) perr("malloc"); exit(1); } if (login != NULL) { pwd = getpwnam(login); if (pwd == NULL) { (void) fprintf(stderr, "%s: %s: unknown user\n", command, login); exit(1); } uid = pwd->pw_uid; gid = pwd->pw_gid; groups[0] = gid; ngrp = _getgroupsbymember(login, groups, (int)ngroups_max, 1); } if (user != NULL) { pwd = getpwnam(user); if (pwd == NULL) { uid = (uid_t)str2id(user); if (uid == (uid_t)-1) { (void) fprintf(stderr, "%s: %s: unknown user" " or bad uid\n", command, user); exit(1); } } else { uid = pwd->pw_uid; } } if (group != NULL) gid = str2gid(group); if (grplst != NULL) { char *cgrp; ngrp = 0; while ((cgrp = strtok(grplst, ",")) != NULL) { if (ngrp >= ngroups_max) { (void) fprintf(stderr, "%s: Too many groups\n", command); exit(1); } groups[ngrp++] = str2gid(cgrp); /* For iterations of strtok */ grplst = NULL; } } }
/* * Build the uid and gid from the netname for users in LDAP. * There is no netid container in LDAP. For this we build * the netname to user data dynamically from the passwd and * group data. This works only for users in a single domain. * This function is an interim solution until we support a * netid container in LDAP which enables us to do netname2user * resolution for multiple domains. */ static int netname2user_ldap(int *err, char *netname, struct netid_userdata *argp) { char buf[NSS_LINELEN_PASSWD]; char *p2, *lasts; struct passwd pw; uid_t uidnu; int ngroups = 0; int count; char pwbuf[NSS_LINELEN_PASSWD]; int maxgrp = sysconf(_SC_NGROUPS_MAX); gid_t *groups = alloca(maxgrp * sizeof (gid_t)); if (strlcpy(buf, netname, NSS_LINELEN_PASSWD) >= NSS_LINELEN_PASSWD) { *err = __NSW_UNAVAIL; return (0); } /* get the uid from the netname */ if (strtok_r(buf, ".", &lasts) == NULL) { *err = __NSW_UNAVAIL; return (0); } if ((p2 = strtok_r(NULL, "@", &lasts)) == NULL) { *err = __NSW_UNAVAIL; return (0); } uidnu = atoi(p2); /* * check out the primary group and crosscheck the uid * with the passwd data */ if ((getpwuid_r(uidnu, &pw, pwbuf, sizeof (pwbuf))) == NULL) { *err = __NSW_UNAVAIL; return (0); } *(argp->uidp) = pw.pw_uid; *(argp->gidp) = pw.pw_gid; /* search through all groups for membership */ groups[0] = pw.pw_gid; ngroups = _getgroupsbymember(pw.pw_name, groups, maxgrp, (pw.pw_gid <= MAXUID) ? 1 : 0); if (ngroups < 0) { *err = __NSW_UNAVAIL; return (0); } *(argp->gidlenp) = ngroups; for (count = 0; count < ngroups; count++) { (argp->gidlist[count]) = groups[count]; } *err = __NSW_SUCCESS; return (1); }
/*----------------------------------------------------------------------------- * Obtain the groups for the given user. * * user: Name of user to check. * groups: Addr of ptr to group list. Will be allocated here and will * contain a group name or a comma-separated list of group names. * * RETURNS: * -1: on failure * */ int pamauth_get_groups_for_user(const char *user, char **groups) { struct group *gr; struct passwd *pw = NULL; gid_t *gids = NULL; int ngroups, ngroups_max, i; const int sizeq = 128; int bufsize = sizeq * 8; int pambufsize; int rv = -1; char numbuf[sizeq]; char* tmp = NULL; char* pambuff = NULL; ngroups_max = sysconf(_SC_NGROUPS_MAX); if (ngroups_max <= 0) { /* zero is actually a perfectly good value for _SC_NGROUPS_MAX */ return (-1); } /* get pw info */ pambufsize = (int)sysconf(_SC_GETPW_R_SIZE_MAX); if ((pambuff = (char*)MALLOC(pambufsize)) == NULL) { return(-1); } if ((pw = (struct passwd *)MALLOC(sizeof(struct passwd))) == NULL) { goto error; } util_getpwnam(user, pw, pambuff, pambufsize); /* temp space for _getgroupsbymember() call below */ if ((gids = CALLOC((uint_t)ngroups_max * sizeof (gid_t))) == NULL) { goto error; } gids[0] = pw->pw_gid; ngroups = _getgroupsbymember(user, gids, ngroups_max, 1); /* print each group (and its gid) to comma-separated list into *groups */ if ((*groups = (char *)MALLOC(bufsize)) == NULL) { goto error; } (*groups)[0] = 0; for (i = 0; i < ngroups; i++) { if ((gr = getgrgid(gids[i]))) { /* check there is still enough space in *groups */ if (strlen(*groups) + strlen(gr->gr_name) + sizeq > bufsize) { bufsize += strlen(gr->gr_name) + sizeq; if ((tmp = (char *)REALLOC(*groups, bufsize)) == NULL) { tmp = *groups; goto error; } *groups = tmp; tmp = NULL; } strcat(*groups, gr->gr_name); strcat(*groups, ","); } sprintf(numbuf, "%d,", (int)gids[i]); strcat(*groups, numbuf); } /* remove last , */ i = strlen(*groups); if (i) { (*groups)[i-1] = 0; } /* return # of groups found */ rv = ngroups * 2; error: if (pambuff) FREE(pambuff); if (pw) FREE(pw); if (gids) FREE(gids); if (tmp) FREE(tmp); return(rv); }