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)
|
if (!def_exempt_group)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
||||||
if (!(grp = getgrnam(def_exempt_group)))
|
if (!(grp = sudo_getgrnam(def_exempt_group)))
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
||||||
if (user_gid == grp->gr_gid)
|
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
|
* 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
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* HAVE_UNISTD_H */
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
#ifdef HAVE_GETSPNAM
|
#ifdef HAVE_GETSPNAM
|
||||||
# include <shadow.h>
|
# include <shadow.h>
|
||||||
#endif /* HAVE_GETSPNAM */
|
#endif /* HAVE_GETSPNAM */
|
||||||
@@ -80,18 +81,20 @@ static const char rcsid[] = "$Sudo$";
|
|||||||
#if defined(HAVE_GETPRPWNAM) && defined(__alpha)
|
#if defined(HAVE_GETPRPWNAM) && defined(__alpha)
|
||||||
int crypt_type = INT_MAX;
|
int crypt_type = INT_MAX;
|
||||||
#endif /* HAVE_GETPRPWNAM && __alpha */
|
#endif /* HAVE_GETPRPWNAM && __alpha */
|
||||||
static struct rbtree *cache_byuid;
|
static struct rbtree *pwcache_byuid, *pwcache_byname;
|
||||||
static struct rbtree *cache_byname;
|
static struct rbtree *grcache_bygid, *grcache_byname;
|
||||||
|
|
||||||
static int cmp_byuid __P((const VOID *, const VOID *));
|
static int cmp_pwuid __P((const VOID *, const VOID *));
|
||||||
static int cmp_byname __P((const VOID *, const VOID *));
|
static int cmp_pwnam __P((const VOID *, const VOID *));
|
||||||
static void pw_free __P((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.
|
* Compare by uid.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmp_byuid(v1, v2)
|
cmp_pwuid(v1, v2)
|
||||||
const VOID *v1;
|
const VOID *v1;
|
||||||
const VOID *v2;
|
const VOID *v2;
|
||||||
{
|
{
|
||||||
@@ -104,7 +107,7 @@ cmp_byuid(v1, v2)
|
|||||||
* Compare by user name.
|
* Compare by user name.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmp_byname(v1, v2)
|
cmp_pwnam(v1, v2)
|
||||||
const VOID *v1;
|
const VOID *v1;
|
||||||
const VOID *v2;
|
const VOID *v2;
|
||||||
{
|
{
|
||||||
@@ -197,7 +200,7 @@ sudo_getepw(pw)
|
|||||||
* Dynamically allocate space for a struct password and the constituent parts
|
* Dynamically allocate space for a struct password and the constituent parts
|
||||||
* that we care about. Fills in pw_passwd from shadow file.
|
* that we care about. Fills in pw_passwd from shadow file.
|
||||||
*/
|
*/
|
||||||
struct passwd *
|
static struct passwd *
|
||||||
sudo_pwdup(pw)
|
sudo_pwdup(pw)
|
||||||
const struct passwd *pw;
|
const struct passwd *pw;
|
||||||
{
|
{
|
||||||
@@ -300,14 +303,14 @@ sudo_getpwuid(uid)
|
|||||||
struct rbnode *node;
|
struct rbnode *node;
|
||||||
|
|
||||||
key.pw_uid = uid;
|
key.pw_uid = uid;
|
||||||
if ((node = rbfind(cache_byuid, &key)) != NULL)
|
if ((node = rbfind(pwcache_byuid, &key)) != NULL)
|
||||||
return((struct passwd *) node->data);
|
return((struct passwd *) node->data);
|
||||||
if ((pw = getpwuid(uid)) == NULL)
|
if ((pw = getpwuid(uid)) == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
else
|
else
|
||||||
pw = sudo_pwdup(pw);
|
pw = sudo_pwdup(pw);
|
||||||
rbinsert(cache_byname, (VOID *) pw);
|
rbinsert(pwcache_byname, (VOID *) pw);
|
||||||
rbinsert(cache_byuid, (VOID *) pw);
|
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||||
return(pw);
|
return(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,14 +326,14 @@ sudo_getpwnam(name)
|
|||||||
struct rbnode *node;
|
struct rbnode *node;
|
||||||
|
|
||||||
key.pw_name = (char *) name;
|
key.pw_name = (char *) name;
|
||||||
if ((node = rbfind(cache_byname, &key)) != NULL)
|
if ((node = rbfind(pwcache_byname, &key)) != NULL)
|
||||||
return((struct passwd *) node->data);
|
return((struct passwd *) node->data);
|
||||||
if ((pw = getpwnam(name)) == NULL)
|
if ((pw = getpwnam(name)) == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
else
|
else
|
||||||
pw = sudo_pwdup(pw);
|
pw = sudo_pwdup(pw);
|
||||||
rbinsert(cache_byname, (VOID *) pw);
|
rbinsert(pwcache_byname, (VOID *) pw);
|
||||||
rbinsert(cache_byuid, (VOID *) pw);
|
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||||
return(pw);
|
return(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,8 +352,8 @@ sudo_fakepwuid(uid)
|
|||||||
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
||||||
(void) snprintf(pw->pw_name, MAX_UID_T_LEN + 1, "#%lu",
|
(void) snprintf(pw->pw_name, MAX_UID_T_LEN + 1, "#%lu",
|
||||||
(unsigned long) uid);
|
(unsigned long) uid);
|
||||||
rbinsert(cache_byname, (VOID *) pw);
|
rbinsert(pwcache_byname, (VOID *) pw);
|
||||||
rbinsert(cache_byuid, (VOID *) pw);
|
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||||
return(pw);
|
return(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +362,7 @@ sudo_fakepwuid(uid)
|
|||||||
*/
|
*/
|
||||||
struct passwd *
|
struct passwd *
|
||||||
sudo_fakepwnam(user)
|
sudo_fakepwnam(user)
|
||||||
char *user;
|
const char *user;
|
||||||
{
|
{
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -370,8 +373,8 @@ sudo_fakepwnam(user)
|
|||||||
pw->pw_uid = (uid_t) atoi(user + 1);
|
pw->pw_uid = (uid_t) atoi(user + 1);
|
||||||
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
pw->pw_name = (char *)pw + sizeof(struct passwd);
|
||||||
strlcpy(pw->pw_name, user, len + 1);
|
strlcpy(pw->pw_name, user, len + 1);
|
||||||
rbinsert(cache_byname, (VOID *) pw);
|
rbinsert(pwcache_byname, (VOID *) pw);
|
||||||
rbinsert(cache_byuid, (VOID *) pw);
|
rbinsert(pwcache_byuid, (VOID *) pw);
|
||||||
return(pw);
|
return(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,8 +397,8 @@ sudo_setpwent()
|
|||||||
#ifdef HAVE_GETAUTHUID
|
#ifdef HAVE_GETAUTHUID
|
||||||
setauthent();
|
setauthent();
|
||||||
#endif
|
#endif
|
||||||
cache_byuid = rbcreate(cmp_byuid);
|
pwcache_byuid = rbcreate(cmp_pwuid);
|
||||||
cache_byname = rbcreate(cmp_byname);
|
pwcache_byname = rbcreate(cmp_pwnam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -417,10 +420,10 @@ sudo_endpwent()
|
|||||||
#ifdef HAVE_GETAUTHUID
|
#ifdef HAVE_GETAUTHUID
|
||||||
endauthent();
|
endauthent();
|
||||||
#endif
|
#endif
|
||||||
rbdestroy(cache_byuid, pw_free);
|
rbdestroy(pwcache_byuid, pw_free);
|
||||||
cache_byuid = NULL;
|
pwcache_byuid = NULL;
|
||||||
rbdestroy(cache_byname, NULL);
|
rbdestroy(pwcache_byname, NULL);
|
||||||
cache_byname = NULL;
|
pwcache_byname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -432,3 +435,152 @@ pw_free(v)
|
|||||||
zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd));
|
zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd));
|
||||||
free(pw);
|
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 *));
|
static void qprintf __P((const char *, Char *));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern struct passwd *sudo_getpwnam __P((const char *));
|
||||||
|
extern struct passwd *sudo_getpwuid __P((uid_t));
|
||||||
|
|
||||||
int
|
int
|
||||||
glob(pattern, flags, errfunc, pglob)
|
glob(pattern, flags, errfunc, pglob)
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
@@ -385,7 +388,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob)
|
|||||||
* first and then trying the password file
|
* first and then trying the password file
|
||||||
*/
|
*/
|
||||||
if ((h = getenv("HOME")) == NULL) {
|
if ((h = getenv("HOME")) == NULL) {
|
||||||
if ((pwd = getpwuid(getuid())) == NULL)
|
if ((pwd = sudo_getpwuid(getuid())) == NULL)
|
||||||
return pattern;
|
return pattern;
|
||||||
else
|
else
|
||||||
h = pwd->pw_dir;
|
h = pwd->pw_dir;
|
||||||
@@ -394,7 +397,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob)
|
|||||||
/*
|
/*
|
||||||
* Expand a ~user
|
* Expand a ~user
|
||||||
*/
|
*/
|
||||||
if ((pwd = getpwnam((char*) patbuf)) == NULL)
|
if ((pwd = sudo_getpwnam((char*) patbuf)) == NULL)
|
||||||
return pattern;
|
return pattern;
|
||||||
else
|
else
|
||||||
h = pwd->pw_dir;
|
h = pwd->pw_dir;
|
||||||
|
4
ldap.c
4
ldap.c
@@ -440,7 +440,7 @@ sudo_ldap_build_pass1()
|
|||||||
ncat(&b,&sz,")");
|
ncat(&b,&sz,")");
|
||||||
|
|
||||||
/* Append primary group */
|
/* Append primary group */
|
||||||
grp=getgrgid(getgid());
|
grp=sudo_getgrgid(getgid());
|
||||||
if (grp!=NULL){
|
if (grp!=NULL){
|
||||||
ncat(&b,&sz,"(sudoUser=%");
|
ncat(&b,&sz,"(sudoUser=%");
|
||||||
ncat(&b,&sz,grp->gr_name);
|
ncat(&b,&sz,grp->gr_name);
|
||||||
@@ -452,7 +452,7 @@ sudo_ldap_build_pass1()
|
|||||||
grplist=calloc(ngrps,sizeof(gid_t));
|
grplist=calloc(ngrps,sizeof(gid_t));
|
||||||
if (grplist!=NULL && (0<getgroups(ngrps,grplist)))
|
if (grplist!=NULL && (0<getgroups(ngrps,grplist)))
|
||||||
for(i=0;i<ngrps;i++){
|
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,"(sudoUser=%");
|
||||||
ncat(&b,&sz,grp->gr_name);
|
ncat(&b,&sz,grp->gr_name);
|
||||||
ncat(&b,&sz,")");
|
ncat(&b,&sz,")");
|
||||||
|
@@ -492,7 +492,7 @@ send_mail(line)
|
|||||||
|
|
||||||
/* Close password and group files so we don't leak fds. */
|
/* Close password and group files so we don't leak fds. */
|
||||||
sudo_endpwent();
|
sudo_endpwent();
|
||||||
endgrent();
|
sudo_endgrent();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Depending on the config, either run the mailer as root
|
* 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,
|
* Returns TRUE if the given user belongs to the named group,
|
||||||
* else returns FALSE.
|
* else returns FALSE.
|
||||||
* XXX - reduce the number of passwd/group lookups
|
* XXX - reduce the number of group lookups
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
usergr_matches(group, user, pw)
|
usergr_matches(group, user, pw)
|
||||||
@@ -539,24 +539,32 @@ usergr_matches(group, user, pw)
|
|||||||
struct group *grp;
|
struct group *grp;
|
||||||
gid_t pw_gid;
|
gid_t pw_gid;
|
||||||
char **cur;
|
char **cur;
|
||||||
|
int n;
|
||||||
|
|
||||||
/* make sure we have a valid usergroup, sudo style */
|
/* make sure we have a valid usergroup, sudo style */
|
||||||
if (*group++ != '%')
|
if (*group++ != '%')
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
||||||
/* look up user's primary gid in the passwd file */
|
/* 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);
|
return(FALSE);
|
||||||
pw_gid = pw->pw_gid;
|
pw_gid = pw->pw_gid;
|
||||||
|
|
||||||
if ((grp = getgrnam(group)) == NULL)
|
if ((grp = sudo_getgrnam(group)) == NULL)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
||||||
/* check against user's primary (passwd file) gid */
|
/* check against user's primary (passwd file) gid */
|
||||||
if (grp->gr_gid == pw_gid)
|
if (grp->gr_gid == pw_gid)
|
||||||
return(TRUE);
|
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 */
|
/* 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++) {
|
for (cur = grp->gr_mem; *cur; cur++) {
|
||||||
if (strcmp(*cur, user) == 0)
|
if (strcmp(*cur, user) == 0)
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
@@ -22,9 +22,6 @@ typedef int (*schandler_t)
|
|||||||
struct childinfo;
|
struct childinfo;
|
||||||
struct listhead;
|
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,
|
static int check_execv __P((int, pid_t, u_int16_t,
|
||||||
struct str_msg_ask *, int, int *, int *));
|
struct str_msg_ask *, int, int *, int *));
|
||||||
static int check_execve __P((int, pid_t, u_int16_t,
|
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 int sudo_edit __P((int, char **));
|
||||||
extern char **rebuild_env __P((char **, int, int));
|
extern char **rebuild_env __P((char **, int, int));
|
||||||
extern char **zero_env __P((char **));
|
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
|
* Globals
|
||||||
@@ -194,6 +191,7 @@ main(argc, argv, envp)
|
|||||||
*/
|
*/
|
||||||
initial_setup();
|
initial_setup();
|
||||||
sudo_setpwent();
|
sudo_setpwent();
|
||||||
|
sudo_setgrent();
|
||||||
|
|
||||||
/* Parse our arguments. */
|
/* Parse our arguments. */
|
||||||
sudo_mode = parse_args(Argc, Argv);
|
sudo_mode = parse_args(Argc, Argv);
|
||||||
@@ -294,9 +292,9 @@ main(argc, argv, envp)
|
|||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
if (*def_timestampowner == '#')
|
if (*def_timestampowner == '#')
|
||||||
pw = getpwuid(atoi(def_timestampowner + 1));
|
pw = sudo_getpwuid(atoi(def_timestampowner + 1));
|
||||||
else
|
else
|
||||||
pw = getpwnam(def_timestampowner);
|
pw = sudo_getpwnam(def_timestampowner);
|
||||||
if (!pw)
|
if (!pw)
|
||||||
log_error(0, "timestamp owner (%s): No such user",
|
log_error(0, "timestamp owner (%s): No such user",
|
||||||
def_timestampowner);
|
def_timestampowner);
|
||||||
@@ -397,7 +395,7 @@ main(argc, argv, envp)
|
|||||||
|
|
||||||
/* Close the password and group files */
|
/* Close the password and group files */
|
||||||
sudo_endpwent();
|
sudo_endpwent();
|
||||||
endgrent();
|
sudo_endgrent();
|
||||||
|
|
||||||
/* Install the real environment. */
|
/* Install the real environment. */
|
||||||
environ = new_environ;
|
environ = new_environ;
|
||||||
@@ -555,6 +553,12 @@ init_vars(sudo_mode)
|
|||||||
|
|
||||||
/* It is now safe to use log_error() and set_perms() */
|
/* 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)
|
if (def_fqdn)
|
||||||
set_fqdn(); /* may call log_error() */
|
set_fqdn(); /* may call log_error() */
|
||||||
|
|
||||||
|
14
sudo.h
14
sudo.h
@@ -40,7 +40,6 @@ struct sudo_user {
|
|||||||
char *path;
|
char *path;
|
||||||
char *shell;
|
char *shell;
|
||||||
char *tty;
|
char *tty;
|
||||||
char cwd[PATH_MAX];
|
|
||||||
char *host;
|
char *host;
|
||||||
char *shost;
|
char *shost;
|
||||||
char **runas;
|
char **runas;
|
||||||
@@ -50,6 +49,9 @@ struct sudo_user {
|
|||||||
char *cmnd_base;
|
char *cmnd_base;
|
||||||
char *cmnd_safe;
|
char *cmnd_safe;
|
||||||
char *class_name;
|
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_gid (sudo_user.pw->pw_gid)
|
||||||
#define user_dir (sudo_user.pw->pw_dir)
|
#define user_dir (sudo_user.pw->pw_dir)
|
||||||
#define user_shell (sudo_user.shell)
|
#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_tty (sudo_user.tty)
|
||||||
#define user_cwd (sudo_user.cwd)
|
#define user_cwd (sudo_user.cwd)
|
||||||
#define user_runas (sudo_user.runas)
|
#define user_runas (sudo_user.runas)
|
||||||
@@ -240,7 +244,15 @@ FILE *open_sudoers __P((const char *, int *));
|
|||||||
void display_privs __P((struct passwd *));
|
void display_privs __P((struct passwd *));
|
||||||
void sudo_setpwent __P((void));
|
void sudo_setpwent __P((void));
|
||||||
void sudo_endpwent __P((void));
|
void sudo_endpwent __P((void));
|
||||||
|
void sudo_setgrent __P((void));
|
||||||
|
void sudo_endgrent __P((void));
|
||||||
void cleanup __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
|
#ifdef HAVE_SYSTRACE
|
||||||
void systrace_attach __P((pid_t));
|
void systrace_attach __P((pid_t));
|
||||||
#endif
|
#endif
|
||||||
|
@@ -147,10 +147,14 @@ main(argc, argv)
|
|||||||
if (!dflag)
|
if (!dflag)
|
||||||
usage();
|
usage();
|
||||||
user_name = "nobody";
|
user_name = "nobody";
|
||||||
user_cmnd = "true";
|
user_cmnd = user_base = "true";
|
||||||
} else {
|
} else {
|
||||||
user_name = *argv++;
|
user_name = *argv++;
|
||||||
user_cmnd = *argv;
|
user_cmnd = *argv;
|
||||||
|
if ((p = strrchr(user_cmnd, '/')) != NULL)
|
||||||
|
user_base = p + 1;
|
||||||
|
else
|
||||||
|
user_base = user_cmnd;
|
||||||
NewArgc -= 2;
|
NewArgc -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +279,34 @@ set_perms(perm)
|
|||||||
return;
|
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
|
void
|
||||||
cleanup()
|
cleanup()
|
||||||
{
|
{
|
||||||
|
33
visudo.c
33
visudo.c
@@ -60,6 +60,7 @@
|
|||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* HAVE_UNISTD_H */
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -524,6 +525,38 @@ user_is_exempt()
|
|||||||
return(FALSE);
|
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
|
* Assuming a parse error occurred, prompt the user for what they want
|
||||||
* to do now. Returns the first letter of their choice.
|
* to do now. Returns the first letter of their choice.
|
||||||
|
Reference in New Issue
Block a user