Imported Upstream version 1.7.6p1
[debian/sudo] / set_perms.c
index 4417330f976ad8b833350048a417ca6428413fb4..355baad555b4483fa7ddc2df55b0bf7d54cc1db4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994-1996,1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1994-1996,1998-2010 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
 #endif /* STDC_HEADERS */
 #ifdef HAVE_STRING_H
 # include <string.h>
-#else
-# ifdef HAVE_STRINGS_H
-#  include <strings.h>
-# endif
 #endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
 #ifdef HAVE_LOGIN_CAP_H
 # include <login_cap.h>
 #endif
+#ifdef HAVE_PROJECT_H
+# include <project.h>
+# include <sys/task.h>
+#endif
 
 #include "sudo.h"
 
-#ifndef lint
-__unused static const char rcsid[] = "$Sudo: set_perms.c,v 1.49 2009/06/25 12:44:33 millert Exp $";
-#endif /* lint */
-
 #ifdef __TANDEM
 # define ROOT_UID      65535
 #else
@@ -88,7 +87,7 @@ set_perms(perm)
     CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return(1);
+       return 1;
 
     switch (perm) {
        case PERM_ROOT:
@@ -173,12 +172,12 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return(1);
+    return 1;
 bad:
     warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
     if (noexit)
-       return(0);
+       return 0;
     exit(1);
 }
 
@@ -202,7 +201,7 @@ set_perms(perm)
     CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return(1);
+       return 1;
 
     switch (perm) {
        case PERM_ROOT:
@@ -290,12 +289,12 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return(1);
+    return 1;
 bad:
     warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
     if (noexit)
-       return(0);
+       return 0;
     exit(1);
 }
 
@@ -317,7 +316,7 @@ set_perms(perm)
     CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return(1);
+       return 1;
 
     /*
      * Since we only have setuid() and seteuid() and semantics
@@ -409,12 +408,12 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return(1);
+    return 1;
 bad:
     warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
     if (noexit)
-       return(0);
+       return 0;
     exit(1);
 }
 
@@ -436,7 +435,7 @@ set_perms(perm)
     CLR(perm, PERM_MASK);
 
     if (perm == current_perm)
-       return(1);
+       return 1;
 
     switch (perm) {
        case PERM_ROOT:
@@ -473,12 +472,12 @@ set_perms(perm)
     }
 
     current_perm = perm;
-    return(1);
+    return 1;
 bad:
     warningx("%s: %s", errstr,
        errno == EAGAIN ? "too many processes" : strerror(errno));
     if (noexit)
-       return(0);
+       return 0;
     exit(1);
 }
 #  endif /* HAVE_SETEUID */
@@ -490,10 +489,11 @@ static void
 runas_setgroups()
 {
     static int ngroups = -1;
-#ifdef HAVE_GETGROUPS
+# ifdef HAVE_GETGROUPS
     static GETGROUPS_T *groups;
-#endif
-    struct passwd *pw;
+# endif
+    static struct passwd *pw;
+    struct passwd *opw = pw;
 
     if (def_preserve_groups)
        return;
@@ -501,27 +501,37 @@ runas_setgroups()
     /*
      * Use stashed copy of runas groups if available, else initgroups and stash.
      */
-    if (ngroups == -1) {
-       pw = runas_pw ? runas_pw : sudo_user.pw;
+    pw = runas_pw ? runas_pw : sudo_user.pw;
+    if (pw != opw) {
+# ifdef HAVE_SETAUTHDB
+       aix_setauthdb(pw->pw_name);
+# endif
        if (initgroups(pw->pw_name, pw->pw_gid) < 0)
            log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
-#ifdef HAVE_GETGROUPS
+# ifdef HAVE_GETGROUPS
+       if (groups) {
+           efree(groups);
+           groups = NULL;
+       }
        if ((ngroups = getgroups(0, NULL)) > 0) {
            groups = emalloc2(ngroups, sizeof(GETGROUPS_T));
            if (getgroups(ngroups, groups) < 0)
                log_error(USE_ERRNO|MSG_ONLY, "can't get runas group vector");
        }
+#  ifdef HAVE_SETAUTHDB
+       aix_restoreauthdb();
+#  endif
     } else {
        if (setgroups(ngroups, groups) < 0)
            log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
-#endif /* HAVE_GETGROUPS */
+# endif /* HAVE_GETGROUPS */
     }
 }
 
 static void
 restore_groups()
 {
-    if (setgroups(user_ngroups, user_groups) < 0)
+    if (user_ngroups >= 0 && setgroups(user_ngroups, user_groups) < 0)
        log_error(USE_ERRNO|MSG_ONLY, "can't reset user group vector");
 }
 
@@ -541,6 +551,69 @@ restore_groups()
 
 #endif /* HAVE_INITGROUPS */
 
+#ifdef HAVE_PROJECT_H
+static void
+set_project(pw)
+    struct passwd *pw;
+{
+    struct project proj;
+    char buf[PROJECT_BUFSZ];
+    int errval;
+
+    /*
+     * Collect the default project for the user and settaskid
+     */
+    setprojent();
+    if (getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf)) != NULL) {
+       errval = setproject(proj.pj_name, pw->pw_name, TASK_NORMAL);
+       switch(errval) {
+       case 0:
+           break;
+       case SETPROJ_ERR_TASK:
+           switch (errno) {
+           case EAGAIN:
+               warningx("resource control limit has been reached");
+               break;
+           case ESRCH:
+               warningx("user \"%s\" is not a member of project \"%s\"",
+                   pw->pw_name, proj.pj_name);
+               break;
+           case EACCES:
+               warningx("the invoking task is final");
+               break;
+           default:
+               warningx("could not join project \"%s\"", proj.pj_name);
+           }
+       case SETPROJ_ERR_POOL:
+           switch (errno) {
+           case EACCES:
+               warningx("no resource pool accepting default bindings "
+                   "exists for project \"%s\"", proj.pj_name);
+               break;
+           case ESRCH:
+               warningx("specified resource pool does not exist for "
+                   "project \"%s\"", proj.pj_name);
+               break;
+           default:
+               warningx("could not bind to default resource pool for "
+                   "project \"%s\"", proj.pj_name);
+           }
+           break;
+       default:
+           if (errval <= 0) {
+               warningx("setproject failed for project \"%s\"", proj.pj_name);
+           } else {
+               warningx("warning, resource control assignment failed for "
+                   "project \"%s\"", proj.pj_name);
+           }
+       }
+    } else {
+       warning("getdefaultproj");
+    }
+    endprojent();
+}
+#endif /* HAVE_PROJECT_H */
+
 static void
 runas_setup()
 {
@@ -552,11 +625,14 @@ runas_setup()
 
     if (runas_pw->pw_name != NULL) {
        gid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
+#ifdef HAVE_PROJECT_H
+       set_project(runas_pw);
+#endif
 #ifdef HAVE_GETUSERATTR
-       aix_setlimits(runas_pw->pw_name);
+       aix_prep_user(runas_pw->pw_name, user_ttypath);
 #endif
 #ifdef HAVE_PAM
-       pam_prep_user(runas_pw);
+       pam_begin_session(runas_pw);
 #endif /* HAVE_PAM */
 
 #ifdef HAVE_LOGIN_CAP_H