LDAP *ld;
struct ldap_result *result;
const char *username;
- struct group_list *grlist;
+ struct gid_list *gidlist;
};
struct sudo_nss sudo_nss_ldap = {
char *buf, timebuffer[TIMEFILTER_LENGTH + 1], gidbuf[MAX_UID_T_LEN + 1];
struct ldap_netgroup_list netgroups;
struct ldap_netgroup *ng, *nextng;
+ struct gid_list *gidlist;
struct group_list *grlist;
struct group *grp;
size_t sz = 0;
continue;
sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
}
- for (i = 0; i < grlist->ngids; i++) {
- if (pw->pw_gid == grlist->gids[i])
+ }
+ if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (pw->pw_gid == gidlist->gids[i])
continue;
sz += 13 + MAX_UID_T_LEN;
}
CHECK_LDAP_VCAT(buf, grlist->groups[i], sz);
CHECK_STRLCAT(buf, ")", sz);
}
- for (i = 0; i < grlist->ngids; i++) {
- if (pw->pw_gid == grlist->gids[i])
+ }
+ if (gidlist != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (pw->pw_gid == gidlist->gids[i])
continue;
(void) snprintf(gidbuf, sizeof(gidbuf), "%u",
- (unsigned int)grlist->gids[i]);
+ (unsigned int)gidlist->gids[i]);
CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
CHECK_STRLCAT(buf, gidbuf, sz);
CHECK_STRLCAT(buf, ")", sz);
}
/* Done with groups. */
+ if (gidlist != NULL)
+ sudo_gidlist_delref(gidlist);
if (grlist != NULL)
sudo_grlist_delref(grlist);
if (grp != NULL)
handle->ld = ld;
/* handle->result = NULL; */
/* handle->username = NULL; */
- /* handle->grlist = NULL; */
+ /* handle->gidlist = NULL; */
nss->handle = handle;
done:
DPRINTF1("removing reusable search result");
sudo_ldap_result_free(handle->result);
handle->username = NULL;
- handle->grlist = NULL;
+ handle->gidlist = NULL;
handle->result = NULL;
}
debug_return;
* have to contact the LDAP server again.
*/
if (handle->result) {
- if (handle->grlist == user_group_list &&
+ if (handle->gidlist == user_gid_list &&
strcmp(pw->pw_name, handle->username) == 0) {
DPRINTF1("reusing previous result (user %s) with %d entries",
handle->username, handle->result->nentries);
/* Store everything in the sudo_nss handle. */
/* XXX - store pw and take a reference to it. */
+ /* XXX - take refs for gidlist and grlist */
handle->result = lres;
handle->username = pw->pw_name;
- handle->grlist = user_group_list;
+ handle->gidlist = user_gid_list;
debug_return_ptr(lres);
}
gid_t egid;
size_t glsize;
char *cp, *gid_list;
- struct group_list *grlist = sudo_get_grlist(runas_pw);
+ struct gid_list *gidlist = sudo_get_gidlist(runas_pw);
/* We reserve an extra spot in the list for the effective gid. */
glsize = sizeof("runas_groups=") - 1 +
- ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
+ ((gidlist->ngids + 1) * (MAX_UID_T_LEN + 1));
gid_list = malloc(glsize);
if (gid_list == NULL)
goto oom;
goto bad;
}
cp += len;
- for (i = 0; i < grlist->ngids; i++) {
- if (grlist->gids[i] != egid) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (gidlist->gids[i] != egid) {
len = snprintf(cp, glsize - (cp - gid_list), ",%u",
- (unsigned int) grlist->gids[i]);
+ (unsigned int) gidlist->gids[i]);
if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) {
sudo_warnx(U_("internal error, %s overflow"), __func__);
free(gid_list);
}
}
command_info[info_len++] = gid_list;
- sudo_grlist_delref(grlist);
+ sudo_gidlist_delref(gidlist);
}
if (def_closefrom >= 0) {
if (asprintf(&command_info[info_len++], "closefrom=%d", def_closefrom) == -1)
sudo_gr_delref(runas_gr);
runas_gr = NULL;
}
- if (user_group_list != NULL) {
- sudo_grlist_delref(user_group_list);
- user_group_list = NULL;
+ if (user_gid_list != NULL) {
+ sudo_gidlist_delref(user_gid_list);
+ user_gid_list = NULL;
}
free(user_gids);
user_gids = NULL;
*/
static struct rbtree *pwcache_byuid, *pwcache_byname;
static struct rbtree *grcache_bygid, *grcache_byname;
-static struct rbtree *grlist_cache;
+static struct rbtree *gidlist_cache, *grlist_cache;
static int cmp_pwuid(const void *, const void *);
static int cmp_pwnam(const void *, const void *);
debug_return_ptr(item->d.gr);
}
+void
+sudo_gidlist_addref(struct gid_list *gidlist)
+{
+ debug_decl(sudo_gidlist_addref, SUDOERS_DEBUG_NSS)
+ ptr_to_item(gidlist)->refcnt++;
+ debug_return;
+}
+
+static void
+sudo_gidlist_delref_item(void *v)
+{
+ struct cache_item *item = v;
+ debug_decl(sudo_gidlist_delref_item, SUDOERS_DEBUG_NSS)
+
+ if (--item->refcnt == 0)
+ free(item);
+
+ debug_return;
+}
+
+void
+sudo_gidlist_delref(struct gid_list *gidlist)
+{
+ debug_decl(sudo_gidlist_delref, SUDOERS_DEBUG_NSS)
+ sudo_gidlist_delref_item(ptr_to_item(gidlist));
+ debug_return;
+}
+
void
sudo_grlist_addref(struct group_list *grlist)
{
- debug_decl(sudo_gr_addref, SUDOERS_DEBUG_NSS)
+ debug_decl(sudo_grlist_addref, SUDOERS_DEBUG_NSS)
ptr_to_item(grlist)->refcnt++;
debug_return;
}
sudo_grlist_delref_item(void *v)
{
struct cache_item *item = v;
- debug_decl(sudo_gr_delref_item, SUDOERS_DEBUG_NSS)
+ debug_decl(sudo_grlist_delref_item, SUDOERS_DEBUG_NSS)
if (--item->refcnt == 0)
free(item);
void
sudo_grlist_delref(struct group_list *grlist)
{
- debug_decl(sudo_gr_delref, SUDOERS_DEBUG_NSS)
+ debug_decl(sudo_grlist_delref, SUDOERS_DEBUG_NSS)
sudo_grlist_delref_item(ptr_to_item(grlist));
debug_return;
}
rbdestroy(grlist_cache, sudo_grlist_delref_item);
grlist_cache = NULL;
}
+ if (gidlist_cache != NULL) {
+ rbdestroy(gidlist_cache, sudo_gidlist_delref_item);
+ gidlist_cache = NULL;
+ }
debug_return;
}
struct rbnode *node;
debug_decl(sudo_get_grlist, SUDOERS_DEBUG_NSS)
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group names for %s",
+ __func__, pw->pw_name);
+
if (grlist_cache == NULL) {
- grlist_cache = rbcreate(cmp_grnam);
+ grlist_cache = rbcreate(cmp_pwnam);
if (grlist_cache == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_ptr(NULL);
/*
* Cache group db entry if it exists or a negative response if not.
*/
- item = sudo_make_grlist_item(pw, NULL, NULL);
+ item = sudo_make_grlist_item(pw, NULL);
if (item == NULL) {
/* Out of memory? */
debug_return_ptr(NULL);
}
int
-sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
+sudo_set_grlist(struct passwd *pw, char * const *groups)
{
struct cache_item key, *item;
struct rbnode *node;
debug_decl(sudo_set_grlist, SUDOERS_DEBUG_NSS)
if (grlist_cache == NULL) {
- grlist_cache = rbcreate(cmp_grnam);
+ grlist_cache = rbcreate(cmp_pwnam);
if (grlist_cache == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_int(-1);
key.k.name = pw->pw_name;
getauthregistry(NULL, key.registry);
if ((node = rbfind(grlist_cache, &key)) == NULL) {
- if ((item = sudo_make_grlist_item(pw, groups, gids)) == NULL) {
+ if ((item = sudo_make_grlist_item(pw, groups)) == NULL) {
sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
debug_return_int(-1);
}
debug_return_int(0);
}
+struct gid_list *
+sudo_get_gidlist(const struct passwd *pw)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_get_gidlist, SUDOERS_DEBUG_NSS)
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group IDs for %s",
+ __func__, pw->pw_name);
+
+ if (gidlist_cache == NULL) {
+ gidlist_cache = rbcreate(cmp_pwnam);
+ if (gidlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.name = pw->pw_name;
+ getauthregistry(pw->pw_name, key.registry);
+ if ((node = rbfind(gidlist_cache, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache group db entry if it exists or a negative response if not.
+ */
+ item = sudo_make_gidlist_item(pw, NULL);
+ if (item == NULL) {
+ /* Out of memory? */
+ debug_return_ptr(NULL);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(gidlist_cache, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ }
+ if (item->d.gidlist != NULL) {
+ int i;
+ for (i = 0; i < item->d.gidlist->ngids; i++) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: user %s has supplementary gid %u", __func__,
+ pw->pw_name, (unsigned int)item->d.gidlist->gids[i]);
+ }
+ }
+done:
+ item->refcnt++;
+ debug_return_ptr(item->d.gidlist);
+}
+
+int
+sudo_set_gidlist(struct passwd *pw, char * const *gids)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_set_gidlist, SUDOERS_DEBUG_NSS)
+
+ if (gidlist_cache == NULL) {
+ gidlist_cache = rbcreate(cmp_pwnam);
+ if (gidlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ }
+
+ /*
+ * Cache group db entry if it doesn't already exist
+ */
+ key.k.name = pw->pw_name;
+ getauthregistry(NULL, key.registry);
+ if ((node = rbfind(gidlist_cache, &key)) == NULL) {
+ if ((item = sudo_make_gidlist_item(pw, gids)) == NULL) {
+ sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
+ debug_return_int(-1);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(gidlist_cache, item, NULL)) {
+ case 1:
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ sudo_gidlist_delref_item(item);
+ break;
+ case -1:
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ sudo_gidlist_delref_item(item);
+ debug_return_int(-1);
+ }
+ }
+ debug_return_int(0);
+}
+
bool
user_in_group(const struct passwd *pw, const char *group)
{
- struct group_list *grlist;
+ struct group_list *grlist = NULL;
+ struct gid_list *gidlist = NULL;
struct group *grp = NULL;
const char *errstr;
int i;
bool matched = false;
debug_decl(user_in_group, SUDOERS_DEBUG_NSS)
- if ((grlist = sudo_get_grlist(pw)) != NULL) {
+ if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
/*
* If it could be a sudo-style group ID check gids first.
*/
matched = true;
goto done;
}
- for (i = 0; i < grlist->ngids; i++) {
- if (gid == grlist->gids[i]) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (gid == gidlist->gids[i]) {
matched = true;
goto done;
}
* Next check the supplementary group vector.
* It usually includes the password db group too.
*/
- for (i = 0; i < grlist->ngroups; i++) {
- if (strcasecmp(group, grlist->groups[i]) == 0) {
- matched = true;
- goto done;
+ if ((grlist = sudo_get_grlist(pw)) != NULL) {
+ for (i = 0; i < grlist->ngroups; i++) {
+ if (strcasecmp(group, grlist->groups[i]) == 0) {
+ matched = true;
+ goto done;
+ }
}
}
done:
if (grp != NULL)
sudo_gr_delref(grp);
- sudo_grlist_delref(grlist);
+ if (grlist != NULL)
+ sudo_grlist_delref(grlist);
+ sudo_gidlist_delref(gidlist);
}
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: user %s %sin group %s",
__func__, pw->pw_name, matched ? "" : "NOT ", group);
struct passwd *pw;
struct group *gr;
struct group_list *grlist;
+ struct gid_list *gidlist;
} d;
};
/*
* Container structs to simpify size and offset calculations and guarantee
- * proper aligment of struct passwd, group and group_list.
+ * proper aligment of struct passwd, group, gid_list and group_list.
*/
struct cache_item_pw {
struct cache_item cache;
/* actually bigger */
};
+struct cache_item_gidlist {
+ struct cache_item cache;
+ struct gid_list gidlist;
+ /* actually bigger */
+};
+
struct cache_item *sudo_make_gritem(gid_t gid, const char *group);
-struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups, char * const *gids);
+struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups);
+struct cache_item *sudo_make_gidlist_item(const struct passwd *pw, char * const *gids);
struct cache_item *sudo_make_pwitem(uid_t uid, const char *user);
#endif /* SUDOERS_PWUTIL_H */
* elements. Fills in datum from user_gids or from getgrouplist(3).
*/
struct cache_item *
-sudo_make_grlist_item(const struct passwd *pw, char * const *unused1,
- char * const *unused2)
+sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1)
{
char *cp;
- size_t nsize, ngroups, total, len;
- struct cache_item_grlist *grlitem;
- struct group_list *grlist;
+ size_t nsize, total;
+ struct cache_item_gidlist *glitem;
+ struct gid_list *gidlist;
GETGROUPS_T *gids;
- struct group *grp = NULL;
- int i, ngids, groupname_len;
- debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+ int i, ngids;
+ debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
if (pw == sudo_user.pw && sudo_user.gids != NULL) {
gids = user_gids;
debug_return_ptr(NULL);
}
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = strlen(pw->pw_name) + 1;
+ total = sizeof(*glitem) + nsize;
+ total += sizeof(gid_t *) * ngids;
+
+ if ((glitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(gids);
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group list and make pointers relative to space
+ * at the end of the buffer. Note that the groups array must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ gidlist = &glitem->gidlist;
+ cp = (char *)(glitem + 1);
+ gidlist->gids = (gid_t *)cp;
+ cp += sizeof(gid_t) * ngids;
+
+ /* Set key and datum. */
+ memcpy(cp, pw->pw_name, nsize);
+ glitem->cache.k.name = cp;
+ glitem->cache.d.gidlist = gidlist;
+ glitem->cache.refcnt = 1;
+
+ /*
+ * Store group IDs.
+ */
+ for (i = 0; i < ngids; i++)
+ gidlist->gids[i] = gids[i];
+ gidlist->ngids = ngids;
+ free(gids);
+
+ debug_return_ptr(&glitem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. Fills in group names from a call to sudo_get_gidlist().
+ */
+struct cache_item *
+sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
+{
+ char *cp;
+ size_t nsize, ngroups, total, len;
+ struct cache_item_grlist *grlitem;
+ struct group_list *grlist;
+ struct gid_list *gidlist;
+ struct group *grp = NULL;
+ int i, groupname_len;
+ debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+
+ gidlist = sudo_get_gidlist(pw);
+ if (gidlist == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "no gid list for use %s", pw->pw_name);
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
#ifdef _SC_LOGIN_NAME_MAX
groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
#else
/* Allocate in one big chunk for easy freeing. */
nsize = strlen(pw->pw_name) + 1;
total = sizeof(*grlitem) + nsize;
- total += sizeof(char *) * ngids;
- total += sizeof(gid_t *) * ngids;
- total += groupname_len * ngids;
+ total += groupname_len * gidlist->ngids;
again:
if ((grlitem = calloc(1, total)) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
- free(gids);
+ sudo_gidlist_delref(gidlist);
debug_return_ptr(NULL);
}
grlist = &grlitem->grlist;
cp = (char *)(grlitem + 1);
grlist->groups = (char **)cp;
- cp += sizeof(char *) * ngids;
- grlist->gids = (gid_t *)cp;
- cp += sizeof(gid_t) * ngids;
+ cp += sizeof(char *) * gidlist->ngids;
/* Set key and datum. */
memcpy(cp, pw->pw_name, nsize);
grlitem->cache.refcnt = 1;
cp += nsize;
- /*
- * Store group IDs.
- */
- for (i = 0; i < ngids; i++)
- grlist->gids[i] = gids[i];
- grlist->ngids = ngids;
-
/*
* Resolve and store group names by ID.
*/
aix_setauthdb((char *) pw->pw_name, NULL);
#endif
ngroups = 0;
- for (i = 0; i < ngids; i++) {
- if ((grp = sudo_getgrgid(gids[i])) != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) {
len = strlen(grp->gr_name) + 1;
if (cp - (char *)grlitem + len > total) {
total += len + groupname_len;
}
}
grlist->ngroups = ngroups;
- free(gids);
+ sudo_gidlist_delref(gidlist);
#ifdef HAVE_SETAUTHDB
aix_restoreauthdb();
* Prototypes
*/
#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
-static struct group_list *runas_setgroups(void);
+static struct gid_list *runas_setgroups(void);
#endif
/*
#if defined(HAVE_SETRESUID) || defined(ID_SAVED)
gid_t sgid;
#endif
- struct group_list *grlist;
+ struct gid_list *gidlist;
};
#define PERM_STACK_MAX 16
if (!restore_perms())
debug_return_bool(false);
}
- sudo_grlist_delref(perm_stack[0].grlist);
+ sudo_gidlist_delref(perm_stack[0].gidlist);
}
debug_return_bool(true);
state->egid = getegid();
state->sgid = state->egid; /* in case we are setgid */
#endif
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
"ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
__func__, (int)state->ruid, (int)state->euid, (int)state->suid,
errstr = N_("unable to change to root gid");
goto bad;
}
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
break;
case PERM_USER:
ID(rgid), ID(egid), ID(sgid));
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_USER: setgroups";
goto bad;
}
ID(rgid), ID(egid), ID(sgid));
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_FULL_USER: setgroups";
goto bad;
}
errstr = N_("unable to change to runas gid");
goto bad;
}
- state->grlist = runas_setgroups();
- if (state->grlist == NULL) {
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
errstr = N_("unable to set runas group vector");
goto bad;
}
break;
case PERM_SUDOERS:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
/* assumes euid == ROOT_UID, ruid == user */
state->rgid = ostate->rgid;
break;
case PERM_TIMESTAMP:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
state->rgid = ostate->rgid;
state->egid = ostate->egid;
state->sgid = ostate->sgid;
(int)OID(rgid), (int)OID(egid), (int)OID(sgid));
goto bad;
}
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
sudo_warn("setgroups()");
goto bad;
}
}
- sudo_grlist_delref(state->grlist);
+ sudo_gidlist_delref(state->gidlist);
debug_return_bool(true);
bad:
state->rgid = getgidx(ID_REAL);
state->egid = getgidx(ID_EFFECTIVE);
state->sgid = getgidx(ID_SAVED);
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
"ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
__func__, (unsigned int)state->ruid, (unsigned int)state->euid,
errstr = N_("unable to change to root gid");
goto bad;
}
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
break;
case PERM_USER:
"PERM_USER: setgidx(ID_EFFECTIVE, %d)", user_gid);
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_USER: setgroups";
goto bad;
}
user_gid);
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_FULL_USER: setgroups";
goto bad;
}
errstr = N_("unable to change to runas gid");
goto bad;
}
- state->grlist = runas_setgroups();
- if (state->grlist == NULL) {
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
errstr = N_("unable to set runas group vector");
goto bad;
}
break;
case PERM_SUDOERS:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
/* assume euid == ROOT_UID, ruid == user */
state->rgid = ostate->rgid;
break;
case PERM_TIMESTAMP:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
state->rgid = ostate->rgid;
state->egid = ostate->egid;
state->sgid = ostate->sgid;
}
}
}
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
sudo_warn("setgroups()");
goto bad;
}
}
- sudo_grlist_delref(state->grlist);
+ sudo_gidlist_delref(state->gidlist);
debug_return_bool(true);
bad:
state->euid = geteuid();
state->rgid = getgid();
state->egid = getegid();
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
"ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
(int)state->ruid, (int)state->euid,
"PERM_ROOT: setregid(%d, %d)", ID(rgid), ID(egid));
goto bad;
}
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
break;
case PERM_USER:
"PERM_USER: setregid(%d, %d)", ID(rgid), ID(egid));
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_USER: setgroups";
goto bad;
}
"PERM_FULL_USER: setregid(%d, %d)", ID(rgid), ID(egid));
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_FULL_USER: setgroups";
goto bad;
}
errstr = N_("unable to change to runas gid");
goto bad;
}
- state->grlist = runas_setgroups();
- if (state->grlist == NULL) {
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
errstr = N_("unable to set runas group vector");
goto bad;
}
break;
case PERM_SUDOERS:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
/* assume euid == ROOT_UID, ruid == user */
state->rgid = ostate->rgid;
break;
case PERM_TIMESTAMP:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
state->rgid = ostate->rgid;
state->egid = ostate->egid;
state->ruid = ROOT_UID;
(int)state->egid, (int)OID(rgid), (int)OID(egid));
goto bad;
}
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
sudo_warn("setgroups()");
goto bad;
}
}
- sudo_grlist_delref(state->grlist);
+ sudo_gidlist_delref(state->gidlist);
debug_return_bool(true);
bad:
state->euid = geteuid();
state->rgid = getgid();
state->egid = getegid();
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
"ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
(int)state->ruid, (int)state->euid,
errstr = N_("unable to change to root gid");
goto bad;
}
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
break;
case PERM_USER:
"PERM_USER: setegid(%d)", user_gid);
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_USER: setgroups";
goto bad;
}
"PERM_FULL_USER: setgid(%d)", user_gid);
goto bad;
}
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_FULL_USER: setgroups";
goto bad;
}
errstr = N_("unable to change to runas gid");
goto bad;
}
- state->grlist = runas_setgroups();
- if (state->grlist == NULL) {
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
errstr = N_("unable to set runas group vector");
goto bad;
}
break;
case PERM_SUDOERS:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
/* assume euid == ROOT_UID, ruid == user */
state->rgid = ostate->rgid;
break;
case PERM_TIMESTAMP:
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
state->rgid = ostate->rgid;
state->egid = ostate->egid;
state->ruid = ROOT_UID;
sudo_warn("setegid(%d)", (int)ostate->egid);
goto bad;
}
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
sudo_warn("setgroups()");
goto bad;
}
sudo_warn("seteuid(%d)", ostate->euid);
goto bad;
}
- sudo_grlist_delref(state->grlist);
+ sudo_gidlist_delref(state->gidlist);
debug_return_bool(true);
bad:
/* Stash initial state */
state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
state->rgid = getgid();
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
"ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
break;
case PERM_ROOT:
state->ruid = ROOT_UID;
state->rgid = ROOT_GID;
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
"[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
if (setuid(ROOT_UID)) {
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
"[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
(void) setgid(user_gid);
- state->grlist = user_group_list;
- sudo_grlist_addref(state->grlist);
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
errstr = "PERM_FULL_USER: setgroups";
goto bad;
}
/* Unsupported since we can't set euid. */
state->ruid = ostate->ruid;
state->rgid = ostate->rgid;
- state->grlist = ostate->grlist;
- sudo_grlist_addref(state->grlist);
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
break;
}
sudo_warn("setgid(%d)", (int)ostate->rgid);
goto bad;
}
- if (state->grlist != ostate->grlist) {
- if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
sudo_warn("setgroups()");
goto bad;
}
}
- sudo_grlist_delref(state->grlist);
+ sudo_gidlist_delref(state->gidlist);
if (OID(ruid) != (uid_t)-1 && setuid(ostate->ruid)) {
sudo_warn("setuid(%d)", (int)ostate->ruid);
goto bad;
#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
-static struct group_list *
+static struct gid_list *
runas_setgroups(void)
{
struct passwd *pw;
- struct group_list *grlist;
+ struct gid_list *gidlist;
debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS)
if (def_preserve_groups) {
- sudo_grlist_addref(user_group_list);
- debug_return_ptr(user_group_list);
+ sudo_gidlist_addref(user_gid_list);
+ debug_return_ptr(user_gid_list);
}
pw = runas_pw ? runas_pw : sudo_user.pw;
- grlist = sudo_get_grlist(pw);
- if (grlist != NULL) {
- if (sudo_setgroups(grlist->ngids, grlist->gids) < 0) {
- sudo_grlist_delref(grlist);
- grlist = NULL;
+ gidlist = sudo_get_gidlist(pw);
+ if (gidlist != NULL) {
+ if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
+ sudo_gidlist_delref(gidlist);
+ gidlist = NULL;
}
}
- debug_return_ptr(grlist);
+ debug_return_ptr(gidlist);
}
#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
unknown_user = true;
}
}
- if (user_group_list == NULL)
- user_group_list = sudo_get_grlist(sudo_user.pw);
+ if (user_gid_list == NULL)
+ user_gid_list = sudo_get_gidlist(sudo_user.pw);
/* Store initialize permissions so we can restore them later. */
if (!set_perms(PERM_INITIAL))
#include "sudoers_debug.h"
/*
- * Password db and supplementary group IDs with associated group names.
+ * Supplementary group IDs for a user.
*/
-struct group_list {
- char **groups;
+struct gid_list {
+ int ngids;
GETGROUPS_T *gids;
+};
+
+/*
+ * Supplementary group names for a user.
+ */
+struct group_list {
int ngroups;
- int ngids;
+ char **groups;
};
/*
char *cmnd_safe;
char *class_name;
char *krb5_ccname;
- struct group_list *group_list;
+ struct gid_list *gid_list;
char * const * env_vars;
#ifdef HAVE_SELINUX
char *role;
#define user_dir (sudo_user.pw->pw_dir)
#define user_gids (sudo_user.gids)
#define user_ngids (sudo_user.ngids)
-#define user_group_list (sudo_user.group_list)
+#define user_gid_list (sudo_user.gid_list)
#define user_tty (sudo_user.tty)
#define user_ttypath (sudo_user.ttypath)
#define user_cwd (sudo_user.cwd)
__dso_public void sudo_gr_delref(struct group *);
bool user_in_group(const struct passwd *, const char *);
struct group *sudo_fakegrnam(const char *);
+struct gid_list *sudo_get_gidlist(const struct passwd *pw);
struct group_list *sudo_get_grlist(const struct passwd *pw);
struct passwd *sudo_fakepwnam(const char *, gid_t);
struct passwd *sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, const char *shell);
void sudo_endspent(void);
void sudo_freegrcache(void);
void sudo_freepwcache(void);
+void sudo_gidlist_addref(struct gid_list *);
+void sudo_gidlist_delref(struct gid_list *);
void sudo_grlist_addref(struct group_list *);
void sudo_grlist_delref(struct group_list *);
void sudo_pw_addref(struct passwd *);
void sudo_pw_delref(struct passwd *);
-int sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids);
+int sudo_set_gidlist(struct passwd *pw, char * const *gids);
+int sudo_set_grlist(struct passwd *pw, char * const *groups);
void sudo_setspent(void);
/* timestr.c */