]> granicus.if.org Git - sudo/commitdiff
Set usrinfo for AIX
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 15 Jun 2010 16:55:28 +0000 (12:55 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 15 Jun 2010 16:55:28 +0000 (12:55 -0400)
Set adminstrative domain for the process when looking up user's
password info and when preparing for execve().

--HG--
branch : 1.7

aix.c
configure
configure.in
pwutil.c
set_perms.c
sudo.h

diff --git a/aix.c b/aix.c
index 0d57c435432006c876a3279c00ff9477695e399f..e70abb71a4d82aaa352099a6edf2560fc56c437e 100644 (file)
--- a/aix.c
+++ b/aix.c
@@ -52,6 +52,10 @@ struct aix_limit {
     int factor;
 };
 
+#ifdef HAVE_SETAUTHDB
+static char saved_authsys[16]; /* 15 chars plus NUL as per setauthdb(3) */
+#endif
+
 static struct aix_limit aix_limits[] = {
     { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
     { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
@@ -78,7 +82,7 @@ aix_getlimit(user, lim, valp)
     return(0);
 }
 
-void
+static void
 aix_setlimits(user)
     char *user;
 {
@@ -86,6 +90,9 @@ aix_setlimits(user)
     rlim64_t val;
     int n;
 
+    if (setuserdb(S_READ) != 0)
+       error(1, "unable to open userdb");
+
     /*
      * For each resource limit, get the soft/hard values for the user
      * and set those values via setrlimit64().  Must be run as euid 0.
@@ -122,6 +129,66 @@ aix_setlimits(user)
        }
        (void)setrlimit64(aix_limits[n].resource, &rlim);
     }
+    enduserdb();
 }
 
+#ifdef HAVE_SETAUTHDB
+/*
+ * Look up administrative domain for user (SYSTEM in /etc/security/user) and
+ * set it as the default for the process.  This ensures that password and
+ * group lookups are made against the correct source (files, NIS, LDAP, etc).
+ */
+void
+aix_setauthdb(char *user)
+{
+    char *authsys;
+
+    if (user != NULL) {
+       if (setuserdb(S_READ) != 0)
+           error(1, "unable to open userdb");
+       if (getuserattr(user, S_AUTHSYSTEM, &authsys, SEC_CHAR) == 0) {
+           if (setauthdb(authsys, saved_authsys) != 0)
+               error(1, "unable to switch to authsystem \"%s\" for %s",
+                   authsys, user);
+       }
+       enduserdb();
+    }
+}
+
+/*
+ * Restore the saved administrative domain, if any.
+ */
+void
+aix_restoreauthdb()
+{
+    if (saved_authsys[0]) {
+       if (setauthdb(saved_authsys, NULL) != 0)
+           error(1, "unable to restore authsystem \"%s\", saved_authsys);
+       saved_authsys[0] = '\0';
+    }
+}
+#endif
+
+void
+aix_prep_user(user)
+    char *user;
+{
+    char *info;
+    int len;
+
+    /* set usrinfo, like login(1) does */
+    /* XXX - should NAME field be pw_gecos? */
+    len = easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
+       user, '\0', user, '\0', user, '\0', user_ttypath ? user_ttypath : "");
+    (void)usrinfo(SETUINFO, info, len);
+    efree(info);
+
+#ifdef HAVE_SETAUTHDB
+    /* set administrative domain */
+    aix_setauthdb(user);
+#endif
+
+    /* set resource limits */
+    aix_setlimits(user);
+}
 #endif /* HAVE_GETUSERATTR */
index 1afd52f972305e9ec5cb7c916a0efd2c434ef846..8d827f3b808098d19862c8895dc9f74608089ac3 100755 (executable)
--- a/configure
+++ b/configure
                fi
 
                # AIX-specific functions
-               for ac_func in getuserattr
+               for ac_func in getuserattr setauthdb
 do :
-  ac_fn_c_check_func "$LINENO" "getuserattr" "ac_cv_func_getuserattr"
-if test "x$ac_cv_func_getuserattr" = x""yes; then :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_GETUSERATTR 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
 fi
index 2bdd2489df92fb8af697c142d4c0dc427e24c4f7..5250b1236b671ae791d63d3b35c8c553f40d294e 100644 (file)
@@ -1438,7 +1438,7 @@ case "$host" in
                fi
 
                # AIX-specific functions
-               AC_CHECK_FUNCS(getuserattr)
+               AC_CHECK_FUNCS(getuserattr setauthdb)
                SUDO_OBJS="$SUDO_OBJS aix.o"
                ;;
     *-*-hiuxmpp*)
index 46c45d01df48d17b598a94eada0436e3857cd76e..2895e70cda1d81f3198f633d5f54d6510063f4d1 100644 (file)
--- a/pwutil.c
+++ b/pwutil.c
@@ -172,11 +172,14 @@ sudo_getpwuid(uid)
     key.pw_uid = uid;
     if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
        pw = (struct passwd *) node->data;
-       return(pw->pw_name != NULL ? pw : NULL);
+       goto done;
     }
     /*
      * Cache passwd db entry if it exists or a negative response if not.
      */
+#ifdef HAVE_SETAUTHDB
+    aix_setauthdb(IDtouser(uid));
+#endif
     if ((pw = getpwuid(uid)) != NULL) {
        pw = sudo_pwdup(pw);
        cp = sudo_getepw(pw);           /* get shadow password */
@@ -186,15 +189,18 @@ sudo_getpwuid(uid)
        if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
            errorx(1, "unable to cache uid %lu (%s), already exists",
                uid, pw->pw_name);
-       return(pw);
     } else {
        pw = emalloc(sizeof(*pw));
        zero_bytes(pw, sizeof(*pw));
        pw->pw_uid = uid;
        if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
            errorx(1, "unable to cache uid %lu, already exists", uid);
-       return(NULL);
     }
+#ifdef HAVE_SETAUTHDB
+    aix_restoreauthdb();
+#endif
+done:
+    return(pw->pw_name != NULL ? pw : NULL);
 }
 
 /*
@@ -213,11 +219,14 @@ sudo_getpwnam(name)
     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);
+       goto done;
     }
     /*
      * Cache passwd db entry if it exists or a negative response if not.
      */
+#ifdef HAVE_SETAUTHDB
+    aix_setauthdb(user);
+#endif
     if ((pw = getpwnam(name)) != NULL) {
        pw = sudo_pwdup(pw);
        cp = sudo_getepw(pw);           /* get shadow password */
@@ -226,7 +235,6 @@ sudo_getpwnam(name)
        pw->pw_passwd = cp;
        if (rbinsert(pwcache_byname, (void *) pw) != NULL)
            errorx(1, "unable to cache user %s, already exists", name);
-       return(pw);
     } else {
        len = strlen(name) + 1;
        cp = emalloc(sizeof(*pw) + len);
@@ -238,8 +246,12 @@ sudo_getpwnam(name)
        pw->pw_uid = (uid_t) -1;
        if (rbinsert(pwcache_byname, (void *) pw) != NULL)
            errorx(1, "unable to cache user %s, already exists", name);
-       return(NULL);
     }
+#ifdef HAVE_SETAUTHDB
+    aix_restoreauthdb();
+#endif
+done:
+    return(pw->pw_uid != (uid_t) -1 ? pw : NULL);
 }
 
 /*
@@ -451,7 +463,7 @@ sudo_getgrgid(gid)
     key.gr_gid = gid;
     if ((node = rbfind(grcache_bygid, &key)) != NULL) {
        gr = (struct group *) node->data;
-       return(gr->gr_name != NULL ? gr : NULL);
+       goto done;
     }
     /*
      * Cache group db entry if it exists or a negative response if not.
@@ -461,15 +473,15 @@ sudo_getgrgid(gid)
        if (rbinsert(grcache_bygid, (void *) gr) != NULL)
            errorx(1, "unable to cache gid %lu (%s), already exists",
                gid, gr->gr_name);
-       return(gr);
     } else {
        gr = emalloc(sizeof(*gr));
        zero_bytes(gr, sizeof(*gr));
        gr->gr_gid = gid;
        if (rbinsert(grcache_bygid, (void *) gr) != NULL)
            errorx(1, "unable to cache gid %lu, already exists, gid");
-       return(NULL);
     }
+done:
+    return(gr->gr_name != NULL ? gr : NULL);
 }
 
 /*
@@ -487,7 +499,7 @@ sudo_getgrnam(name)
     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);
+       goto done;
     }
     /*
      * Cache group db entry if it exists or a negative response if not.
@@ -496,7 +508,6 @@ sudo_getgrnam(name)
        gr = sudo_grdup(gr);
        if (rbinsert(grcache_byname, (void *) gr) != NULL)
            errorx(1, "unable to cache group %s, already exists", name);
-       return(gr);
     } else {
        len = strlen(name) + 1;
        cp = emalloc(sizeof(*gr) + len);
@@ -508,8 +519,9 @@ sudo_getgrnam(name)
        gr->gr_gid = (gid_t) -1;
        if (rbinsert(grcache_byname, (void *) gr) != NULL)
            errorx(1, "unable to cache group %s, already exists", name);
-       return(NULL);
     }
+done:
+    return(gr->gr_gid != (gid_t) -1 ? gr : NULL);
 }
 
 void
@@ -560,7 +572,14 @@ user_in_group(pw, group)
 #endif
     struct group *grp;
 
-    if ((grp = sudo_getgrnam(group)) == NULL)
+#ifdef HAVE_SETAUTHDB
+    aix_setauthdb(pw->pw_user);
+#endif
+    grp = sudo_getgrnam(group);
+#ifdef HAVE_SETAUTHDB
+    aix_restoreauthdb();
+#endif
+    if (grp == NULL)
        return(FALSE);
 
     /* check against user's primary (passwd file) gid */
index b867af5b069807b132724746969b872b4ed809e0..a8d6301e6f830ec9b7d9e7cb4878ece61ca67b76 100644 (file)
@@ -554,7 +554,7 @@ runas_setup(dowait)
     if (runas_pw->pw_name != NULL) {
        gid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
 #ifdef HAVE_GETUSERATTR
-       aix_setlimits(runas_pw->pw_name);
+       aix_prep_user(runas_pw->pw_name);
 #endif
 #ifdef HAVE_PAM
        pam_begin_session(runas_pw);
diff --git a/sudo.h b/sudo.h
index 52b1e21825289f82e9960a6eed1f6be7dbd0e0df..5915e03f782af1cd5fbc0892c75ea5473d81c10b 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -211,7 +211,7 @@ struct passwd;
 struct stat;
 
 /* aix.c */
-void aix_setlimits __P((char *));
+void aix_prep_user __P((char *));
 
 /* boottime.c */
 int get_boottime __P((struct timeval *));