Implement group caching and use the passwd and group caches throughout.
This commit is contained in:
2
check.c
2
check.c
@@ -283,7 +283,7 @@ user_is_exempt()
|
||||
if (!def_exempt_group)
|
||||
return(FALSE);
|
||||
|
||||
if (!(grp = getgrnam(def_exempt_group)))
|
||||
if (!(grp = sudo_getgrnam(def_exempt_group)))
|
||||
return(FALSE);
|
||||
|
||||
if (user_gid == grp->gr_gid)
|
||||
|
202
getspwuid.c
202
getspwuid.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998-2002 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -46,6 +46,7 @@
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#ifdef HAVE_GETSPNAM
|
||||
# include <shadow.h>
|
||||
#endif /* HAVE_GETSPNAM */
|
||||
@@ -80,18 +81,20 @@ static const char rcsid[] = "$Sudo$";
|
||||
#if defined(HAVE_GETPRPWNAM) && defined(__alpha)
|
||||
int crypt_type = INT_MAX;
|
||||
#endif /* HAVE_GETPRPWNAM && __alpha */
|
||||
static struct rbtree *cache_byuid;
|
||||
static struct rbtree *cache_byname;
|
||||
static struct rbtree *pwcache_byuid, *pwcache_byname;
|
||||
static struct rbtree *grcache_bygid, *grcache_byname;
|
||||
|
||||
static int cmp_byuid __P((const VOID *, const VOID *));
|
||||
static int cmp_byname __P((const VOID *, const VOID *));
|
||||
static int cmp_pwuid __P((const VOID *, const VOID *));
|
||||
static int cmp_pwnam __P((const VOID *, const VOID *));
|
||||
static void pw_free __P((VOID *));
|
||||
static int cmp_grgid __P((const VOID *, const VOID *));
|
||||
static int cmp_grnam __P((const VOID *, const VOID *));
|
||||
|
||||
/*
|
||||
* Compare by uid.
|
||||
*/
|
||||
static int
|
||||
cmp_byuid(v1, v2)
|
||||
cmp_pwuid(v1, v2)
|
||||
const VOID *v1;
|
||||
const VOID *v2;
|
||||
{
|
||||
@@ -104,7 +107,7 @@ cmp_byuid(v1, v2)
|
||||
* Compare by user name.
|
||||
*/
|
||||
static int
|
||||
cmp_byname(v1, v2)
|
||||
cmp_pwnam(v1, v2)
|
||||
const VOID *v1;
|
||||
const VOID *v2;
|
||||
{
|
||||
@@ -197,7 +200,7 @@ sudo_getepw(pw)
|
||||
* Dynamically allocate space for a struct password and the constituent parts
|
||||
* that we care about. Fills in pw_passwd from shadow file.
|
||||
*/
|
||||
struct passwd *
|
||||
static struct passwd *
|
||||
sudo_pwdup(pw)
|
||||
const struct passwd *pw;
|
||||
{
|
||||
@@ -300,14 +303,14 @@ sudo_getpwuid(uid)
|
||||
struct rbnode *node;
|
||||
|
||||
key.pw_uid = uid;
|
||||
if ((node = rbfind(cache_byuid, &key)) != NULL)
|
||||
if ((node = rbfind(pwcache_byuid, &key)) != NULL)
|
||||
return((struct passwd *) node->data);
|
||||
if ((pw = getpwuid(uid)) == NULL)
|
||||
return(NULL);
|
||||
else
|
||||
pw = sudo_pwdup(pw);
|
||||
rbinsert(cache_byname, (VOID *) pw);
|
||||
rbinsert(cache_byuid, (VOID *) pw);
|
||||
rbinsert(pwcache_byname, (VOID *) pw);
|
||||
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||
return(pw);
|
||||
}
|
||||
|
||||
@@ -323,14 +326,14 @@ sudo_getpwnam(name)
|
||||
struct rbnode *node;
|
||||
|
||||
key.pw_name = (char *) name;
|
||||
if ((node = rbfind(cache_byname, &key)) != NULL)
|
||||
if ((node = rbfind(pwcache_byname, &key)) != NULL)
|
||||
return((struct passwd *) node->data);
|
||||
if ((pw = getpwnam(name)) == NULL)
|
||||
return(NULL);
|
||||
else
|
||||
pw = sudo_pwdup(pw);
|
||||
rbinsert(cache_byname, (VOID *) pw);
|
||||
rbinsert(cache_byuid, (VOID *) pw);
|
||||
rbinsert(pwcache_byname, (VOID *) pw);
|
||||
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||
return(pw);
|
||||
}
|
||||
|
||||
@@ -349,8 +352,8 @@ sudo_fakepwuid(uid)
|
||||
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
||||
(void) snprintf(pw->pw_name, MAX_UID_T_LEN + 1, "#%lu",
|
||||
(unsigned long) uid);
|
||||
rbinsert(cache_byname, (VOID *) pw);
|
||||
rbinsert(cache_byuid, (VOID *) pw);
|
||||
rbinsert(pwcache_byname, (VOID *) pw);
|
||||
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||
return(pw);
|
||||
}
|
||||
|
||||
@@ -359,7 +362,7 @@ sudo_fakepwuid(uid)
|
||||
*/
|
||||
struct passwd *
|
||||
sudo_fakepwnam(user)
|
||||
char *user;
|
||||
const char *user;
|
||||
{
|
||||
struct passwd *pw;
|
||||
size_t len;
|
||||
@@ -370,8 +373,8 @@ sudo_fakepwnam(user)
|
||||
pw->pw_uid = (uid_t) atoi(user + 1);
|
||||
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
||||
strlcpy(pw->pw_name, user, len + 1);
|
||||
rbinsert(cache_byname, (VOID *) pw);
|
||||
rbinsert(cache_byuid, (VOID *) pw);
|
||||
rbinsert(pwcache_byname, (VOID *) pw);
|
||||
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||
return(pw);
|
||||
}
|
||||
|
||||
@@ -394,8 +397,8 @@ sudo_setpwent()
|
||||
#ifdef HAVE_GETAUTHUID
|
||||
setauthent();
|
||||
#endif
|
||||
cache_byuid = rbcreate(cmp_byuid);
|
||||
cache_byname = rbcreate(cmp_byname);
|
||||
pwcache_byuid = rbcreate(cmp_pwuid);
|
||||
pwcache_byname = rbcreate(cmp_pwnam);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -417,10 +420,10 @@ sudo_endpwent()
|
||||
#ifdef HAVE_GETAUTHUID
|
||||
endauthent();
|
||||
#endif
|
||||
rbdestroy(cache_byuid, pw_free);
|
||||
cache_byuid = NULL;
|
||||
rbdestroy(cache_byname, NULL);
|
||||
cache_byname = NULL;
|
||||
rbdestroy(pwcache_byuid, pw_free);
|
||||
pwcache_byuid = NULL;
|
||||
rbdestroy(pwcache_byname, NULL);
|
||||
pwcache_byname = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -432,3 +435,152 @@ pw_free(v)
|
||||
zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd));
|
||||
free(pw);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare by gid.
|
||||
*/
|
||||
static int
|
||||
cmp_grgid(v1, v2)
|
||||
const VOID *v1;
|
||||
const VOID *v2;
|
||||
{
|
||||
const struct group *grp1 = (const struct group *) v1;
|
||||
const struct group *grp2 = (const struct group *) v2;
|
||||
return(grp1->gr_gid - grp2->gr_gid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare by group name.
|
||||
*/
|
||||
static int
|
||||
cmp_grnam(v1, v2)
|
||||
const VOID *v1;
|
||||
const VOID *v2;
|
||||
{
|
||||
const struct group *grp1 = (const struct group *) v1;
|
||||
const struct group *grp2 = (const struct group *) v2;
|
||||
return(strcmp(grp1->gr_name, grp2->gr_name));
|
||||
}
|
||||
|
||||
void
|
||||
sudo_setgrent()
|
||||
{
|
||||
setgrent();
|
||||
grcache_bygid = rbcreate(cmp_grgid);
|
||||
grcache_byname = rbcreate(cmp_grnam);
|
||||
}
|
||||
|
||||
void
|
||||
sudo_endgrent()
|
||||
{
|
||||
endgrent();
|
||||
rbdestroy(grcache_bygid, free);
|
||||
grcache_bygid = NULL;
|
||||
rbdestroy(grcache_byname, NULL);
|
||||
grcache_byname = NULL;
|
||||
}
|
||||
|
||||
static struct group *
|
||||
sudo_grdup(gr)
|
||||
const struct group *gr;
|
||||
{
|
||||
char *cp;
|
||||
size_t nsize, psize, csize, num, total, len;
|
||||
struct group *newgr;
|
||||
|
||||
/* Allocate in one big chunk for easy freeing. */
|
||||
nsize = psize = csize = num = 0;
|
||||
total = sizeof(struct group);
|
||||
if (gr->gr_name) {
|
||||
nsize = strlen(gr->gr_name) + 1;
|
||||
total += nsize;
|
||||
}
|
||||
if (gr->gr_passwd) {
|
||||
psize = strlen(gr->gr_passwd) + 1;
|
||||
total += psize;
|
||||
}
|
||||
if (gr->gr_mem) {
|
||||
for (num = 0; gr->gr_mem[num] != NULL; num++)
|
||||
total += strlen(gr->gr_mem[num]) + 1;
|
||||
num++;
|
||||
total += sizeof(char *) * num;
|
||||
}
|
||||
if ((cp = malloc(total)) == NULL)
|
||||
return (NULL);
|
||||
newgr = (struct group *)cp;
|
||||
|
||||
/*
|
||||
* Copy in group contents and make strings relative to space
|
||||
* at the end of the buffer.
|
||||
*/
|
||||
(void)memcpy(newgr, gr, sizeof(struct group));
|
||||
cp += sizeof(struct group);
|
||||
if (nsize) {
|
||||
(void)memcpy(cp, gr->gr_name, nsize);
|
||||
newgr->gr_name = cp;
|
||||
cp += nsize;
|
||||
}
|
||||
if (psize) {
|
||||
(void)memcpy(cp, gr->gr_passwd, psize);
|
||||
newgr->gr_passwd = cp;
|
||||
cp += psize;
|
||||
}
|
||||
if (gr->gr_mem) {
|
||||
newgr->gr_mem = (char **)cp;
|
||||
cp += sizeof(char *) * num;
|
||||
for (num = 0; gr->gr_mem[num] != NULL; num++) {
|
||||
len = strlen(gr->gr_mem[num]) + 1;
|
||||
memcpy(cp, gr->gr_mem[num], len);
|
||||
newgr->gr_mem[num] = cp;
|
||||
cp += len;
|
||||
}
|
||||
newgr->gr_mem[num] = NULL;
|
||||
}
|
||||
|
||||
return (newgr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a group entry by gid and allocate space for it.
|
||||
*/
|
||||
struct group *
|
||||
sudo_getgruid(gid)
|
||||
gid_t gid;
|
||||
{
|
||||
struct group key, *gr;
|
||||
struct rbnode *node;
|
||||
|
||||
key.gr_gid = gid;
|
||||
if ((node = rbfind(grcache_bygid, &key)) != NULL)
|
||||
return((struct group *) node->data);
|
||||
if ((gr = getgrgid(gid)) == NULL)
|
||||
return(NULL);
|
||||
else
|
||||
gr = sudo_grdup(gr);
|
||||
rbinsert(grcache_byname, (VOID *) gr);
|
||||
rbinsert(grcache_bygid, (VOID *) gr);
|
||||
return(gr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a group entry by name and allocate space for it.
|
||||
*/
|
||||
struct group *
|
||||
sudo_getgrnam(name)
|
||||
const char *name;
|
||||
{
|
||||
struct group key, *gr;
|
||||
struct rbnode *node;
|
||||
|
||||
key.gr_name = (char *) name;
|
||||
if ((node = rbfind(grcache_byname, &key)) != NULL)
|
||||
return((struct group *) node->data);
|
||||
if ((gr = getgrnam(name)) == NULL)
|
||||
return(NULL);
|
||||
else
|
||||
gr = sudo_grdup(gr);
|
||||
rbinsert(grcache_byname, (VOID *) gr);
|
||||
rbinsert(grcache_bygid, (VOID *) gr);
|
||||
return(gr);
|
||||
}
|
||||
|
||||
|
7
glob.c
7
glob.c
@@ -172,6 +172,9 @@ static int match __P((Char *, Char *, Char *));
|
||||
static void qprintf __P((const char *, Char *));
|
||||
#endif
|
||||
|
||||
extern struct passwd *sudo_getpwnam __P((const char *));
|
||||
extern struct passwd *sudo_getpwuid __P((uid_t));
|
||||
|
||||
int
|
||||
glob(pattern, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
@@ -385,7 +388,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob)
|
||||
* first and then trying the password file
|
||||
*/
|
||||
if ((h = getenv("HOME")) == NULL) {
|
||||
if ((pwd = getpwuid(getuid())) == NULL)
|
||||
if ((pwd = sudo_getpwuid(getuid())) == NULL)
|
||||
return pattern;
|
||||
else
|
||||
h = pwd->pw_dir;
|
||||
@@ -394,7 +397,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob)
|
||||
/*
|
||||
* Expand a ~user
|
||||
*/
|
||||
if ((pwd = getpwnam((char*) patbuf)) == NULL)
|
||||
if ((pwd = sudo_getpwnam((char*) patbuf)) == NULL)
|
||||
return pattern;
|
||||
else
|
||||
h = pwd->pw_dir;
|
||||
|
4
ldap.c
4
ldap.c
@@ -440,7 +440,7 @@ sudo_ldap_build_pass1()
|
||||
ncat(&b,&sz,")");
|
||||
|
||||
/* Append primary group */
|
||||
grp=getgrgid(getgid());
|
||||
grp=sudo_getgrgid(getgid());
|
||||
if (grp!=NULL){
|
||||
ncat(&b,&sz,"(sudoUser=%");
|
||||
ncat(&b,&sz,grp->gr_name);
|
||||
@@ -452,7 +452,7 @@ sudo_ldap_build_pass1()
|
||||
grplist=calloc(ngrps,sizeof(gid_t));
|
||||
if (grplist!=NULL && (0<getgroups(ngrps,grplist)))
|
||||
for(i=0;i<ngrps;i++){
|
||||
if((grp=getgrgid(grplist[i]))!=NULL){
|
||||
if((grp=sudo_getgrgid(grplist[i]))!=NULL){
|
||||
ncat(&b,&sz,"(sudoUser=%");
|
||||
ncat(&b,&sz,grp->gr_name);
|
||||
ncat(&b,&sz,")");
|
||||
|
@@ -492,7 +492,7 @@ send_mail(line)
|
||||
|
||||
/* Close password and group files so we don't leak fds. */
|
||||
sudo_endpwent();
|
||||
endgrent();
|
||||
sudo_endgrent();
|
||||
|
||||
/*
|
||||
* Depending on the config, either run the mailer as root
|
||||
|
14
match.c
14
match.c
@@ -528,7 +528,7 @@ userpw_matches(sudoers_user, user, pw)
|
||||
/*
|
||||
* Returns TRUE if the given user belongs to the named group,
|
||||
* else returns FALSE.
|
||||
* XXX - reduce the number of passwd/group lookups
|
||||
* XXX - reduce the number of group lookups
|
||||
*/
|
||||
int
|
||||
usergr_matches(group, user, pw)
|
||||
@@ -539,24 +539,32 @@ usergr_matches(group, user, pw)
|
||||
struct group *grp;
|
||||
gid_t pw_gid;
|
||||
char **cur;
|
||||
int n;
|
||||
|
||||
/* make sure we have a valid usergroup, sudo style */
|
||||
if (*group++ != '%')
|
||||
return(FALSE);
|
||||
|
||||
/* look up user's primary gid in the passwd file */
|
||||
if (pw == NULL && (pw = getpwnam(user)) == NULL)
|
||||
if (pw == NULL && (pw = sudo_getpwnam(user)) == NULL)
|
||||
return(FALSE);
|
||||
pw_gid = pw->pw_gid;
|
||||
|
||||
if ((grp = getgrnam(group)) == NULL)
|
||||
if ((grp = sudo_getgrnam(group)) == NULL)
|
||||
return(FALSE);
|
||||
|
||||
/* check against user's primary (passwd file) gid */
|
||||
if (grp->gr_gid == pw_gid)
|
||||
return(TRUE);
|
||||
|
||||
/* check the user's group vector */
|
||||
n = user_ngroups;
|
||||
while (n--)
|
||||
if (grp->gr_gid == user_groups[n])
|
||||
return(TRUE);
|
||||
|
||||
/* check to see if user is explicitly listed in the group */
|
||||
/* XXX - skip if group vector is set? */
|
||||
for (cur = grp->gr_mem; *cur; cur++) {
|
||||
if (strcmp(*cur, user) == 0)
|
||||
return(TRUE);
|
||||
|
@@ -22,9 +22,6 @@ typedef int (*schandler_t)
|
||||
struct childinfo;
|
||||
struct listhead;
|
||||
|
||||
extern struct passwd *sudo_getpwuid __P((uid_t));
|
||||
extern struct passwd *sudo_fakepwuid __P((uid_t));
|
||||
|
||||
static int check_execv __P((int, pid_t, u_int16_t,
|
||||
struct str_msg_ask *, int, int *, int *));
|
||||
static int check_execve __P((int, pid_t, u_int16_t,
|
||||
|
16
sudo.c
16
sudo.c
@@ -107,9 +107,6 @@ static struct passwd *get_authpw __P((void));
|
||||
extern int sudo_edit __P((int, char **));
|
||||
extern char **rebuild_env __P((char **, int, int));
|
||||
extern char **zero_env __P((char **));
|
||||
extern struct passwd *sudo_fakepwnam __P((const char *));
|
||||
extern struct passwd *sudo_getpwnam __P((const char *));
|
||||
extern struct passwd *sudo_getpwuid __P((uid_t));
|
||||
|
||||
/*
|
||||
* Globals
|
||||
@@ -194,6 +191,7 @@ main(argc, argv, envp)
|
||||
*/
|
||||
initial_setup();
|
||||
sudo_setpwent();
|
||||
sudo_setgrent();
|
||||
|
||||
/* Parse our arguments. */
|
||||
sudo_mode = parse_args(Argc, Argv);
|
||||
@@ -294,9 +292,9 @@ main(argc, argv, envp)
|
||||
struct passwd *pw;
|
||||
|
||||
if (*def_timestampowner == '#')
|
||||
pw = getpwuid(atoi(def_timestampowner + 1));
|
||||
pw = sudo_getpwuid(atoi(def_timestampowner + 1));
|
||||
else
|
||||
pw = getpwnam(def_timestampowner);
|
||||
pw = sudo_getpwnam(def_timestampowner);
|
||||
if (!pw)
|
||||
log_error(0, "timestamp owner (%s): No such user",
|
||||
def_timestampowner);
|
||||
@@ -397,7 +395,7 @@ main(argc, argv, envp)
|
||||
|
||||
/* Close the password and group files */
|
||||
sudo_endpwent();
|
||||
endgrent();
|
||||
sudo_endgrent();
|
||||
|
||||
/* Install the real environment. */
|
||||
environ = new_environ;
|
||||
@@ -555,6 +553,12 @@ init_vars(sudo_mode)
|
||||
|
||||
/* It is now safe to use log_error() and set_perms() */
|
||||
|
||||
if ((user_ngroups = getgroups(0, NULL)) > 0) {
|
||||
user_groups = emalloc2(user_ngroups, sizeof(gid_t));
|
||||
if (getgroups(user_ngroups, user_groups) < 0)
|
||||
log_error(USE_ERRNO|MSG_ONLY, "can't get group vector");
|
||||
}
|
||||
|
||||
if (def_fqdn)
|
||||
set_fqdn(); /* may call log_error() */
|
||||
|
||||
|
14
sudo.h
14
sudo.h
@@ -40,7 +40,6 @@ struct sudo_user {
|
||||
char *path;
|
||||
char *shell;
|
||||
char *tty;
|
||||
char cwd[PATH_MAX];
|
||||
char *host;
|
||||
char *shost;
|
||||
char **runas;
|
||||
@@ -50,6 +49,9 @@ struct sudo_user {
|
||||
char *cmnd_base;
|
||||
char *cmnd_safe;
|
||||
char *class_name;
|
||||
int ngroups;
|
||||
gid_t *groups;
|
||||
char cwd[PATH_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -123,6 +125,8 @@ struct sudo_user {
|
||||
#define user_gid (sudo_user.pw->pw_gid)
|
||||
#define user_dir (sudo_user.pw->pw_dir)
|
||||
#define user_shell (sudo_user.shell)
|
||||
#define user_ngroups (sudo_user.ngroups)
|
||||
#define user_groups (sudo_user.groups)
|
||||
#define user_tty (sudo_user.tty)
|
||||
#define user_cwd (sudo_user.cwd)
|
||||
#define user_runas (sudo_user.runas)
|
||||
@@ -240,7 +244,15 @@ FILE *open_sudoers __P((const char *, int *));
|
||||
void display_privs __P((struct passwd *));
|
||||
void sudo_setpwent __P((void));
|
||||
void sudo_endpwent __P((void));
|
||||
void sudo_setgrent __P((void));
|
||||
void sudo_endgrent __P((void));
|
||||
void cleanup __P((void));
|
||||
struct passwd *sudo_getpwnam __P((const char *));
|
||||
struct passwd *sudo_fakepwnam __P((const char *));
|
||||
struct passwd *sudo_getpwuid __P((uid_t));
|
||||
struct passwd *sudo_fakepwuid __P((uid_t));
|
||||
struct group *sudo_getgrnam __P((const char *));
|
||||
struct group *sudo_getgrgid __P((gid_t));
|
||||
#ifdef HAVE_SYSTRACE
|
||||
void systrace_attach __P((pid_t));
|
||||
#endif
|
||||
|
@@ -147,10 +147,14 @@ main(argc, argv)
|
||||
if (!dflag)
|
||||
usage();
|
||||
user_name = "nobody";
|
||||
user_cmnd = "true";
|
||||
user_cmnd = user_base = "true";
|
||||
} else {
|
||||
user_name = *argv++;
|
||||
user_cmnd = *argv;
|
||||
if ((p = strrchr(user_cmnd, '/')) != NULL)
|
||||
user_base = p + 1;
|
||||
else
|
||||
user_base = user_cmnd;
|
||||
NewArgc -= 2;
|
||||
}
|
||||
|
||||
@@ -275,6 +279,34 @@ set_perms(perm)
|
||||
return;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
sudo_getpwuid(uid)
|
||||
uid_t uid;
|
||||
{
|
||||
return(getpwuid(uid));
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
sudo_getpwnam(name)
|
||||
const char *name;
|
||||
{
|
||||
return(getpwnam(name));
|
||||
}
|
||||
|
||||
struct group *
|
||||
sudo_getgrgid(gid)
|
||||
gid_t gid;
|
||||
{
|
||||
return(getgrgid(gid));
|
||||
}
|
||||
|
||||
struct group *
|
||||
sudo_getgrnam(name)
|
||||
const char *name;
|
||||
{
|
||||
return(getgrnam(name));
|
||||
}
|
||||
|
||||
void
|
||||
cleanup()
|
||||
{
|
||||
|
33
visudo.c
33
visudo.c
@@ -60,6 +60,7 @@
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
@@ -524,6 +525,38 @@ user_is_exempt()
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
struct passwd *
|
||||
sudo_getpwuid(uid)
|
||||
uid_t uid;
|
||||
{
|
||||
return(getpwuid(uid));
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
struct passwd *
|
||||
sudo_getpwnam(name)
|
||||
const char *name;
|
||||
{
|
||||
return(getpwnam(name));
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
struct group *
|
||||
sudo_getgrgid(gid)
|
||||
gid_t gid;
|
||||
{
|
||||
return(getgrgid(gid));
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
struct group *
|
||||
sudo_getgrnam(name)
|
||||
const char *name;
|
||||
{
|
||||
return(getgrnam(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Assuming a parse error occurred, prompt the user for what they want
|
||||
* to do now. Returns the first letter of their choice.
|
||||
|
Reference in New Issue
Block a user