When running a command as the invoking user we cannot use the gid
list from the front-end since it may not correspond to the user's aux group vector as defined by the group database.
This commit is contained in:
@@ -1697,7 +1697,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
|||||||
sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
|
sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
|
if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
|
||||||
for (i = 0; i < gidlist->ngids; i++) {
|
for (i = 0; i < gidlist->ngids; i++) {
|
||||||
if (pw->pw_gid == gidlist->gids[i])
|
if (pw->pw_gid == gidlist->gids[i])
|
||||||
continue;
|
continue;
|
||||||
|
@@ -540,7 +540,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
|||||||
gid_t egid;
|
gid_t egid;
|
||||||
size_t glsize;
|
size_t glsize;
|
||||||
char *cp, *gid_list;
|
char *cp, *gid_list;
|
||||||
struct gid_list *gidlist = sudo_get_gidlist(runas_pw);
|
struct gid_list *gidlist;
|
||||||
|
|
||||||
|
/* Only use results from a group db query, not the front end. */
|
||||||
|
gidlist = sudo_get_gidlist(runas_pw, ENTRY_TYPE_QUERIED);
|
||||||
|
|
||||||
/* We reserve an extra spot in the list for the effective gid. */
|
/* We reserve an extra spot in the list for the effective gid. */
|
||||||
glsize = sizeof("runas_groups=") - 1 +
|
glsize = sizeof("runas_groups=") - 1 +
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 1998-2005, 2007-2016
|
* Copyright (c) 1996, 1998-2005, 2007-2017
|
||||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@@ -69,7 +69,8 @@ static int cmp_grgid(const void *, const void *);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare by uid.
|
* Compare by user ID.
|
||||||
|
* v1 is the key to find or data to insert, v2 is in-tree data.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmp_pwuid(const void *v1, const void *v2)
|
cmp_pwuid(const void *v1, const void *v2)
|
||||||
@@ -78,11 +79,14 @@ cmp_pwuid(const void *v1, const void *v2)
|
|||||||
const struct cache_item *ci2 = (const struct cache_item *) v2;
|
const struct cache_item *ci2 = (const struct cache_item *) v2;
|
||||||
if (ci1->k.uid == ci2->k.uid)
|
if (ci1->k.uid == ci2->k.uid)
|
||||||
return strcmp(ci1->registry, ci2->registry);
|
return strcmp(ci1->registry, ci2->registry);
|
||||||
return ci1->k.uid - ci2->k.uid;
|
if (ci1->k.uid < ci2->k.uid)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare by user name.
|
* Compare by user/group name.
|
||||||
|
* v1 is the key to find or data to insert, v2 is in-tree data.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmp_pwnam(const void *v1, const void *v2)
|
cmp_pwnam(const void *v1, const void *v2)
|
||||||
@@ -95,6 +99,28 @@ cmp_pwnam(const void *v1, const void *v2)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare by user name, taking into account the source type.
|
||||||
|
* Need to differentiate between group IDs received from the front-end
|
||||||
|
* (via getgroups()) and groups IDs queried from the group database.
|
||||||
|
* v1 is the key to find or data to insert, v2 is in-tree data.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmp_gidlist(const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
const struct cache_item *ci1 = (const struct cache_item *) v1;
|
||||||
|
const struct cache_item *ci2 = (const struct cache_item *) v2;
|
||||||
|
int ret = strcmp(ci1->k.name, ci2->k.name);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (ci1->type == ENTRY_TYPE_ANY || ci1->type == ci2->type)
|
||||||
|
return strcmp(ci1->registry, ci2->registry);
|
||||||
|
if (ci1->type < ci2->type)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sudo_pw_addref(struct passwd *pw)
|
sudo_pw_addref(struct passwd *pw)
|
||||||
{
|
{
|
||||||
@@ -401,7 +427,8 @@ sudo_freepwcache(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare by gid.
|
* Compare by group ID.
|
||||||
|
* v1 is the key to find or data to insert, v2 is in-tree data.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmp_grgid(const void *v1, const void *v2)
|
cmp_grgid(const void *v1, const void *v2)
|
||||||
@@ -410,7 +437,9 @@ cmp_grgid(const void *v1, const void *v2)
|
|||||||
const struct cache_item *ci2 = (const struct cache_item *) v2;
|
const struct cache_item *ci2 = (const struct cache_item *) v2;
|
||||||
if (ci1->k.gid == ci2->k.gid)
|
if (ci1->k.gid == ci2->k.gid)
|
||||||
return strcmp(ci1->registry, ci2->registry);
|
return strcmp(ci1->registry, ci2->registry);
|
||||||
return ci1->k.gid - ci2->k.gid;
|
if (ci1->k.gid < ci2->k.gid)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -836,7 +865,7 @@ sudo_set_grlist(struct passwd *pw, char * const *groups)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct gid_list *
|
struct gid_list *
|
||||||
sudo_get_gidlist(const struct passwd *pw)
|
sudo_get_gidlist(const struct passwd *pw, unsigned int type)
|
||||||
{
|
{
|
||||||
struct cache_item key, *item;
|
struct cache_item key, *item;
|
||||||
struct rbnode *node;
|
struct rbnode *node;
|
||||||
@@ -846,7 +875,7 @@ sudo_get_gidlist(const struct passwd *pw)
|
|||||||
__func__, pw->pw_name);
|
__func__, pw->pw_name);
|
||||||
|
|
||||||
if (gidlist_cache == NULL) {
|
if (gidlist_cache == NULL) {
|
||||||
gidlist_cache = rbcreate(cmp_pwnam);
|
gidlist_cache = rbcreate(cmp_gidlist);
|
||||||
if (gidlist_cache == NULL) {
|
if (gidlist_cache == NULL) {
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
@@ -854,6 +883,7 @@ sudo_get_gidlist(const struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
key.k.name = pw->pw_name;
|
key.k.name = pw->pw_name;
|
||||||
|
key.type = type;
|
||||||
getauthregistry(pw->pw_name, key.registry);
|
getauthregistry(pw->pw_name, key.registry);
|
||||||
if ((node = rbfind(gidlist_cache, &key)) != NULL) {
|
if ((node = rbfind(gidlist_cache, &key)) != NULL) {
|
||||||
item = node->data;
|
item = node->data;
|
||||||
@@ -862,7 +892,7 @@ sudo_get_gidlist(const struct passwd *pw)
|
|||||||
/*
|
/*
|
||||||
* Cache group db entry if it exists or a negative response if not.
|
* Cache group db entry if it exists or a negative response if not.
|
||||||
*/
|
*/
|
||||||
item = sudo_make_gidlist_item(pw, NULL);
|
item = sudo_make_gidlist_item(pw, NULL, type);
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
/* Out of memory? */
|
/* Out of memory? */
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
@@ -896,14 +926,14 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_set_gidlist(struct passwd *pw, char * const *gids)
|
sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type)
|
||||||
{
|
{
|
||||||
struct cache_item key, *item;
|
struct cache_item key, *item;
|
||||||
struct rbnode *node;
|
struct rbnode *node;
|
||||||
debug_decl(sudo_set_gidlist, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_set_gidlist, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
if (gidlist_cache == NULL) {
|
if (gidlist_cache == NULL) {
|
||||||
gidlist_cache = rbcreate(cmp_pwnam);
|
gidlist_cache = rbcreate(cmp_gidlist);
|
||||||
if (gidlist_cache == NULL) {
|
if (gidlist_cache == NULL) {
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
@@ -914,9 +944,10 @@ sudo_set_gidlist(struct passwd *pw, char * const *gids)
|
|||||||
* Cache group db entry if it doesn't already exist
|
* Cache group db entry if it doesn't already exist
|
||||||
*/
|
*/
|
||||||
key.k.name = pw->pw_name;
|
key.k.name = pw->pw_name;
|
||||||
|
key.type = type;
|
||||||
getauthregistry(NULL, key.registry);
|
getauthregistry(NULL, key.registry);
|
||||||
if ((node = rbfind(gidlist_cache, &key)) == NULL) {
|
if ((node = rbfind(gidlist_cache, &key)) == NULL) {
|
||||||
if ((item = sudo_make_gidlist_item(pw, gids)) == NULL) {
|
if ((item = sudo_make_gidlist_item(pw, gids, type)) == NULL) {
|
||||||
sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
|
sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
@@ -961,7 +992,7 @@ user_in_group(const struct passwd *pw, const char *group)
|
|||||||
matched = true;
|
matched = true;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
|
if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
|
||||||
for (i = 0; i < gidlist->ngids; i++) {
|
for (i = 0; i < gidlist->ngids; i++) {
|
||||||
if (gid == gidlist->gids[i]) {
|
if (gid == gidlist->gids[i]) {
|
||||||
matched = true;
|
matched = true;
|
||||||
@@ -992,11 +1023,13 @@ user_in_group(const struct passwd *pw, const char *group)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check the supplementary group vector. */
|
/* Check the supplementary group vector. */
|
||||||
if (gidlist == NULL && (gidlist = sudo_get_gidlist(pw)) != NULL) {
|
if (gidlist == NULL) {
|
||||||
for (i = 0; i < gidlist->ngids; i++) {
|
if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
|
||||||
if (gid == gidlist->gids[i]) {
|
for (i = 0; i < gidlist->ngids; i++) {
|
||||||
matched = true;
|
if (gid == gidlist->gids[i]) {
|
||||||
goto done;
|
matched = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 2010-2013, 2015-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -24,7 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
struct cache_item {
|
struct cache_item {
|
||||||
unsigned int refcnt;
|
unsigned int refcnt;
|
||||||
char registry[16];
|
unsigned int type; /* only used for gidlist */
|
||||||
|
char registry[16]; /* AIX-specific, empty otherwise */
|
||||||
/* key */
|
/* key */
|
||||||
union {
|
union {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
@@ -68,7 +69,7 @@ struct cache_item_gidlist {
|
|||||||
|
|
||||||
struct cache_item *sudo_make_gritem(gid_t gid, const char *group);
|
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);
|
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_gidlist_item(const struct passwd *pw, char * const *gids, unsigned int type);
|
||||||
struct cache_item *sudo_make_pwitem(uid_t uid, const char *user);
|
struct cache_item *sudo_make_pwitem(uid_t uid, const char *user);
|
||||||
|
|
||||||
#endif /* SUDOERS_PWUTIL_H */
|
#endif /* SUDOERS_PWUTIL_H */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 1998-2005, 2007-2015
|
* Copyright (c) 1996, 1998-2005, 2007-2017
|
||||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@@ -230,7 +230,8 @@ sudo_make_gritem(gid_t gid, const char *name)
|
|||||||
* elements. Fills in datum from user_gids or from getgrouplist(3).
|
* elements. Fills in datum from user_gids or from getgrouplist(3).
|
||||||
*/
|
*/
|
||||||
struct cache_item *
|
struct cache_item *
|
||||||
sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1)
|
sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1,
|
||||||
|
unsigned int type)
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
size_t nsize, total;
|
size_t nsize, total;
|
||||||
@@ -240,12 +241,15 @@ sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1)
|
|||||||
int i, ngids;
|
int i, ngids;
|
||||||
debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
if (pw == sudo_user.pw && sudo_user.gids != NULL) {
|
/* Don't use user_gids if the entry type says we must query the db. */
|
||||||
|
if (type != ENTRY_TYPE_QUERIED && pw == sudo_user.pw && sudo_user.gids != NULL) {
|
||||||
gids = user_gids;
|
gids = user_gids;
|
||||||
ngids = user_ngids;
|
ngids = user_ngids;
|
||||||
user_gids = NULL;
|
user_gids = NULL;
|
||||||
user_ngids = 0;
|
user_ngids = 0;
|
||||||
|
type = ENTRY_TYPE_FRONTEND;
|
||||||
} else {
|
} else {
|
||||||
|
type = ENTRY_TYPE_QUERIED;
|
||||||
if (sudo_user.max_groups > 0) {
|
if (sudo_user.max_groups > 0) {
|
||||||
ngids = sudo_user.max_groups;
|
ngids = sudo_user.max_groups;
|
||||||
gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
|
gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
|
||||||
@@ -320,6 +324,7 @@ sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1)
|
|||||||
glitem->cache.k.name = cp;
|
glitem->cache.k.name = cp;
|
||||||
glitem->cache.d.gidlist = gidlist;
|
glitem->cache.d.gidlist = gidlist;
|
||||||
glitem->cache.refcnt = 1;
|
glitem->cache.refcnt = 1;
|
||||||
|
glitem->cache.type = type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store group IDs.
|
* Store group IDs.
|
||||||
@@ -348,7 +353,7 @@ sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
|
|||||||
int i, groupname_len;
|
int i, groupname_len;
|
||||||
debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
gidlist = sudo_get_gidlist(pw);
|
gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY);
|
||||||
if (gidlist == NULL) {
|
if (gidlist == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"no gid list for use %s", pw->pw_name);
|
"no gid list for use %s", pw->pw_name);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1994-1996,1998-2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 1994-1996, 1998-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -1699,8 +1699,9 @@ runas_setgroups(void)
|
|||||||
debug_return_ptr(user_gid_list);
|
debug_return_ptr(user_gid_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only use results from a group db query, not the front end. */
|
||||||
pw = runas_pw ? runas_pw : sudo_user.pw;
|
pw = runas_pw ? runas_pw : sudo_user.pw;
|
||||||
gidlist = sudo_get_gidlist(pw);
|
gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_QUERIED);
|
||||||
if (gidlist != NULL) {
|
if (gidlist != NULL) {
|
||||||
if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
|
if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
|
||||||
sudo_gidlist_delref(gidlist);
|
sudo_gidlist_delref(gidlist);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1993-1996, 1998-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 1993-1996, 1998-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -732,7 +732,7 @@ init_vars(char * const envp[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (user_gid_list == NULL)
|
if (user_gid_list == NULL)
|
||||||
user_gid_list = sudo_get_gidlist(sudo_user.pw);
|
user_gid_list = sudo_get_gidlist(sudo_user.pw, ENTRY_TYPE_ANY);
|
||||||
|
|
||||||
/* Store initialize permissions so we can restore them later. */
|
/* Store initialize permissions so we can restore them later. */
|
||||||
if (!set_perms(PERM_INITIAL))
|
if (!set_perms(PERM_INITIAL))
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1993-1996, 1998-2005, 2007-2016
|
* Copyright (c) 1993-1996, 1998-2005, 2007-2017
|
||||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@@ -110,6 +110,13 @@ struct sudo_user {
|
|||||||
pid_t sid;
|
pid_t sid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sudo_get_gidlist() type values
|
||||||
|
*/
|
||||||
|
#define ENTRY_TYPE_ANY 0x00
|
||||||
|
#define ENTRY_TYPE_QUERIED 0x01
|
||||||
|
#define ENTRY_TYPE_FRONTEND 0x02
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sudo_user flag values
|
* sudo_user flag values
|
||||||
*/
|
*/
|
||||||
@@ -303,7 +310,7 @@ __dso_public void sudo_gr_addref(struct group *);
|
|||||||
__dso_public void sudo_gr_delref(struct group *);
|
__dso_public void sudo_gr_delref(struct group *);
|
||||||
bool user_in_group(const struct passwd *, const char *);
|
bool user_in_group(const struct passwd *, const char *);
|
||||||
struct group *sudo_fakegrnam(const char *);
|
struct group *sudo_fakegrnam(const char *);
|
||||||
struct gid_list *sudo_get_gidlist(const struct passwd *pw);
|
struct gid_list *sudo_get_gidlist(const struct passwd *pw, unsigned int type);
|
||||||
struct group_list *sudo_get_grlist(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_fakepwnam(const char *, gid_t);
|
||||||
struct passwd *sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, const char *shell);
|
struct passwd *sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, const char *shell);
|
||||||
@@ -318,7 +325,7 @@ void sudo_grlist_addref(struct group_list *);
|
|||||||
void sudo_grlist_delref(struct group_list *);
|
void sudo_grlist_delref(struct group_list *);
|
||||||
void sudo_pw_addref(struct passwd *);
|
void sudo_pw_addref(struct passwd *);
|
||||||
void sudo_pw_delref(struct passwd *);
|
void sudo_pw_delref(struct passwd *);
|
||||||
int sudo_set_gidlist(struct passwd *pw, char * const *gids);
|
int sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type);
|
||||||
int sudo_set_grlist(struct passwd *pw, char * const *groups);
|
int sudo_set_grlist(struct passwd *pw, char * const *groups);
|
||||||
void sudo_setspent(void);
|
void sudo_setspent(void);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user