mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-30 13:58:05 +00:00
Move all but the shadow stuff from getspwuid.c to pwutil.c and pwcache_get
and pwcache_put as they are no longer needed. Also add preprocessor magic to use private versions of the passwd and group routines if MYPW is defined (for use by testsudoers).
This commit is contained in:
169
getspwuid.c
169
getspwuid.c
@@ -75,17 +75,12 @@ static const char rcsid[] = "$Sudo$";
|
|||||||
#endif /* lint */
|
#endif /* lint */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global variables (yuck)
|
* Exported for auth/secureware.c
|
||||||
*/
|
*/
|
||||||
#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 */
|
||||||
|
|
||||||
extern VOID *pwcache_get __P((enum cmptype, VOID *));
|
|
||||||
extern int pwcache_put __P((enum cmptype, VOID *));
|
|
||||||
extern struct passwd *sudo_pwdup __P((const struct passwd *));
|
|
||||||
extern struct group *sudo_grdup __P((const struct group *));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a copy of the encrypted password for the user described by pw.
|
* Return a copy of the encrypted password for the user described by pw.
|
||||||
* If shadow passwords are in use, look in the shadow file.
|
* If shadow passwords are in use, look in the shadow file.
|
||||||
@@ -166,83 +161,9 @@ sudo_getepw(pw)
|
|||||||
return(estrdup(pw->pw_passwd));
|
return(estrdup(pw->pw_passwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a password entry by uid and allocate space for it.
|
|
||||||
* Fills in pw_passwd from shadow file if necessary.
|
|
||||||
*/
|
|
||||||
struct passwd *
|
|
||||||
sudo_getpwuid(uid)
|
|
||||||
uid_t uid;
|
|
||||||
{
|
|
||||||
struct passwd key, *pw;
|
|
||||||
|
|
||||||
key.pw_uid = uid;
|
|
||||||
if ((pw = pwcache_get(byuid, &key)) != NULL)
|
|
||||||
return(pw);
|
|
||||||
/*
|
|
||||||
* Cache passwd db entry if it exists or a negative response if not.
|
|
||||||
*/
|
|
||||||
if ((pw = getpwuid(uid)) != NULL) {
|
|
||||||
pw = sudo_pwdup(pw);
|
|
||||||
if (!pwcache_put(bypwnam, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache user name, already exists");
|
|
||||||
if (!pwcache_put(byuid, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache uid, already exists");
|
|
||||||
return(pw);
|
|
||||||
} else {
|
|
||||||
pw = emalloc(sizeof(*pw));
|
|
||||||
memset(pw, 0, sizeof(*pw));
|
|
||||||
pw->pw_uid = uid;
|
|
||||||
if (!pwcache_put(byuid, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache uid, already exists");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a password entry by name and allocate space for it.
|
|
||||||
* Fills in pw_passwd from shadow file if necessary.
|
|
||||||
*/
|
|
||||||
struct passwd *
|
|
||||||
sudo_getpwnam(name)
|
|
||||||
const char *name;
|
|
||||||
{
|
|
||||||
struct passwd key, *pw;
|
|
||||||
size_t len;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
key.pw_name = (char *) name;
|
|
||||||
if ((pw = pwcache_get(bypwnam, &key)) != NULL)
|
|
||||||
return(pw);
|
|
||||||
/*
|
|
||||||
* Cache passwd db entry if it exists or a negative response if not.
|
|
||||||
*/
|
|
||||||
if ((pw = getpwnam(name)) != NULL) {
|
|
||||||
pw = sudo_pwdup(pw);
|
|
||||||
if (!pwcache_put(bypwnam, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache user name, already exists");
|
|
||||||
if (!pwcache_put(byuid, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache uid, already exists");
|
|
||||||
return(pw);
|
|
||||||
} else {
|
|
||||||
len = strlen(name) + 1;
|
|
||||||
cp = emalloc(sizeof(*pw) + len);
|
|
||||||
memset(cp, 0, sizeof(*pw));
|
|
||||||
pw = (struct passwd *) cp;
|
|
||||||
cp += sizeof(*pw);
|
|
||||||
memcpy(cp, name, len);
|
|
||||||
pw->pw_name = cp;
|
|
||||||
pw->pw_uid = (uid_t) -1;
|
|
||||||
if (!pwcache_put(bypwnam, (VOID *) pw))
|
|
||||||
errorx(1, "unable to cache user name, already exists");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sudo_setpwent()
|
sudo_setspent()
|
||||||
{
|
{
|
||||||
setpwent();
|
|
||||||
#ifdef HAVE_GETPRPWNAM
|
#ifdef HAVE_GETPRPWNAM
|
||||||
setprpwent();
|
setprpwent();
|
||||||
#endif
|
#endif
|
||||||
@@ -261,9 +182,8 @@ sudo_setpwent()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sudo_endpwent()
|
sudo_endspent()
|
||||||
{
|
{
|
||||||
endpwent();
|
|
||||||
#ifdef HAVE_GETPRPWNAM
|
#ifdef HAVE_GETPRPWNAM
|
||||||
endprpwent();
|
endprpwent();
|
||||||
#endif
|
#endif
|
||||||
@@ -280,86 +200,3 @@ sudo_endpwent()
|
|||||||
endauthent();
|
endauthent();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sudo_setgrent()
|
|
||||||
{
|
|
||||||
setgrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sudo_endgrent()
|
|
||||||
{
|
|
||||||
endgrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a group entry by gid and allocate space for it.
|
|
||||||
*/
|
|
||||||
struct group *
|
|
||||||
sudo_getgrgid(gid)
|
|
||||||
gid_t gid;
|
|
||||||
{
|
|
||||||
struct group key, *gr;
|
|
||||||
|
|
||||||
key.gr_gid = gid;
|
|
||||||
if ((gr = pwcache_get(bygid, &key)) != NULL)
|
|
||||||
return(gr);
|
|
||||||
/*
|
|
||||||
* Cache group db entry if it exists or a negative response if not.
|
|
||||||
*/
|
|
||||||
if ((gr = getgrgid(gid)) != NULL) {
|
|
||||||
gr = sudo_grdup(gr);
|
|
||||||
if (!pwcache_put(bygrnam, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache group name, already exists");
|
|
||||||
if (!pwcache_put(bygid, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache gid, already exists");
|
|
||||||
return(gr);
|
|
||||||
} else {
|
|
||||||
gr = emalloc(sizeof(*gr));
|
|
||||||
memset(gr, 0, sizeof(*gr));
|
|
||||||
gr->gr_gid = gid;
|
|
||||||
if (!pwcache_put(bygid, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache gid, already exists");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a group entry by name and allocate space for it.
|
|
||||||
*/
|
|
||||||
struct group *
|
|
||||||
sudo_getgrnam(name)
|
|
||||||
const char *name;
|
|
||||||
{
|
|
||||||
struct group key, *gr;
|
|
||||||
size_t len;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
key.gr_name = (char *) name;
|
|
||||||
if ((gr = pwcache_get(bygrnam, &key)) != NULL)
|
|
||||||
return(gr);
|
|
||||||
/*
|
|
||||||
* Cache group db entry if it exists or a negative response if not.
|
|
||||||
*/
|
|
||||||
if ((gr = getgrnam(name)) != NULL) {
|
|
||||||
gr = sudo_grdup(gr);
|
|
||||||
if (!pwcache_put(bygrnam, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache group name, already exists");
|
|
||||||
if (!pwcache_put(bygid, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache gid, already exists");
|
|
||||||
return(gr);
|
|
||||||
} else {
|
|
||||||
len = strlen(name) + 1;
|
|
||||||
cp = emalloc(sizeof(*gr) + len);
|
|
||||||
memset(cp, 0, sizeof(*gr));
|
|
||||||
gr = (struct group *) cp;
|
|
||||||
cp += sizeof(*gr);
|
|
||||||
memcpy(cp, name, len);
|
|
||||||
gr->gr_name = cp;
|
|
||||||
gr->gr_gid = (gid_t) -1;
|
|
||||||
if (!pwcache_put(bygrnam, (VOID *) gr))
|
|
||||||
errorx(1, "unable to cache group name, already exists");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
330
pwutil.c
330
pwutil.c
@@ -55,6 +55,28 @@
|
|||||||
static const char rcsid[] = "$Sudo$";
|
static const char rcsid[] = "$Sudo$";
|
||||||
#endif /* lint */
|
#endif /* lint */
|
||||||
|
|
||||||
|
#ifdef MYPW
|
||||||
|
void my_setgrfile __P((const char *));
|
||||||
|
void my_setgrent __P((void));
|
||||||
|
void my_endgrent __P((void));
|
||||||
|
struct group *my_getgrnam __P((const char *));
|
||||||
|
struct group *my_getgruid __P((gid_t));
|
||||||
|
#define setgrent() my_setgrent()
|
||||||
|
#define endgrent() my_endgrent()
|
||||||
|
#define getgrnam(n) my_getgrnam(n)
|
||||||
|
#define getgruid(g) my_getgruid(g)
|
||||||
|
|
||||||
|
void my_setpwfile __P((const char *));
|
||||||
|
void my_setpwent __P((void));
|
||||||
|
void my_endpwent __P((void));
|
||||||
|
struct passwd *my_getpwnam __P((const char *));
|
||||||
|
struct passwd *my_getpwuid __P((uid_t));
|
||||||
|
#define setpwent() my_setpwent()
|
||||||
|
#define endpwent() my_endpwent()
|
||||||
|
#define getpwnam(n) my_getpwnam(n)
|
||||||
|
#define getpwuid(u) my_getpwuid(u)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The passwd and group caches.
|
* The passwd and group caches.
|
||||||
*/
|
*/
|
||||||
@@ -66,105 +88,6 @@ static int cmp_pwnam __P((const VOID *, const VOID *));
|
|||||||
static int cmp_grgid __P((const VOID *, const VOID *));
|
static int cmp_grgid __P((const VOID *, const VOID *));
|
||||||
static int cmp_grnam __P((const VOID *, const VOID *));
|
static int cmp_grnam __P((const VOID *, const VOID *));
|
||||||
static void pw_free __P((VOID *));
|
static void pw_free __P((VOID *));
|
||||||
VOID *pwcache_get __P((enum cmptype, VOID *));
|
|
||||||
int pwcache_put __P((enum cmptype, VOID *));
|
|
||||||
|
|
||||||
void
|
|
||||||
pwcache_init()
|
|
||||||
{
|
|
||||||
pwcache_byuid = rbcreate(cmp_pwuid);
|
|
||||||
pwcache_byname = rbcreate(cmp_pwnam);
|
|
||||||
grcache_bygid = rbcreate(cmp_grgid);
|
|
||||||
grcache_byname = rbcreate(cmp_grnam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pwcache_destroy()
|
|
||||||
{
|
|
||||||
if (pwcache_byuid) {
|
|
||||||
rbdestroy(pwcache_byuid, pw_free);
|
|
||||||
pwcache_byuid = NULL;
|
|
||||||
}
|
|
||||||
if (pwcache_byname) {
|
|
||||||
rbdestroy(pwcache_byname, NULL);
|
|
||||||
pwcache_byname = NULL;
|
|
||||||
}
|
|
||||||
if (grcache_bygid) {
|
|
||||||
rbdestroy(grcache_bygid, free);
|
|
||||||
grcache_bygid = NULL;
|
|
||||||
}
|
|
||||||
if (grcache_byname) {
|
|
||||||
rbdestroy(grcache_byname, NULL);
|
|
||||||
grcache_byname = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get an entry in the passwd/group cache.
|
|
||||||
*/
|
|
||||||
VOID *
|
|
||||||
pwcache_get(how, key)
|
|
||||||
enum cmptype how;
|
|
||||||
VOID *key;
|
|
||||||
{
|
|
||||||
struct rbnode *node;
|
|
||||||
struct passwd *pw;
|
|
||||||
struct group *gr;
|
|
||||||
|
|
||||||
switch (how) {
|
|
||||||
case bypwnam:
|
|
||||||
if ((node = rbfind(pwcache_byname, key)) != NULL) {
|
|
||||||
pw = (struct passwd *) node->data;
|
|
||||||
return(pw->pw_uid != (uid_t) -1 ? pw : NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case byuid:
|
|
||||||
if ((node = rbfind(pwcache_byuid, key)) != NULL) {
|
|
||||||
pw = (struct passwd *) node->data;
|
|
||||||
return(pw->pw_name != NULL ? pw : NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case bygrnam:
|
|
||||||
if ((node = rbfind(grcache_bygid, key)) != NULL) {
|
|
||||||
gr = (struct group *) node->data;
|
|
||||||
return(gr->gr_gid != (gid_t) -1 ? gr : NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case bygid:
|
|
||||||
if ((node = rbfind(grcache_bygid, key)) != NULL) {
|
|
||||||
gr = (struct group *) node->data;
|
|
||||||
return(gr->gr_name != NULL ? gr : NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Store an entry in the passwd/group cache.
|
|
||||||
* Returns TRUE on success and FALSE if the entry already exists.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
pwcache_put(how, data)
|
|
||||||
enum cmptype how;
|
|
||||||
VOID *data;
|
|
||||||
{
|
|
||||||
switch (how) {
|
|
||||||
case bypwnam:
|
|
||||||
return(rbinsert(pwcache_byname, data) == NULL);
|
|
||||||
break;
|
|
||||||
case byuid:
|
|
||||||
return(rbinsert(pwcache_byuid, data) == NULL);
|
|
||||||
break;
|
|
||||||
case bygrnam:
|
|
||||||
return(rbinsert(grcache_byname, data) == NULL);
|
|
||||||
break;
|
|
||||||
case bygid:
|
|
||||||
return(rbinsert(grcache_bygid, data) == NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare by uid.
|
* Compare by uid.
|
||||||
@@ -196,18 +119,15 @@ cmp_pwnam(v1, v2)
|
|||||||
* 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;
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
const char *pw_passwd, *pw_shell;
|
const char *pw_shell;
|
||||||
size_t nsize, psize, csize, gsize, dsize, ssize, total;
|
size_t nsize, psize, csize, gsize, dsize, ssize, total;
|
||||||
struct passwd *newpw;
|
struct passwd *newpw;
|
||||||
|
|
||||||
/* Get shadow password if available. */
|
|
||||||
pw_passwd = sudo_getepw(pw);
|
|
||||||
|
|
||||||
/* If shell field is empty, expand to _PATH_BSHELL. */
|
/* If shell field is empty, expand to _PATH_BSHELL. */
|
||||||
pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
|
pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
|
||||||
? _PATH_BSHELL : pw->pw_shell;
|
? _PATH_BSHELL : pw->pw_shell;
|
||||||
@@ -219,8 +139,8 @@ sudo_pwdup(pw)
|
|||||||
nsize = strlen(pw->pw_name) + 1;
|
nsize = strlen(pw->pw_name) + 1;
|
||||||
total += nsize;
|
total += nsize;
|
||||||
}
|
}
|
||||||
if (pw_passwd) {
|
if (pw->pw_passwd) {
|
||||||
psize = strlen(pw_passwd) + 1;
|
psize = strlen(pw->pw_passwd) + 1;
|
||||||
total += psize;
|
total += psize;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LOGIN_CAP_H
|
#ifdef HAVE_LOGIN_CAP_H
|
||||||
@@ -257,7 +177,7 @@ sudo_pwdup(pw)
|
|||||||
cp += nsize;
|
cp += nsize;
|
||||||
}
|
}
|
||||||
if (psize) {
|
if (psize) {
|
||||||
(void)memcpy(cp, pw_passwd, psize);
|
(void)memcpy(cp, pw->pw_passwd, psize);
|
||||||
newpw->pw_passwd = cp;
|
newpw->pw_passwd = cp;
|
||||||
cp += psize;
|
cp += psize;
|
||||||
}
|
}
|
||||||
@@ -287,6 +207,87 @@ sudo_pwdup(pw)
|
|||||||
return(newpw);
|
return(newpw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a password entry by uid and allocate space for it.
|
||||||
|
* Fills in pw_passwd from shadow file if necessary.
|
||||||
|
*/
|
||||||
|
struct passwd *
|
||||||
|
sudo_getpwuid(uid)
|
||||||
|
uid_t uid;
|
||||||
|
{
|
||||||
|
struct passwd key, *pw;
|
||||||
|
struct rbnode *node;
|
||||||
|
|
||||||
|
key.pw_uid = uid;
|
||||||
|
if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
|
||||||
|
pw = (struct passwd *) node->data;
|
||||||
|
return(pw->pw_name != NULL ? pw : NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Cache passwd db entry if it exists or a negative response if not.
|
||||||
|
*/
|
||||||
|
if ((pw = getpwuid(uid)) != NULL) {
|
||||||
|
pw->pw_passwd = sudo_getepw(pw); /* get shadow password */
|
||||||
|
pw = sudo_pwdup(pw);
|
||||||
|
if (rbinsert(pwcache_byname, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache user name, already exists");
|
||||||
|
if (rbinsert(pwcache_byuid, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache uid, already exists");
|
||||||
|
return(pw);
|
||||||
|
} else {
|
||||||
|
pw = emalloc(sizeof(*pw));
|
||||||
|
memset(pw, 0, sizeof(*pw));
|
||||||
|
pw->pw_uid = uid;
|
||||||
|
if (rbinsert(pwcache_byuid, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache uid, already exists");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a password entry by name and allocate space for it.
|
||||||
|
* Fills in pw_passwd from shadow file if necessary.
|
||||||
|
*/
|
||||||
|
struct passwd *
|
||||||
|
sudo_getpwnam(name)
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
struct passwd key, *pw;
|
||||||
|
struct rbnode *node;
|
||||||
|
size_t len;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
key.pw_name = (char *) name;
|
||||||
|
if ((node = rbfind(pwcache_byname, &key)) != NULL) {
|
||||||
|
pw = (struct passwd *) node->data;
|
||||||
|
return(pw->pw_uid != (uid_t) -1 ? pw : NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Cache passwd db entry if it exists or a negative response if not.
|
||||||
|
*/
|
||||||
|
if ((pw = getpwnam(name)) != NULL) {
|
||||||
|
pw->pw_passwd = sudo_getepw(pw); /* get shadow password */
|
||||||
|
pw = sudo_pwdup(pw);
|
||||||
|
if (rbinsert(pwcache_byname, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache user name, already exists");
|
||||||
|
if (rbinsert(pwcache_byuid, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache uid, already exists");
|
||||||
|
return(pw);
|
||||||
|
} else {
|
||||||
|
len = strlen(name) + 1;
|
||||||
|
cp = emalloc(sizeof(*pw) + len);
|
||||||
|
memset(cp, 0, sizeof(*pw));
|
||||||
|
pw = (struct passwd *) cp;
|
||||||
|
cp += sizeof(*pw);
|
||||||
|
memcpy(cp, name, len);
|
||||||
|
pw->pw_name = cp;
|
||||||
|
pw->pw_uid = (uid_t) -1;
|
||||||
|
if (rbinsert(pwcache_byname, (VOID *) pw) != NULL)
|
||||||
|
errorx(1, "unable to cache user name, already exists");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Take a uid and return a faked up passwd struct.
|
* Take a uid and return a faked up passwd struct.
|
||||||
*/
|
*/
|
||||||
@@ -346,6 +347,26 @@ sudo_fakepwnam(user)
|
|||||||
return(pw);
|
return(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sudo_setpwent()
|
||||||
|
{
|
||||||
|
setpwent();
|
||||||
|
sudo_setspent();
|
||||||
|
pwcache_byuid = rbcreate(cmp_pwuid);
|
||||||
|
pwcache_byname = rbcreate(cmp_pwnam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sudo_endpwent()
|
||||||
|
{
|
||||||
|
endpwent();
|
||||||
|
sudo_endspent();
|
||||||
|
rbdestroy(pwcache_byuid, pw_free);
|
||||||
|
pwcache_byuid = NULL;
|
||||||
|
rbdestroy(pwcache_byname, NULL);
|
||||||
|
pwcache_byname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pw_free(v)
|
pw_free(v)
|
||||||
VOID *v;
|
VOID *v;
|
||||||
@@ -442,3 +463,98 @@ sudo_grdup(gr)
|
|||||||
|
|
||||||
return(newgr);
|
return(newgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a group entry by gid and allocate space for it.
|
||||||
|
*/
|
||||||
|
struct group *
|
||||||
|
sudo_getgrgid(gid)
|
||||||
|
gid_t gid;
|
||||||
|
{
|
||||||
|
struct group key, *gr;
|
||||||
|
struct rbnode *node;
|
||||||
|
|
||||||
|
key.gr_gid = gid;
|
||||||
|
if ((node = rbfind(grcache_bygid, &key)) != NULL) {
|
||||||
|
gr = (struct group *) node->data;
|
||||||
|
return(gr->gr_name != NULL ? gr : NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Cache group db entry if it exists or a negative response if not.
|
||||||
|
*/
|
||||||
|
if ((gr = getgrgid(gid)) != NULL) {
|
||||||
|
gr = sudo_grdup(gr);
|
||||||
|
if (rbinsert(grcache_byname, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache group name, already exists");
|
||||||
|
if (rbinsert(grcache_bygid, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache gid, already exists");
|
||||||
|
return(gr);
|
||||||
|
} else {
|
||||||
|
gr = emalloc(sizeof(*gr));
|
||||||
|
memset(gr, 0, sizeof(*gr));
|
||||||
|
gr->gr_gid = gid;
|
||||||
|
if (rbinsert(grcache_bygid, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache gid, already exists");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
size_t len;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
key.gr_name = (char *) name;
|
||||||
|
if ((node = rbfind(grcache_byname, &key)) != NULL) {
|
||||||
|
gr = (struct group *) node->data;
|
||||||
|
return(gr->gr_gid != (gid_t) -1 ? gr : NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Cache group db entry if it exists or a negative response if not.
|
||||||
|
*/
|
||||||
|
if ((gr = getgrnam(name)) != NULL) {
|
||||||
|
gr = sudo_grdup(gr);
|
||||||
|
if (rbinsert(grcache_byname, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache group name, already exists");
|
||||||
|
if (rbinsert(grcache_bygid, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache gid, already exists");
|
||||||
|
return(gr);
|
||||||
|
} else {
|
||||||
|
len = strlen(name) + 1;
|
||||||
|
cp = emalloc(sizeof(*gr) + len);
|
||||||
|
memset(cp, 0, sizeof(*gr));
|
||||||
|
gr = (struct group *) cp;
|
||||||
|
cp += sizeof(*gr);
|
||||||
|
memcpy(cp, name, len);
|
||||||
|
gr->gr_name = cp;
|
||||||
|
gr->gr_gid = (gid_t) -1;
|
||||||
|
if (rbinsert(grcache_byname, (VOID *) gr) != NULL)
|
||||||
|
errorx(1, "unable to cache group name, already exists");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user