]> granicus.if.org Git - sudo/commitdiff
Move all but the shadow stuff from getspwuid.c to pwutil.c and pwcache_get
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 5 Jan 2005 19:41:31 +0000 (19:41 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 5 Jan 2005 19:41:31 +0000 (19:41 +0000)
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).

getspwuid.c
pwutil.c

index 9c4fb5544a5903ee9ded9f77ee27d21726aa6144..8002e7bdc7db5e0bfde470ae0f08e98e2e8ac464 100644 (file)
@@ -75,17 +75,12 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 /*
- * Global variables (yuck)
+ * Exported for auth/secureware.c
  */
 #if defined(HAVE_GETPRPWNAM) && defined(__alpha)
 int crypt_type = INT_MAX;
 #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.
  * If shadow passwords are in use, look in the shadow file.
@@ -166,83 +161,9 @@ sudo_getepw(pw)
     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
-sudo_setpwent()
+sudo_setspent()
 {
-    setpwent();
 #ifdef HAVE_GETPRPWNAM
     setprpwent();
 #endif
@@ -261,9 +182,8 @@ sudo_setpwent()
 }
 
 void
-sudo_endpwent()
+sudo_endspent()
 {
-    endpwent();
 #ifdef HAVE_GETPRPWNAM
     endprpwent();
 #endif
@@ -280,86 +200,3 @@ sudo_endpwent()
     endauthent();
 #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);
-    }
-}
index e6fdacd413d5c48736bfa33a2627316d9371bce1..9f62b8f1c51bf8addce7352edc764b896fe072b5 100644 (file)
--- a/pwutil.c
+++ b/pwutil.c
 static const char rcsid[] = "$Sudo$";
 #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.
  */
 static struct rbtree *pwcache_byuid, *pwcache_byname;
 static struct rbtree *grcache_bygid, *grcache_byname;
 
-static int  cmp_pwuid          __P((const VOID *, const VOID *));
-static int  cmp_pwnam          __P((const VOID *, const VOID *));
-static int  cmp_grgid          __P((const VOID *, const VOID *));
-static int  cmp_grnam          __P((const VOID *, const 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);
-}
+static int  cmp_pwuid  __P((const VOID *, const VOID *));
+static int  cmp_pwnam  __P((const VOID *, const VOID *));
+static int  cmp_grgid  __P((const VOID *, const VOID *));
+static int  cmp_grnam  __P((const VOID *, const VOID *));
+static void pw_free    __P((VOID *));
 
 /*
  * Compare by uid.
@@ -196,18 +119,15 @@ cmp_pwnam(v1, v2)
  * 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;
 {
     char *cp;
-    const char *pw_passwd, *pw_shell;
+    const char *pw_shell;
     size_t nsize, psize, csize, gsize, dsize, ssize, total;
     struct passwd *newpw;
 
-    /* Get shadow password if available. */
-    pw_passwd = sudo_getepw(pw);
-
     /* If shell field is empty, expand to _PATH_BSHELL. */
     pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
        ? _PATH_BSHELL : pw->pw_shell;
@@ -219,8 +139,8 @@ sudo_pwdup(pw)
            nsize = strlen(pw->pw_name) + 1;
            total += nsize;
     }
-    if (pw_passwd) {
-           psize = strlen(pw_passwd) + 1;
+    if (pw->pw_passwd) {
+           psize = strlen(pw->pw_passwd) + 1;
            total += psize;
     }
 #ifdef HAVE_LOGIN_CAP_H
@@ -257,7 +177,7 @@ sudo_pwdup(pw)
            cp += nsize;
     }
     if (psize) {
-           (void)memcpy(cp, pw_passwd, psize);
+           (void)memcpy(cp, pw->pw_passwd, psize);
            newpw->pw_passwd = cp;
            cp += psize;
     }
@@ -287,6 +207,87 @@ sudo_pwdup(pw)
     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.
  */
@@ -346,6 +347,26 @@ sudo_fakepwnam(user)
     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
 pw_free(v)
     VOID *v;
@@ -442,3 +463,98 @@ sudo_grdup(gr)
 
     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;
+}