Cache the user's group IDs and group names separately and only
resolve group IDs -> names when needed. If the sudoers file doesn't contain groups we will no longer try to resolve all the user's group IDs to names, which can be expensive on some systems.
This commit is contained in:
@@ -392,7 +392,7 @@ struct sudo_ldap_handle {
|
||||
LDAP *ld;
|
||||
struct ldap_result *result;
|
||||
const char *username;
|
||||
struct group_list *grlist;
|
||||
struct gid_list *gidlist;
|
||||
};
|
||||
|
||||
struct sudo_nss sudo_nss_ldap = {
|
||||
@@ -1598,6 +1598,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
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;
|
||||
@@ -1628,8 +1629,10 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
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;
|
||||
}
|
||||
@@ -1696,11 +1699,13 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
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);
|
||||
@@ -1708,6 +1713,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
}
|
||||
|
||||
/* Done with groups. */
|
||||
if (gidlist != NULL)
|
||||
sudo_gidlist_delref(gidlist);
|
||||
if (grlist != NULL)
|
||||
sudo_grlist_delref(grlist);
|
||||
if (grp != NULL)
|
||||
@@ -3101,7 +3108,7 @@ sudo_ldap_open(struct sudo_nss *nss)
|
||||
handle->ld = ld;
|
||||
/* handle->result = NULL; */
|
||||
/* handle->username = NULL; */
|
||||
/* handle->grlist = NULL; */
|
||||
/* handle->gidlist = NULL; */
|
||||
nss->handle = handle;
|
||||
|
||||
done:
|
||||
@@ -3372,7 +3379,7 @@ sudo_ldap_result_free_nss(struct sudo_nss *nss)
|
||||
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;
|
||||
@@ -3400,7 +3407,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
|
||||
* 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);
|
||||
@@ -3501,9 +3508,10 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@@ -492,11 +492,11 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||||
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;
|
||||
@@ -513,10 +513,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||||
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);
|
||||
@@ -526,7 +526,7 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -678,9 +678,9 @@ sudoers_policy_close(int exit_status, int error_code)
|
||||
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;
|
||||
|
@@ -48,7 +48,7 @@
|
||||
*/
|
||||
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 *);
|
||||
@@ -652,10 +652,38 @@ sudo_fakegrnam(const char *group)
|
||||
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;
|
||||
}
|
||||
@@ -664,7 +692,7 @@ static void
|
||||
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);
|
||||
@@ -675,7 +703,7 @@ sudo_grlist_delref_item(void *v)
|
||||
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;
|
||||
}
|
||||
@@ -697,6 +725,10 @@ sudo_freegrcache(void)
|
||||
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;
|
||||
}
|
||||
@@ -708,8 +740,11 @@ sudo_get_grlist(const struct passwd *pw)
|
||||
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);
|
||||
@@ -725,7 +760,7 @@ sudo_get_grlist(const struct passwd *pw)
|
||||
/*
|
||||
* 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);
|
||||
@@ -759,14 +794,14 @@ done:
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -779,7 +814,7 @@ sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
|
||||
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);
|
||||
}
|
||||
@@ -800,17 +835,120 @@ sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
|
||||
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.
|
||||
*/
|
||||
@@ -824,8 +962,8 @@ user_in_group(const struct passwd *pw, const char *group)
|
||||
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;
|
||||
}
|
||||
@@ -837,12 +975,14 @@ user_in_group(const struct passwd *pw, const char *group)
|
||||
* Next check the supplementary group vector.
|
||||
* It usually includes the password db group too.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally check against user's primary (passwd file) group. */
|
||||
if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
|
||||
@@ -854,7 +994,9 @@ user_in_group(const struct passwd *pw, const char *group)
|
||||
done:
|
||||
if (grp != NULL)
|
||||
sudo_gr_delref(grp);
|
||||
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);
|
||||
|
@@ -36,12 +36,13 @@ struct cache_item {
|
||||
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;
|
||||
@@ -59,8 +60,15 @@ struct cache_item_grlist {
|
||||
/* 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 */
|
||||
|
@@ -230,17 +230,15 @@ sudo_make_gritem(gid_t gid, const char *name)
|
||||
* 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;
|
||||
@@ -286,27 +284,88 @@ sudo_make_grlist_item(const struct passwd *pw, char * const *unused1,
|
||||
debug_return_ptr(NULL);
|
||||
}
|
||||
|
||||
#ifdef _SC_LOGIN_NAME_MAX
|
||||
groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
|
||||
#else
|
||||
groupname_len = MAX(LOGIN_NAME_MAX, 32);
|
||||
#endif
|
||||
|
||||
/* Allocate in one big chunk for easy freeing. */
|
||||
nsize = strlen(pw->pw_name) + 1;
|
||||
total = sizeof(*grlitem) + nsize;
|
||||
total += sizeof(char *) * ngids;
|
||||
total = sizeof(*glitem) + nsize;
|
||||
total += sizeof(gid_t *) * ngids;
|
||||
total += groupname_len * ngids;
|
||||
|
||||
again:
|
||||
if ((grlitem = calloc(1, total)) == NULL) {
|
||||
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
|
||||
groupname_len = MAX(LOGIN_NAME_MAX, 32);
|
||||
#endif
|
||||
|
||||
/* Allocate in one big chunk for easy freeing. */
|
||||
nsize = strlen(pw->pw_name) + 1;
|
||||
total = sizeof(*grlitem) + nsize;
|
||||
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");
|
||||
sudo_gidlist_delref(gidlist);
|
||||
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
|
||||
@@ -315,9 +374,7 @@ again:
|
||||
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);
|
||||
@@ -326,13 +383,6 @@ again:
|
||||
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.
|
||||
*/
|
||||
@@ -341,8 +391,8 @@ again:
|
||||
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;
|
||||
@@ -357,7 +407,7 @@ again:
|
||||
}
|
||||
}
|
||||
grlist->ngroups = ngroups;
|
||||
free(gids);
|
||||
sudo_gidlist_delref(gidlist);
|
||||
|
||||
#ifdef HAVE_SETAUTHDB
|
||||
aix_restoreauthdb();
|
||||
|
@@ -44,7 +44,7 @@
|
||||
* 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
|
||||
|
||||
/*
|
||||
@@ -62,7 +62,7 @@ struct perm_state {
|
||||
#if defined(HAVE_SETRESUID) || defined(ID_SAVED)
|
||||
gid_t sgid;
|
||||
#endif
|
||||
struct group_list *grlist;
|
||||
struct gid_list *gidlist;
|
||||
};
|
||||
|
||||
#define PERM_STACK_MAX 16
|
||||
@@ -84,7 +84,7 @@ rewind_perms(void)
|
||||
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);
|
||||
@@ -147,8 +147,8 @@ set_perms(int perm)
|
||||
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,
|
||||
@@ -180,8 +180,8 @@ set_perms(int perm)
|
||||
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:
|
||||
@@ -197,10 +197,10 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -234,10 +234,10 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -269,8 +269,8 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -288,8 +288,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -328,8 +328,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -402,13 +402,13 @@ restore_perms(void)
|
||||
(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:
|
||||
@@ -459,8 +459,8 @@ set_perms(int perm)
|
||||
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,
|
||||
@@ -493,8 +493,8 @@ set_perms(int perm)
|
||||
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:
|
||||
@@ -510,10 +510,10 @@ set_perms(int perm)
|
||||
"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;
|
||||
}
|
||||
@@ -555,10 +555,10 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -590,8 +590,8 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -609,8 +609,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -658,8 +658,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -805,13 +805,13 @@ restore_perms(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
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:
|
||||
@@ -860,8 +860,8 @@ set_perms(int perm)
|
||||
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,
|
||||
@@ -901,8 +901,8 @@ set_perms(int perm)
|
||||
"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:
|
||||
@@ -916,10 +916,10 @@ set_perms(int perm)
|
||||
"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;
|
||||
}
|
||||
@@ -948,10 +948,10 @@ set_perms(int perm)
|
||||
"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;
|
||||
}
|
||||
@@ -978,8 +978,8 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -995,8 +995,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -1030,8 +1030,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -1103,13 +1103,13 @@ restore_perms(void)
|
||||
(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:
|
||||
@@ -1173,8 +1173,8 @@ set_perms(int perm)
|
||||
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,
|
||||
@@ -1197,8 +1197,8 @@ set_perms(int perm)
|
||||
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:
|
||||
@@ -1212,10 +1212,10 @@ set_perms(int perm)
|
||||
"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;
|
||||
}
|
||||
@@ -1244,10 +1244,10 @@ set_perms(int perm)
|
||||
"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;
|
||||
}
|
||||
@@ -1274,8 +1274,8 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -1291,8 +1291,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -1326,8 +1326,8 @@ set_perms(int perm)
|
||||
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;
|
||||
@@ -1394,8 +1394,8 @@ restore_perms(void)
|
||||
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;
|
||||
}
|
||||
@@ -1404,7 +1404,7 @@ restore_perms(void)
|
||||
sudo_warn("seteuid(%d)", ostate->euid);
|
||||
goto bad;
|
||||
}
|
||||
sudo_grlist_delref(state->grlist);
|
||||
sudo_gidlist_delref(state->gidlist);
|
||||
debug_return_bool(true);
|
||||
|
||||
bad:
|
||||
@@ -1447,8 +1447,8 @@ set_perms(int perm)
|
||||
/* 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;
|
||||
@@ -1456,8 +1456,8 @@ set_perms(int perm)
|
||||
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)) {
|
||||
@@ -1477,10 +1477,10 @@ set_perms(int perm)
|
||||
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;
|
||||
}
|
||||
@@ -1502,8 +1502,8 @@ set_perms(int perm)
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -1541,13 +1541,13 @@ restore_perms(void)
|
||||
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;
|
||||
@@ -1560,26 +1560,26 @@ 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 */
|
||||
|
@@ -695,8 +695,8 @@ init_vars(char * const envp[])
|
||||
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))
|
||||
|
@@ -45,13 +45,19 @@
|
||||
#include "sudoers_debug.h"
|
||||
|
||||
/*
|
||||
* Password db and supplementary group IDs with associated group names.
|
||||
* Supplementary group IDs for a user.
|
||||
*/
|
||||
struct gid_list {
|
||||
int ngids;
|
||||
GETGROUPS_T *gids;
|
||||
};
|
||||
|
||||
/*
|
||||
* Supplementary group names for a user.
|
||||
*/
|
||||
struct group_list {
|
||||
char **groups;
|
||||
GETGROUPS_T *gids;
|
||||
int ngroups;
|
||||
int ngids;
|
||||
char **groups;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -77,7 +83,7 @@ struct sudo_user {
|
||||
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;
|
||||
@@ -183,7 +189,7 @@ struct sudo_user {
|
||||
#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)
|
||||
@@ -294,6 +300,7 @@ __dso_public void sudo_gr_addref(struct group *);
|
||||
__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);
|
||||
@@ -302,11 +309,14 @@ struct passwd *sudo_getpwuid(uid_t);
|
||||
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 */
|
||||
|
Reference in New Issue
Block a user