]> granicus.if.org Git - sudo/commitdiff
Add Solaris 10 "project" support. From Michael Brantley.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 19 Jun 2007 22:24:51 +0000 (22:24 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 19 Jun 2007 22:24:51 +0000 (22:24 +0000)
config.h.in
configure.in
sudo.c

index 4179f5ebb6adbe2a97bfd8f7f7a06c7180f491b4..27a41a176123910902cba8118247aec7ba4c5d02 100644 (file)
 /* Define to 1 if you have the <paths.h> header file. */
 #undef HAVE_PATHS_H
 
+/* Define to 1 if you have the <project.h> header file. */
+#undef HAVE_PROJECT_H
+
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
index 61c881cfd4af4c3c896b8db4c6ad9937807df65c..c67e8e696487e7d13343b4e8194fb38fb822ac02 100644 (file)
@@ -396,6 +396,14 @@ AC_ARG_WITH(systrace, [  --with-systrace[[=DIR]]   enable systrace(4) support],
     *)         ;;
 esac])
 
+AC_ARG_WITH(project, [  --with-project          enable Solaris project support],
+[case $with_project in
+    yes|no)    ;;
+    no)        ;;
+    *)         AC_MSG_ERROR(["--with-project does not take an argument."])
+               ;;
+esac])
+
 AC_MSG_CHECKING(whether to lecture users the first time they run sudo)
 AC_ARG_WITH(lecture, [  --without-lecture       don't print lecture for first-time sudoer],
 [case $with_lecture in
@@ -1627,6 +1635,10 @@ if test "$with_bsdauth" = "yes"; then
     AC_CHECK_HEADER(bsd_auth.h, AC_DEFINE(HAVE_BSD_AUTH_H)
        [SUDO_ADD_AUTH([BSD authentication], [bsdauth.o], [true])], -)
 fi
+if test ${with_project-'no'} != "no"; then
+    AC_CHECK_HEADER(project.h, AC_DEFINE(HAVE_PROJECT_H)
+       [SUDO_LIBS="${SUDO_LIBS} -lproject"], -)
+fi
 dnl
 dnl typedef checks
 dnl
diff --git a/sudo.c b/sudo.c
index 37989650f3272b00debd9c59d0ff5fde4a7b8185..35a4c558b53e92c28693682318a217e0b93f8b21 100644 (file)
--- a/sudo.c
+++ b/sudo.c
 #  define LOGIN_DEFROOTCLASS   "daemon"
 # endif
 #endif
+#ifdef HAVE_PROJECT_H
+# include <project.h>
+# include <sys/task.h>
+#endif
 
 #include "sudo.h"
 #include "interfaces.h"
@@ -104,6 +108,7 @@ static int set_cmnd                 __P((int));
 static int parse_args                  __P((int, char **));
 static void initial_setup              __P((void));
 static void set_loginclass             __P((struct passwd *));
+static void set_project                        __P((struct passwd *));
 static void usage                      __P((int))
                                            __attribute__((__noreturn__));
 static void usage_excl                 __P((int))
@@ -658,6 +663,9 @@ set_cmnd(sudo_mode)
 {
     int rval;
 
+    /* Set project if applicable. */
+    set_project(runas_pw);
+
     /* Resolve the path and return. */
     rval = FOUND;
     user_stat = emalloc(sizeof(struct stat));
@@ -1082,6 +1090,72 @@ set_loginclass(pw)
 }
 #endif /* HAVE_LOGIN_CAP_H */
 
+#ifdef HAVE_PROJECT_H
+static void
+set_project(pw)
+    struct passwd *pw;
+{
+    int errflags = NO_MAIL|MSG_ONLY|NO_EXIT;
+    int errval;
+    struct project proj;
+    struct project *resultp = '\0';
+    char buf[1024];
+
+    /*
+     * Collect the default project for the user and settaskid
+     */
+    setprojent();
+    if (resultp = getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf))) {
+       errval = setproject(resultp->pj_name, pw->pw_name, TASK_NORMAL);
+       if (errval != 0) {
+           switch(errval) {
+           case SETPROJ_ERR_TASK:
+               if (errno == EAGAIN)
+                   log_error(errflags, "resource control limit has been reached");
+               else if (errno == ESRCH)
+                   log_error(errflags, "user \"%s\" is not a member of "
+                       "project \"%s\"", pw->pw_name, resultp->pj_name);
+               else if (errno == EACCES)
+                   log_error(errflags, "the invoking task is final");
+               else
+                   log_error(errflags, "could not join project \"%s\"",
+                       resultp->pj_name);
+               break;
+           case SETPROJ_ERR_POOL:
+               if (errno == EACCES)
+                   log_error(errflags, "no resource pool accepting "
+                           "default bindings exists for project \"%s\"",
+                           resultp->pj_name);
+               else if (errno == ESRCH)
+                   log_error(errflags, "specified resource pool does "
+                           "not exist for project \"%s\"", resultp->pj_name);
+               else
+                   log_error(errflags, "could not bind to default "
+                           "resource pool for project \"%s\"", resultp->pj_name);
+               break;
+           default:
+               if (error <= 0) {
+                   log_error(errflags, "setproject failed for project \"%s\"",
+                       resultp->pj_name);
+               } else {
+                   log_error(errflags, "warning, resource control assignment "
+                       "failed for project \"%s\"", resultp->pj_name);
+               }
+           }
+       }
+    } else {
+       log_error(errflags, "getdefaultproj() error: %s", strerror(errno));
+    }
+    endprojent();
+}
+#else
+static void
+set_project(pw)
+    struct passwd *pw;
+{
+}
+#endif /* HAVE_PROJECT_H */
+
 /*
  * Look up the fully qualified domain name and set user_host and user_shost.
  */