static gint get_user_groups (ActUser *user, gid_t *primary, gid_t **groups) { struct passwd *pwd; const gchar *name; gint res; gint ngroups; name = act_user_get_user_name (user); pwd = getpwnam_alloc (name); if (pwd == NULL) { *primary = -1; *groups = NULL; return 0; } *primary = pwd->pw_gid; ngroups = 0; res = getgrouplist (name, *primary, NULL, &ngroups); g_debug ("user %s has %d groups", name, ngroups); *groups = g_new (gid_t, ngroups); res = getgrouplist (name, *primary, *groups, &ngroups); g_free (pwd); return res; }
static int check_group(const char *group, const char *name, const gid_t gid) { int match = 0; int i, ng = 0; gid_t *groups = NULL; struct group gbuf, *grent = NULL; long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); if (rbuflen <= 0) return 0; char *rbuf = malloc(rbuflen); if (rbuf == NULL) return 0; if (getgrnam_r(group, &gbuf, rbuf, rbuflen, &grent) != 0) goto done; if (getgrouplist(name, gid, NULL, &ng) < 0) { groups = (gid_t *) malloc(sizeof (gid_t) * ng); if (!groups) goto done; if (getgrouplist(name, gid, groups, &ng) < 0) goto done; } for (i = 0; i < ng; i++) { if (grent->gr_gid == groups[i]) { match = 1; goto done; } } done: free(groups); free(rbuf); return match; }
/** * Gets the group IDs for a given user. The groups argument is allocated * internally, and it contains the list of groups. The ngroups is updated to * the number of groups * Returns 0 on success (on success, the caller must free the memory allocated * internally) */ int getGroupIDList(const char *user, int *ngroups, gid_t **groups) { int getPW(const char *user, char **pwbuf); *ngroups = 0; char *pwbuf = NULL; *groups = NULL; /*Look up the password database first*/ int error = getPW(user, &pwbuf); if (error != 0) { if (pwbuf != NULL) { free(pwbuf); } return error; } struct passwd *pw = (struct passwd*)pwbuf; int ng = 0; /*Get the groupIDs that this user belongs to*/ if (getgrouplist(user, pw->pw_gid, NULL, &ng) < 0) { *ngroups = ng; *groups = (gid_t *) malloc(ng * sizeof (gid_t)); if (!*groups) { *ngroups = 0; free(pwbuf); return ENOMEM; } if (getgrouplist(user, pw->pw_gid, *groups, &ng) < 0) { *ngroups = 0; free(pwbuf); free(*groups); *groups = NULL; return ENOENT; } } free(pwbuf); return 0; }
/* Allocate supplementary groups buffer */ static bool my_getgrouplist_alloc(char *user, gid_t gid, struct group_data *gdata) { int ngroups = 0; gid_t *groups, *groups2; /* We call getgrouplist() with 0 ngroups first. This should always * return -1, and ngroups should be set to the actual number of * groups the user is in. The manpage doesn't say anything * about errno value, it was usually zero but was set to 34 * (ERANGE) under some environments. ngroups was set correctly * no matter what the errno value is! * * We assume that ngroups is correctly set, no matter what the * errno value is. The man page says, "The ngroups argument * is a value-result argument: on return it always contains * the number of groups found for user." */ (void)getgrouplist(user, gid, NULL, &ngroups); /* Allocate gdata->groups with the right size then call * getgrouplist() a second time to get the actual group list */ groups = gsh_malloc(ngroups * sizeof(gid_t)); if (groups == NULL) return false; if (getgrouplist(user, gid, groups, &ngroups) == -1) { LogEvent(COMPONENT_IDMAPPER, "getgrouplist for user: %s failed retrying", user); gsh_free(groups); /* Try with the largest ngroups we support */ ngroups = 1000; groups2 = gsh_malloc(ngroups * sizeof(gid_t)); if (groups2 == NULL) return false; if (getgrouplist(user, gid, groups2, &ngroups) == -1) { LogWarn(COMPONENT_IDMAPPER, "getgrouplist for user:%s failed, ngroups: %d", user, ngroups); gsh_free(groups2); return false; } /* Resize the buffer */ groups = gsh_realloc(groups2, ngroups * sizeof(gid_t)); if (groups == NULL) /* Use the large buffer! */ groups = groups2; } gdata->groups = groups; gdata->nbgroups = ngroups; return true; }
int main(int argc, char *argv[]) { int i = 0; int ng = 1; char *user; gid_t *groups = NULL; gid_t gid; struct group *mygroup = NULL; struct passwd *pw = NULL; if (argc != 2) { printf("\nLists the groups a given username is part of using the getgrouplist(3) function.\n"); printf("Usage: %s <username>\n\n", argv[0]); exit(1); } user = strdup(argv[1]); if ((pw = getpwnam(user)) == NULL) { printf("Error: user '%s' doesn't exist.\n", user); exit(1); } if ((groups = (gid_t *) malloc(ng * sizeof(gid_t))) == NULL) { printf("Error, out of memory.\n"); exit(1); } if (getgrouplist(user, pw->pw_gid, groups, &ng) == -1) { /* use realloc... */ free(groups); groups = malloc((size_t)(ng * sizeof(gid_t))); if (groups == NULL) { printf("Error, out of memory.\n"); exit(1); } if (getgrouplist(user, pw->pw_gid, groups, &ng) == -1) { printf("getgrouplist(): error fetching list of groups.\n"); exit(1); } } for(i = 0; i < ng; i++) { mygroup = getgrgid(groups[i]); if (mygroup != NULL) printf("%s", mygroup->gr_name); else continue; if (i < ng - 1) printf(","); else printf("\n"); } free(groups); free(user); return 0; }
static int check_group(const char *group, const char *name, const gid_t gid) { int match = 0; int i, ng = 0; gid_t *groups = NULL; struct group gbuf, *grent = NULL; long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); if (rbuflen <= 0) return 0; char *rbuf; while(1) { rbuf = malloc(rbuflen); if (rbuf == NULL) return 0; int retval = getgrnam_r(group, &gbuf, rbuf, rbuflen, &grent); if ( retval == ERANGE ) { free(rbuf); rbuflen = rbuflen * 2; } else if ( retval != 0 || grent == NULL ) { goto done; } else { break; } } if (getgrouplist(name, gid, NULL, &ng) < 0) { if (ng == 0) goto done; groups = calloc(ng, sizeof(*groups)); if (!groups) goto done; if (getgrouplist(name, gid, groups, &ng) < 0) goto done; } else { /* WTF? ng was 0 and we didn't fail? Are we in 0 groups? */ goto done; } for (i = 0; i < ng; i++) { if (grent->gr_gid == groups[i]) { match = 1; goto done; } } done: free(groups); free(rbuf); return match; }
GSList *getugroups(char *username, gid_t gid) { GSList *grouplist = NULL; int i, ng = 0; gid_t *groups = NULL; /* need to lock as position is common to all thread */ g_static_mutex_lock(&group_mutex); #ifdef PERF_DISPLAY_ENABLE { struct timeval tvstart, tvend, result; if (nuauthconf->debug_areas & DEBUG_AREA_PERF) { gettimeofday(&tvstart, NULL); } #endif if (system_glibc_cant_guess_maxgroups) { ng = system_glibc_cant_guess_maxgroups; } else { if (getgrouplist(username, gid, NULL, &ng) >= 0) { return NULL; } } groups = g_new0(gid_t, ng); getgrouplist(username, gid, groups, &ng); for (i = 0; i < ng; i++) { grouplist = g_slist_prepend(grouplist, GINT_TO_POINTER(groups[i])); } g_free(groups); #ifdef PERF_DISPLAY_ENABLE if (nuauthconf->debug_areas & DEBUG_AREA_PERF) { gettimeofday(&tvend, NULL); timeval_substract(&result, &tvend, &tvstart); log_message(INFO, DEBUG_AREA_PERF, "Group list fetching duration: %.1f msec", (double)result.tv_sec*1000+ (double)(result.tv_usec/1000)); } } #endif /* release lock */ g_static_mutex_unlock(&group_mutex); return grouplist; }
int hadoop_user_info_getgroups(struct hadoop_user_info *uinfo) { int ret, ngroups; gid_t *ngids; if (!uinfo->pwd.pw_name) { // invalid user info return EINVAL; } uinfo->num_gids = 0; if (!uinfo->gids) { uinfo->gids = malloc(sizeof(uinfo->gids[0]) * INITIAL_GIDS_SIZE); if (!uinfo->gids) { return ENOMEM; } uinfo->gids_size = INITIAL_GIDS_SIZE; } ngroups = uinfo->gids_size; ret = getgrouplist(uinfo->pwd.pw_name, uinfo->pwd.pw_gid, uinfo->gids, &ngroups); if (ret > 0) { uinfo->num_gids = ngroups; ret = put_primary_gid_first(uinfo); if (ret) { return ret; } return 0; } else if (ret != -1) { // Any return code that is not -1 is considered as error. // Since the user lookup was successful, there should be at least one // group for this user. return EIO; } ngids = realloc(uinfo->gids, sizeof(uinfo->gids[0]) * ngroups); if (!ngids) { return ENOMEM; } uinfo->gids = ngids; uinfo->gids_size = ngroups; ret = getgrouplist(uinfo->pwd.pw_name, uinfo->pwd.pw_gid, uinfo->gids, &ngroups); if (ret < 0) { return EIO; } uinfo->num_gids = ngroups; ret = put_primary_gid_first(uinfo); return ret; }
static void group(struct passwd *pw, int nflag) { struct group *gr; int cnt, id, lastid, ngroups; gid_t groups[NGROUPS + 1]; const char *fmt; if (pw) { ngroups = NGROUPS + 1; getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); } else { groups[0] = getgid(); ngroups = getgroups(NGROUPS, groups + 1) + 1; } fmt = nflag ? "%s" : "%u"; for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { if (lastid == (id = groups[cnt])) continue; if (nflag) { if ((gr = getgrgid(id))) printf(fmt, gr->gr_name); else printf(*fmt == ' ' ? " %u" : "%u", id); fmt = " %s"; } else { printf(fmt, id); fmt = " %u"; } lastid = id; } printf("\n"); }
static void user(struct passwd *pw) { struct group *gr; const char *fmt; int cnt, ngroups; gid_t gid, lastgid, groups[NGROUPS + 1]; printf("uid=%u(%s)", pw->pw_uid, pw->pw_name); gid = pw->pw_gid; printf(" gid=%u", gid); if ((gr = getgrgid(gid))) printf("(%s)", gr->gr_name); ngroups = NGROUPS + 1; getgrouplist(pw->pw_name, gid, groups, &ngroups); fmt = " groups=%u"; for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { if (lastgid == (gid = groups[cnt])) continue; printf(fmt, gid); fmt = ", %u"; if ((gr = getgrgid(gid))) printf("(%s)", gr->gr_name); lastgid = gid; } printf("\n"); }
static void tcpeek_init_setuid(void) { struct passwd *passwd; gid_t groups[128]; int ngroups; if(strisempty(g.option.user)) { return; } passwd = strisdigit(g.option.user) ? getpwuid((uid_t)strtol(g.option.user, NULL, 10)) : getpwnam(g.option.user); if(!passwd) { error_abort("%s", strerror(errno)); } ngroups = sizeof(groups); if(getgrouplist(g.option.user, passwd->pw_gid, groups, &ngroups) == -1) { error_abort("getgrouplist: %s", strerror(errno)); } if(setgroups(ngroups, groups) == -1) { error_abort("setgroups: %s", strerror(errno)); } if(setgid(passwd->pw_gid) == -1) { error_abort("setgid: %s", strerror(errno)); } if(setuid(passwd->pw_uid) == -1) { error_abort("setuid: %s", strerror(errno)); } }
APIE process_set_identity(uid_t uid, gid_t gid) { APIE error_code; struct passwd *pw; gid_t groups[128]; // FIXME: maybe allocate this dynamically int length = sizeof(groups) / sizeof(gid_t); // get username pw = getpwuid(uid); if (pw == NULL) { error_code = api_get_error_code_from_errno(); log_error("Could not get passwd entry for user ID %u: %s (%d)", uid, get_errno_name(errno), errno); return error_code; } // get (secondary) groups if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &length) < 0) { error_code = api_get_error_code_from_errno(); log_error("Could not get secondary groups for user ID %u: %s (%d)", uid, get_errno_name(errno), errno); return error_code; } // set (primary) group if (setregid(gid, gid) < 0) { error_code = api_get_error_code_from_errno(); log_error("Could not change real and effective group ID to %u: %s (%d)", gid, get_errno_name(errno), errno); return error_code; } // set (secondary) groups if (setgroups(length, groups) < 0) { error_code = api_get_error_code_from_errno(); log_error("Could not set secondary group IDs of user ID %u: %s (%d)", uid, get_errno_name(errno), errno); return error_code; } // set user if (setreuid(uid, uid) < 0) { error_code = api_get_error_code_from_errno(); log_error("Could not change real and effective user ID to %u: %s (%d)", uid, get_errno_name(errno), errno); return error_code; } return API_E_SUCCESS; }
void do_id(char *username) { int flags, i, ngroups, cmd_groups = toys.which->name[0] == 'g'; struct passwd *pw; struct group *grp; uid_t uid = getuid(), euid = geteuid(); gid_t gid = getgid(), egid = getegid(), *groups; if (cmd_groups) toys.optflags |= FLAG_G | FLAG_n; flags = toys.optflags; // check if a username is given if (username) { pw = xgetpwnam(username); uid = euid = pw->pw_uid; gid = egid = pw->pw_gid; if (cmd_groups) printf("%s : ", pw->pw_name); } i = flags & FLAG_r; pw = xgetpwuid(i ? uid : euid); if (flags & FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1); grp = xgetgrgid(i ? gid : egid); if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1); if (!(flags & FLAG_G)) { showid("uid=", pw->pw_uid, pw->pw_name); showid(" gid=", grp->gr_gid, grp->gr_name); if (!i) { if (uid != euid) { pw = xgetpwuid(euid); showid(" euid=", pw->pw_uid, pw->pw_name); } if (gid != egid) { grp = xgetgrgid(egid); showid(" egid=", grp->gr_gid, grp->gr_name); } } showid(" groups=", grp->gr_gid, grp->gr_name); } groups = (gid_t *)toybuf; i = sizeof(toybuf)/sizeof(gid_t); ngroups = username ? getgrouplist(username, gid, groups, &i) : getgroups(i, groups); if (ngroups<0) perror_exit(0); for (i = 0; i<ngroups; i++) { if (i) xputc(' '); if (!(grp = getgrgid(groups[i]))) perror_msg(0); else if (flags & FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0); else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name); } xputc('\n'); }
static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) { int retval; bool winbind_env; DEBUG(10,("sys_getgrouplist: user [%s]\n", user)); /* This is only ever called for Unix users, remote memberships are * always determined by the info3 coming back from auth3 or the * PAC. */ winbind_env = winbind_env_set(); (void)winbind_off(); #ifdef HAVE_GETGROUPLIST retval = getgrouplist(user, gid, groups, grpcnt); #else #ifdef HAVE_GETGRSET retval = getgrouplist_getgrset(user, gid, groups, grpcnt); #else become_root(); retval = getgrouplist_internals(user, gid, groups, grpcnt); unbecome_root(); #endif /* HAVE_GETGRSET */ #endif /* HAVE_GETGROUPLIST */ /* allow winbindd lookups, but only if they were not already disabled */ if (!winbind_env) { (void)winbind_on(); } return retval; }
void group(struct passwd *pw, int nflag) { int cnt, ngroups; gid_t gid, groups[NGROUPS + 1]; struct group *gr; char *fmt; if (pw) { ngroups = NGROUPS + 1; (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); } else { groups[0] = getgid(); ngroups = getgroups(NGROUPS, groups + 1) + 1; } fmt = nflag ? "%s" : "%u"; for (cnt = 0; cnt < ngroups;) { gid = groups[cnt]; if (nflag) { if ((gr = getgrgid(gid))) (void)printf(fmt, gr->gr_name); else (void)printf(*fmt == ' ' ? " %u" : "%u", gid); fmt = " %s"; } else { (void)printf(fmt, gid); fmt = " %u"; } /* Skip same gid entries. */ while (++cnt < ngroups && gid == groups[cnt]); } (void)printf("\n"); }
void user(struct passwd *pw) { gid_t gid, groups[NGROUPS + 1]; int cnt, ngroups; uid_t uid; struct group *gr; char *fmt; uid = pw->pw_uid; (void)printf("uid=%u(%s)", uid, pw->pw_name); (void)printf(" gid=%u", pw->pw_gid); if ((gr = getgrgid(pw->pw_gid))) (void)printf("(%s)", gr->gr_name); ngroups = NGROUPS + 1; (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); fmt = " groups=%u"; for (cnt = 0; cnt < ngroups;) { gid = groups[cnt]; (void)printf(fmt, gid); fmt = ", %u"; if ((gr = getgrgid(gid))) (void)printf("(%s)", gr->gr_name); /* Skip same gid entries. */ while (++cnt < ngroups && gid == groups[cnt]); } (void)printf("\n"); }
int initgroups(const char *user, gid_t gid) { gid_t groups[NGROUPS_MAX]; int count; if (getgrouplist(user, gid, groups, &count) < 0) return -1; return setgroups(count, groups); }
void ch_user(void) { int jid, ngroups; uid_t huid; struct passwd *husername, *jusername; gid_t groups[NGROUPS]; login_cap_t *lcap; /* Get the current user ID and user name in the host system */ huid = getuid(); husername = getpwuid(huid); /* Get the user name in the jail */ jusername = getpwuid(huid); if (jusername == NULL || strcmp(husername->pw_name, jusername->pw_name) != 0) err(1, "Username mapping failed"); lcap = login_getpwclass(jusername); if (lcap == NULL) { err(1, "getpwclass: %s", jusername->pw_name); } ngroups = NGROUPS; if (getgrouplist(jusername->pw_name, jusername->pw_gid, groups, &ngroups) != 0) err(1, "getgrouplist: %s", jusername->pw_name); if (setgroups(ngroups, groups) != 0) err(1, "setgroups"); if (setgid(jusername->pw_gid) != 0) err(1, "setgid"); if (setusercontext(lcap, jusername, jusername->pw_uid, LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN) != 0) err(1, "setusercontext"); login_close(lcap); }
int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) { char *p; int retval; DEBUG(10,("sys_getgrouplist: user [%s]\n", user)); /* see if we should disable winbindd lookups for local users */ if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) { if ( !winbind_off() ) DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n", WINBINDD_DONT_ENV)); else DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n", user)); } #ifdef HAVE_GETGROUPLIST retval = getgrouplist(user, gid, groups, grpcnt); #else become_root(); retval = getgrouplist_internals(user, gid, groups, grpcnt); unbecome_root(); #endif /* allow winbindd lookups */ winbind_on(); return retval; }
/* This needs to be called with the usercache lock held. * I don't think it's thread safe. -jg */ static int _getgrouplist (Npsrv *srv, Npuser *u) { int i, ret = -1; gid_t *sgcpy; u->nsg = sysconf(_SC_NGROUPS_MAX); if (u->nsg < 65536) u->nsg = 65536; if (!(u->sg = malloc (u->nsg * sizeof (gid_t)))) { np_uerror (ENOMEM); np_logerr (srv, "_alloc_user: %s", u->uname); goto done; } if (getgrouplist(u->uname, u->gid, u->sg, &u->nsg) == -1) { np_logerr (srv, "_alloc_user: %s: getgrouplist", u->uname); if (np_rerror () == 0) np_uerror (EPERM); goto done; } if ((sgcpy = malloc (u->nsg * sizeof (gid_t)))) { for (i = 0; i < u->nsg; i++) sgcpy[i] = u->sg[i]; free (u->sg); u->sg = sgcpy; } ret = 0; done: return ret; }
/* * Initialize group access list for user with primary (base) and * supplementary groups. Return the number of groups in the list. */ int ga_init(const char *user, gid_t base) { gid_t *groups_bygid; int i, j; struct group *gr; if (ngroups > 0) ga_free(); ngroups = NGROUPS_MAX; #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); #endif groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) logit("getgrouplist: groups list too small"); for (i = 0, j = 0; i < ngroups; i++) if ((gr = getgrgid(groups_bygid[i])) != NULL) groups_byname[j++] = xstrdup(gr->gr_name); xfree(groups_bygid); return (ngroups = j); }
/* On error set *n < 0 and return >= 0 * If *n is too small, update it and return < 0 * (ok to trash groups[] in both cases) * Otherwise fill in groups[] and return >= 0 */ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) { int m; if (username) { /* If the user is a member of more than * *n groups, then -1 is returned. Otherwise >= 0. * (and no defined way of detecting errors?!) */ m = getgrouplist(username, rgid, groups, n); /* I guess *n < 0 might indicate error. Anyway, * malloc'ing -1 bytes won't be good, so: */ if (*n < 0) return 0; return m; } *n = getgroups(*n, groups); if (*n >= 0) return *n; /* Error */ if (errno == EINVAL) /* *n is too small? */ *n = getgroups(0, groups); /* get needed *n */ /* if *n >= 0, return -1 (got new *n), else return 0 (error): */ return -(*n >= 0); }
static int is_gr_member(const char *login, const struct group_workspace *buf) { struct passwd *pw; int ngroups = buf->ngroups; int rc; pw = getpwnam(login); if (!pw) return 0; if (buf->requested_group == pw->pw_gid) return 1; rc = getgrouplist(login, pw->pw_gid, buf->groups, &ngroups); if (rc < 0) { /* buffer too small, not sure how this can happen, since we used sysconf to get the size... */ errx(EXIT_FAILURE, _("getgrouplist found more groups than sysconf allows")); } for (; ngroups >= 0; --ngroups) { if (buf->requested_group == (gid_t) buf->groups[ngroups]) return 1; } return 0; }
/* On error set *n < 0 and return >= 0 * If *n is too small, update it and return < 0 * (ok to trash groups[] in both cases) * Otherwise fill in groups[] and return >= 0 */ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) { int m; if (username) { /* If the user is a member of more than * *n groups, then -1 is returned. Otherwise >= 0. * (and no defined way of detecting errors?!) */ m = getgrouplist(username, rgid, groups, n); /* I guess *n < 0 might indicate error. Anyway, * malloc'ing -1 bytes won't be good, so: */ //if (*n < 0) // return 0; //return m; //commented out here, happens below anyway } else { /* On error -1 is returned, which ends up in *n */ int nn = getgroups(*n, groups); /* 0: nn <= *n, groups[] was big enough; -1 otherwise */ m = - (nn > *n); *n = nn; } if (*n < 0) return 0; /* error, don't return < 0! */ return m; }
int acl_can_connect(struct Creds *cred) { gid_t gids[64]; int nr_gids = 64; struct passwd *pw; int i, j; // root always allowed if (cred->uid == 0) return 1; pw = getpwuid(cred->uid); if (!pw) return 0; if (getgrouplist(pw->pw_name, cred->gid, &gids[0], &nr_gids) < 0) { nr_gids = 63; } for (i = 0; i < nr_gids; i++) { for (j = 0; j < acl_nr_allowed_gids; j++) { if (gids[i] == acl_allowed_gids[j]) return 1; } } return 0; }
static int check_acl(int node, struct Creds *cred) { gid_t gids[64]; int nr_gids = 64; struct passwd *pw; struct acl_class *ac; struct acl_group *ag; void *acptr = ∾ int level; int i, j; model_acl_get(model_parent(node), acptr, &level); if (!ac) return 0; pw = getpwuid(cred->uid); if (!pw) return 0; if (getgrouplist(pw->pw_name, cred->gid, &gids[0], &nr_gids) < 0) { nr_gids = 63; } for (i = 0; i < nr_gids; i++) { for (j = 0; j < ac->nr_groups; j++) { ag = &ac->group[j]; if (gids[i] == ag->gid) { if (ag->level <= level) return 1; else break; } } } return 0; }
gint get_user_groups (const gchar *user, gid_t group, gid_t **groups) { gint res; gint ngroups; ngroups = 0; res = getgrouplist (user, group, NULL, &ngroups); g_debug ("user %s has %d groups", user, ngroups); *groups = g_new (gid_t, ngroups); res = getgrouplist (user, group, *groups, &ngroups); return res; }
static void setCredentials(char *user) { struct passwd *pwd; int ngroups; gid_t *groups; /* Look up user in user database */ pwd = getpwnam(user); if (pwd == NULL) { fprintf(stderr, "Unknown user: %s\n", user); exit(EXIT_FAILURE); } /* Find out how many supplementary groups the user is a member of */ ngroups = 0; getgrouplist(user, pwd->pw_gid, NULL, &ngroups); /* Allocate an array for supplementary group IDs */ groups = calloc(ngroups, sizeof(gid_t)); if (groups == NULL) errExit("calloc"); /* Get supplementary group list of 'user' from group database */ if (getgrouplist(user, pwd->pw_gid, groups, &ngroups) == -1) errExit("getgrouplist"); /* Set the supplementary group list */ if (setgroups(ngroups, groups) == -1) errExit("setgroups"); /* Set all group IDs to GID of this user */ if (setresgid(pwd->pw_gid, pwd->pw_gid, pwd->pw_gid) == -1) errExit("setresgid"); /* Set all user IDs to UID of this user */ if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) == -1) errExit("setresuid"); }
int push_groups4(PerThreadContext* ctx, uid_t uid, gid_t gid) { TRY_DECLS(); // check for two pushes without a pop if (ctx->pushed_groups) { LOG(LOG_ERR, "double-push (groups) -> %u\n", uid); errno = EPERM; return -1; } // save the group-list for the current process ctx->group_ct = getgroups(sizeof ctx->groups / sizeof (gid_t), ctx->groups); if (ctx->group_ct < 0) { // ctx->group_ct = 0; // ? LOG(LOG_ERR, "getgroups() failed\n"); return -1; } // find user-name from uid struct passwd pwd; struct passwd* result; const size_t STR_BUF_LEN = 1024; // probably enough char str_buf[STR_BUF_LEN]; if (getpwuid_r(uid, &pwd, str_buf, STR_BUF_LEN, &result)) { LOG(LOG_ERR, "getpwuid_r() failed: %s\n", strerror(errno)); return -EINVAL; } else if (! result) { LOG(LOG_ERR, "No passwd entries found, for uid %u\n", uid); return -EINVAL; } LOG(LOG_INFO, "uid %u = user '%s'\n", uid, result->pw_name); // find group-membership of user, using user-name gid_t groups[NGROUPS_MAX +1]; int ngroups = NGROUPS_MAX +1; int group_ct = getgrouplist(result->pw_name, gid, groups, &ngroups); if (group_ct < 0) { LOG(LOG_ERR, "No passwd entries found, for user '%s'\n", result->pw_name); return -1; } // DEBUGGING int i; for (i=0; i<group_ct; ++i) { LOG(LOG_INFO, "group = %u\n", groups[i]); } // change group membership of process TRY0( setgroups(ngroups, groups) ); ctx->pushed_groups = 1; // so we can pop return 0; }
void _populate_users(Users *us) { UsersItem *u; struct passwd *usr = NULL; us->list = NULL; /*Abre el archivo por defecto para la lectura de los usuarios.*/ setpwent(); usr = getpwent(); while (usr != NULL) { u = NULL; u = (UsersItem *)(malloc (sizeof(UsersItem))); if (u != NULL) { if (usr->pw_uid >= 1000 && usr->pw_uid < 60000) { u->uid = usr->pw_uid; u->gid = usr->pw_gid; u->name = strdup(usr->pw_name); /*u->fullname = strdup(usr->pw_gecos);*/ _parse_gecos(u, usr->pw_gecos); u->home= strdup (usr->pw_dir); u->shell = strdup (usr->pw_shell); u->is_new = FALSE; us->list = g_list_append (us->list, u); u->n_groups = 1; u->groups = malloc (sizeof(gid_t)); /*Obtiene la lista de grupos auxiliares al que pertenec el usuario actual a ser leido * La primera vez, getgrouplist devuelve en el puntero de entero de entrada * en este caso n->groups la cantidad de grupos que realmente tiene el usuario * Para lo cual, una vez obtenido la cantidad total de grupos, se realiza una * segunda llamada con la memoria reservada para la cantidad total. */ if (getgrouplist (u->name, u->gid, u->groups, &u->n_groups)) { g_free(u->groups); u->groups = malloc (u->n_groups * sizeof(gid_t)); getgrouplist (u->name, u->gid, u->groups, &u->n_groups); g_print ("Group: %i\n", u->groups[1]); } } } usr = getpwent(); } endpwent(); }