Imported Upstream version 1.6.9p14 upstream/1.6.9p14
authorBdale Garbee <bdale@gag.com>
Wed, 14 May 2008 18:04:25 +0000 (12:04 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 14 May 2008 18:04:25 +0000 (12:04 -0600)
35 files changed:
CHANGES
INSTALL
Makefile.in
auth/kerb5.c
auth/pam.c
config.h.in
configure
configure.in
def_data.c
def_data.h
def_data.in
ldap.c
lex.yy.c
parse.c
parse.h
parse.lex
parse.yacc
pathnames.h.in
selinux.c [new file with mode: 0644]
sesh.c [new file with mode: 0644]
sudo.c
sudo.cat
sudo.h
sudo.man.in
sudo.pod
sudo.tab.c
sudo.tab.h
sudoers.cat
sudoers.man.in
sudoers.pod
testsudoers.c
version.h
visudo.cat
visudo.man.in
visudo.pod

diff --git a/CHANGES b/CHANGES
index fcb8d5596b7662665b11379987e402eec3555c46..6e11ab9d64059f5bac08edd1d41d467fa73f6ece 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2045,3 +2045,31 @@ Sudo 1.6.9p11 released.
      to the screen if there was a read timeout.
 
 Sudo 1.6.9p12 released.
+
+646) Sudo will now set the nproc resource limit to unlimited on Linux
+     systems to work around Linux's setuid() resource limit semantics.
+     On PAM systems the resource limits will be reset by pam_limits.so
+     before the command is executed.
+
+647) SELinux support that can be used to implement role based access
+     control (RBAC).  A role and (optional) type may be specified
+     in sudoers or on the command line.  These are then used in the
+     security context that the command is run as.
+
+648) Fixed a Kerberos 5 compilation problem with MIT Kerberos.
+
+Sudo 1.6.9p13 released.
+
+649) Fixed an invalid assumption in the PAM conversation function
+     introduced in version 1.6.9p9.  The conversation function may
+     be called for non-password reading purposes as well.
+
+650) Fixed freeing an uninitialized pointer in -l mode, introduced in
+     version 1.6.9p13.
+
+651) Check /etc/sudoers after LDAP even if the user was found in LDAP.
+     This allows Defaults options in /etc/sudoers to take effect.
+
+652) Add missing checks for enforcing mode in SELinux RBAC mode.
+
+Sudo 1.6.9p14 released.
diff --git a/INSTALL b/INSTALL
index b03d9e8ef39ca35306a5c0350af3b6908fa008b2..1692887912e1b9deaba49606cedf0ef10fa6f4df 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -320,6 +320,10 @@ Special features/options:
        physically live in ${prefix}/etc and /etc/sudoers will be
        a symbolic link.
 
+  --with-selinux 
+       Enable support for role based access control (RBAC) on
+       systems that support SELinux.
+
 The following options are also configurable at runtime:
 
   --with-long-otp-prompt
index 1ed0b8b4931b7ae8bd5d81531c7f342428854090..badea3729e133135373e7d37dd90380acef97e5c 100644 (file)
@@ -20,7 +20,7 @@
 #
 # @configure_input@
 #
-# $Sudo: Makefile.in,v 1.246.2.23 2008/01/14 12:22:57 millert Exp $
+# $Sudo: Makefile.in,v 1.246.2.28 2008/03/05 12:41:08 millert Exp $
 #
 
 #### Start of system configuration section. ####
@@ -63,6 +63,7 @@ sbindir = @sbindir@
 sysconfdir = @sysconfdir@
 mandir = @mandir@
 noexecdir = @NOEXECDIR@
+libexecdir = @libexecdir@
 datarootdir = @datarootdir@
 
 # Directory in which to install sudo.
@@ -105,7 +106,7 @@ SRCS = alloc.c alloca.c check.c closefrom.c def_data.c defaults.c env.c err.c \
        logging.c memrchr.c mkstemp.c parse.c parse.lex parse.yacc set_perms.c \
        sigaction.c snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c \
        sudo.c sudo_noexec.c sudo.tab.c sudo_edit.c testsudoers.c tgetpass.c \
-       utimes.c visudo.c zero_bytes.c $(AUTH_SRCS)
+       utimes.c visudo.c zero_bytes.c selinux.c sesh.c $(AUTH_SRCS)
 
 AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
            auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
@@ -131,7 +132,7 @@ TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS)
 
 LIBOBJS = @LIBOBJS@ @ALLOCA@
 
-VERSION = 1.6.9p12
+VERSION = 1.6.9p14
 
 DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES HISTORY INSTALL INSTALL.configure \
             LICENSE Makefile.in PORTING README README.LDAP \
@@ -233,6 +234,7 @@ glob.o: glob.c config.h compat.h emul/glob.h
 lsearch.o: lsearch.c config.h compat.h emul/search.h
 memrchr.o: memrchr.c config.h compat.h
 mkstemp.o: mkstemp.c config.h compat.h
+selinux.o: selinux.c $(SUDODEP)
 snprintf.o: snprintf.c config.h compat.h
 strcasecmp.o: strcasecmp.c config.h
 strlcat.o: strlcat.c config.h
@@ -276,7 +278,7 @@ sia.o: $(authdir)/sia.c $(AUTHDEP)
 
 sudo.man.in: $(srcdir)/sudo.pod
        @rm -f $(srcdir)/$@
-       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e 1d -e '/^=pod/q' -e 's/^/.\\" /p' sudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" | perl -p sudo.man.pl >> $@ )
 
 sudo.man: sudo.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
@@ -285,7 +287,7 @@ sudo.cat: sudo.man
 
 visudo.man.in: $(srcdir)/visudo.pod
        @rm -f $(srcdir)/$@
-       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e 1d -e '/^=pod/q' -e 's/^/.\\" /p' visudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' visudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
 
 visudo.man: visudo.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
@@ -294,7 +296,7 @@ visudo.cat: visudo.man
 
 sudoers.man.in: $(srcdir)/sudoers.pod
        @rm -f $(srcdir)/$@
-       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e 1d -e '/^=pod/q' -e 's/^/.\\" /p' sudoers.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ )
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudoers.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudoers.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" | perl -p sudoers.man.pl >> $@ )
 
 sudoers.man:: sudoers.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status
@@ -313,8 +315,8 @@ install-binaries: $(PROGS)
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 4111 -s sudo $(DESTDIR)$(sudodir)/sudo
        rm -f $(DESTDIR)$(sudodir)/sudoedit
        ln $(DESTDIR)$(sudodir)/sudo $(DESTDIR)$(sudodir)/sudoedit
-
        $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s visudo $(DESTDIR)$(visudodir)/visudo
+@SELINUX@      $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s sesh $(DESTDIR)$(libexecdir)/sesh
 
 install-noexec: sudo_noexec.la
        $(LIBTOOL) --mode=install $(INSTALL) sudo_noexec.la $(DESTDIR)$(noexecdir)
index 763ce851b0ddf7f2b11991cf92ae1c1ee2c2ed09..89d43a7dd85af4b6b408553d0ca497aee7c547f7 100644 (file)
@@ -54,7 +54,7 @@
 #include "sudo_auth.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: kerb5.c,v 1.23.2.7 2008/01/13 14:54:40 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: kerb5.c,v 1.23.2.8 2008/02/13 22:17:41 millert Exp $";
 #endif /* lint */
 
 #ifdef HAVE_HEIMDAL
@@ -185,8 +185,10 @@ kerb5_verify(pw, pass, auth)
                  error_message(error));
        goto done;
     }
+#ifdef HAVE_HEIMDAL
     krb5_get_init_creds_opt_set_default_flags(sudo_context, NULL,
        krb5_principal_get_realm(sudo_context, princ), opts);
+#endif
 
     /* Note that we always obtain a new TGT to verify the user */
     if ((error = krb5_get_init_creds_password(sudo_context, &credbuf, princ,
@@ -217,8 +219,13 @@ kerb5_verify(pw, pass, auth)
     }
 
 done:
-    if (opts)
+    if (opts) {
+#ifdef HAVE_HEIMDAL
        krb5_get_init_creds_opt_free(opts);
+#else
+       krb5_get_init_creds_opt_free(sudo_context, opts);
+#endif
+    }
     if (creds)
        krb5_free_cred_contents(sudo_context, creds);
     return (error ? AUTH_FAILURE : AUTH_SUCCESS);
index f6024785bd8c78e870881af87fa57a925312168b..b2fe41a745671b84cf46f6500569c52c0d263904 100644 (file)
@@ -72,7 +72,7 @@
 #endif
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: pam.c,v 1.43.2.9 2007/12/02 17:13:52 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: pam.c,v 1.43.2.10 2008/02/22 20:19:45 millert Exp $";
 #endif /* lint */
 
 static int sudo_conv __P((int, PAM_CONST struct pam_message **,
@@ -257,11 +257,6 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
        return(PAM_CONV_ERR);
     zero_bytes(*response, num_msg * sizeof(struct pam_response));
 
-    /* Is the sudo prompt standard? (If so, we'l just use PAM's) */
-    std_prompt =  strncmp(def_prompt, "Password:", 9) == 0 &&
-       (def_prompt[9] == '\0' ||
-       (def_prompt[9] == ' ' && def_prompt[10] == '\0'));
-
     for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
        flags = tgetpass_flags;
        switch (pm->msg_style) {
@@ -269,6 +264,12 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
                SET(flags, TGP_ECHO);
            case PAM_PROMPT_ECHO_OFF:
                prompt = def_prompt;
+
+               /* Is the sudo prompt standard? (If so, we'l just use PAM's) */
+               std_prompt = strncmp(def_prompt, "Password:", 9) == 0 &&
+                   (def_prompt[9] == '\0' ||
+                   (def_prompt[9] == ' ' && def_prompt[10] == '\0'));
+
                /* Only override PAM prompt if it matches /^Password: ?/ */
 #if defined(PAM_TEXT_DOMAIN) && defined(HAVE_DGETTEXT)
                if (!def_passprompt_override && (std_prompt ||
index 2ce67d7af9d34abfe8c991a4870d60badcf76f3c..ab33f134111ea3ebb7c293c02dbda0f1a5645f03 100644 (file)
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
+/* Define to 1 to enable SELinux RBAC support. */
+#undef HAVE_SELINUX
+
 /* Define to 1 if you have the `seteuid' function. */
 #undef HAVE_SETEUID
 
index fd21e6379243603335dd67472e84e56ae9da7594..047edea53a78d9cb0db2764bc23210594a7e6180 100755 (executable)
--- a/configure
+++ b/configure
@@ -818,6 +818,10 @@ SUDOERS_MODE
 SUDOERS_UID
 SUDOERS_GID
 DEV
+SELINUX
+BAMAN
+LCMAN
+SEMAN
 mansectsu
 mansectform
 mansrcdir
@@ -1567,6 +1571,7 @@ Optional Packages:
   --with-secure-path      override the user's path with a built-in one
   --without-interfaces    don't try to read the ip addr of ether interfaces
   --with-stow             properly handle GNU stow packaging
+  --with-selinux          enable SELinux support
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
@@ -2068,6 +2073,10 @@ echo "$as_me: Configuring Sudo version 1.6.9" >&6;}
 
 
 
+
+
+
+
 
 
 
@@ -2106,6 +2115,10 @@ PROGS="sudo visudo"
 : ${SUDOERS_UID='0'}
 : ${SUDOERS_GID='0'}
 DEV="#"
+SELINUX="#"
+BAMAN='.\" '
+LCMAN='.\" '
+SEMAN='.\" '
 AUTH_OBJS=
 AUTH_REG=
 AUTH_EXCL=
@@ -2118,7 +2131,11 @@ shadow_funcs=
 shadow_libs=
 shadow_libs_optional=
 
-test "$mandir" = '${prefix}/man' && mandir='$(prefix)/man'
+if test X"$prefix" = X"NONE"; then
+    test "$mandir" = '${datarootdir}/man' && mandir='$(prefix)/man'
+else
+    test "$mandir" = '${datarootdir}/man' && mandir='$(datarootdir)/man'
+fi
 test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
 test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
 test "$sysconfdir" = '${prefix}/etc' -a X"$with_stow" != X"yes" && sysconfdir='/etc'
@@ -3922,6 +3939,29 @@ echo "${ECHO_T}no" >&6; }
 fi
 
 
+
+# Check whether --with-selinux was given.
+if test "${with_selinux+set}" = set; then
+  withval=$with_selinux; case $with_selinux in
+    yes)       cat >>confdefs.h <<\_ACEOF
+#define HAVE_SELINUX 1
+_ACEOF
+
+               SUDO_LIBS="${SUDO_LIBS} -lselinux"
+               SUDO_OBJS="${SUDO_OBJS} selinux.o"
+               PROGS="${PROGS} sesh"
+               SELINUX=""
+               SEMAN=""
+               ;;
+    no)                ;;
+    *)         { { echo "$as_me:$LINENO: error: \"--with-selinux does not take an argument.\"" >&5
+echo "$as_me: error: \"--with-selinux does not take an argument.\"" >&2;}
+   { (exit 1); exit 1; }; }
+               ;;
+esac
+fi
+
+
 # Extract the first word of "egrep", so it can be a program name with args.
 set dummy egrep; ac_word=$2
 { echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -6085,7 +6125,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6088 "configure"' > conftest.$ac_ext
+  echo '#line 6128 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7629,11 +7669,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7632: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7672: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7636: \$? = $ac_status" >&5
+   echo "$as_me:7676: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7919,11 +7959,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7922: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7962: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7926: \$? = $ac_status" >&5
+   echo "$as_me:7966: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8023,11 +8063,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8026: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8066: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8030: \$? = $ac_status" >&5
+   echo "$as_me:8070: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10368,7 +10408,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10371 "configure"
+#line 10411 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10468,7 +10508,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10471 "configure"
+#line 10511 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11734,7 +11774,7 @@ fi
                : ${mansectsu='1m'}
                : ${mansectform='4'}
                ;;
-    *-*-linux*)
+    *-*-linux*|*-*-k*bsd*-gnu)
                OSDEFS="${OSDEFS} -D_GNU_SOURCE"
                # Some Linux versions need to link with -lshadow
                shadow_funcs="getspnam"
@@ -13675,7 +13715,7 @@ if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-
+ LCMAN=""
        case "$OS" in
            freebsd|netbsd)     SUDO_LIBS="${SUDO_LIBS} -lutil"
            ;;
@@ -20051,8 +20091,7 @@ if test $ac_cv_header_bsd_auth_h = yes; then
 _ACEOF
 
        AUTH_OBJS="$AUTH_OBJS bsdauth.o"
-       BSDAUTH_USAGE='[-a auth_type] '
-       AUTH_EXCL=BSD_AUTH
+       AUTH_EXCL=BSD_AUTH; BAMAN=""
 else
   { { echo "$as_me:$LINENO: error: BSD authentication was specified but bsd_auth.h could not be found" >&5
 echo "$as_me: error: BSD authentication was specified but bsd_auth.h could not be found" >&2;}
@@ -22726,26 +22765,19 @@ done
 for ac_header in ldap_ssl.h mps/ldap_ssl.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
+#include <ldap.h>
+
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
@@ -22765,94 +22797,19 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
        } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
+  eval "$as_ac_Header=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
+       eval "$as_ac_Header=no"
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
 fi
 ac_res=`eval echo '${'$as_ac_Header'}'`
               { echo "$as_me:$LINENO: result: $ac_res" >&5
 echo "${ECHO_T}$ac_res" >&6; }
-
-fi
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 
 test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
 
-if test "$with_noexec" != "no"; then
-    PROGS="${PROGS} sudo_noexec.la"
-    INSTALL_NOEXEC="install-noexec"
-
+if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no"; then
     oexec_prefix="$exec_prefix"
     if test "$exec_prefix" = '$(prefix)'; then
        if test "$prefix" = "NONE"; then
@@ -22997,12 +22951,25 @@ if test "$with_noexec" != "no"; then
            exec_prefix="$prefix"
        fi
     fi
-    eval noexec_file="$with_noexec"
+    if test X"$with_noexec" != X"no"; then
+       PROGS="${PROGS} sudo_noexec.la"
+       INSTALL_NOEXEC="install-noexec"
+
+       eval noexec_file="$with_noexec"
 
 cat >>confdefs.h <<_ACEOF
 #define _PATH_SUDO_NOEXEC "$noexec_file"
 _ACEOF
 
+    fi
+    if test X"$with_selinux" != X"no"; then
+       eval sesh_file="$libexecdir/sesh"
+
+cat >>confdefs.h <<_ACEOF
+#define _PATH_SUDO_SESH "$sesh_file"
+_ACEOF
+
+    fi
     exec_prefix="$oexec_prefix"
 fi
 
@@ -23683,6 +23650,10 @@ SUDOERS_MODE!$SUDOERS_MODE$ac_delim
 SUDOERS_UID!$SUDOERS_UID$ac_delim
 SUDOERS_GID!$SUDOERS_GID$ac_delim
 DEV!$DEV$ac_delim
+SELINUX!$SELINUX$ac_delim
+BAMAN!$BAMAN$ac_delim
+LCMAN!$LCMAN$ac_delim
+SEMAN!$SEMAN$ac_delim
 mansectsu!$mansectsu$ac_delim
 mansectform!$mansectform$ac_delim
 mansrcdir!$mansrcdir$ac_delim
@@ -23720,10 +23691,6 @@ EGREPPROG!$EGREPPROG$ac_delim
 CC!$CC$ac_delim
 ac_ct_CC!$ac_ct_CC$ac_delim
 EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-build!$build$ac_delim
-build_cpu!$build_cpu$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -23765,6 +23732,10 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
 build_vendor!$build_vendor$ac_delim
 build_os!$build_os$ac_delim
 host!$host$ac_delim
@@ -23794,7 +23765,7 @@ KRB5CONFIG!$KRB5CONFIG$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 27; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 31; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -24402,6 +24373,8 @@ fi
 
 
 
+
+
 
 
 
index 0760e35e715321d5c30c9d7d480e22d3c70c4c32..4449b006ac99b324554a3af5f78eecd964881503 100644 (file)
@@ -1,6 +1,6 @@
 dnl
 dnl Process this file with GNU autoconf to produce a configure script.
-dnl $Sudo: configure.in,v 1.413.2.42 2008/01/21 16:08:27 millert Exp $
+dnl $Sudo: configure.in,v 1.413.2.47 2008/02/19 18:27:32 millert Exp $
 dnl
 dnl Copyright (c) 1994-1996,1998-2007 Todd C. Miller <Todd.Miller@courtesan.com>
 dnl
@@ -33,6 +33,10 @@ AC_SUBST(SUDOERS_MODE)
 AC_SUBST(SUDOERS_UID)
 AC_SUBST(SUDOERS_GID)
 AC_SUBST(DEV)
+AC_SUBST(SELINUX)
+AC_SUBST(BAMAN)
+AC_SUBST(LCMAN)
+AC_SUBST(SEMAN)
 AC_SUBST(mansectsu)
 AC_SUBST(mansectform)
 AC_SUBST(mansrcdir)
@@ -109,6 +113,10 @@ PROGS="sudo visudo"
 : ${SUDOERS_UID='0'}
 : ${SUDOERS_GID='0'}
 DEV="#"
+SELINUX="#"
+BAMAN='.\" '
+LCMAN='.\" '
+SEMAN='.\" '
 AUTH_OBJS=
 AUTH_REG=
 AUTH_EXCL=
@@ -127,7 +135,11 @@ shadow_libs_optional=
 dnl
 dnl Override default configure dirs...
 dnl
-test "$mandir" = '${prefix}/man' && mandir='$(prefix)/man'
+if test X"$prefix" = X"NONE"; then
+    test "$mandir" = '${datarootdir}/man' && mandir='$(prefix)/man'
+else
+    test "$mandir" = '${datarootdir}/man' && mandir='$(datarootdir)/man'
+fi
 test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
 test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
 test "$sysconfdir" = '${prefix}/etc' -a X"$with_stow" != X"yes" && sysconfdir='/etc'
@@ -1114,6 +1126,20 @@ AC_ARG_ENABLE(path_info,
   esac
 ], AC_MSG_RESULT(no))
 
+AC_ARG_WITH(selinux, [  --with-selinux          enable SELinux support],
+[case $with_selinux in
+    yes)       AC_DEFINE(HAVE_SELINUX)
+               SUDO_LIBS="${SUDO_LIBS} -lselinux"
+               SUDO_OBJS="${SUDO_OBJS} selinux.o"
+               PROGS="${PROGS} sesh"
+               SELINUX=""
+               SEMAN=""
+               ;;
+    no)                ;;
+    *)         AC_MSG_ERROR(["--with-selinux does not take an argument."])
+               ;;
+esac])
+
 dnl
 dnl If we don't have egrep we can't do anything...
 dnl
@@ -1382,7 +1408,7 @@ case "$host" in
                : ${mansectsu='1m'}
                : ${mansectform='4'}
                ;;
-    *-*-linux*)
+    *-*-linux*|*-*-k*bsd*-gnu)
                OSDEFS="${OSDEFS} -D_GNU_SOURCE"
                # Some Linux versions need to link with -lshadow
                shadow_funcs="getspnam"
@@ -1633,7 +1659,7 @@ if test "$OS" != "ultrix"; then
     fi
 fi
 if test ${with_logincap-'no'} != "no"; then
-    AC_CHECK_HEADERS(login_cap.h, [
+    AC_CHECK_HEADERS(login_cap.h, [LCMAN=""
        case "$OS" in
            freebsd|netbsd)     SUDO_LIBS="${SUDO_LIBS} -lutil"
            ;;
@@ -1868,8 +1894,7 @@ dnl
 if test ${with_bsdauth-'no'} != "no"; then
     AC_CHECK_HEADER(bsd_auth.h, AC_DEFINE(HAVE_BSD_AUTH_H)
        [AUTH_OBJS="$AUTH_OBJS bsdauth.o"]
-       [BSDAUTH_USAGE='[[-a auth_type]] ']
-       [AUTH_EXCL=BSD_AUTH],
+       [AUTH_EXCL=BSD_AUTH; BAMAN=""],
        [AC_MSG_ERROR([BSD authentication was specified but bsd_auth.h could not be found])])
 fi
 
@@ -2294,7 +2319,7 @@ if test ${with_ldap-'no'} != "no"; then
     AC_DEFINE(HAVE_LBER_H)])
 
     AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength)
-    AC_CHECK_HEADERS([ldap_ssl.h] [mps/ldap_ssl.h], [break])
+    AC_CHECK_HEADERS([ldap_ssl.h] [mps/ldap_ssl.h], [break], [], [#include <ldap.h>])
 
     SUDO_LIBS="${SUDO_LIBS}${LDAP_LIBS}"
     LIBS="$_LIBS"
@@ -2360,13 +2385,11 @@ dnl
 test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
 
 dnl
-dnl Defer setting _PATH_SUDO_NOEXEC until after exec_prefix is set
+dnl Defer setting _PATH_SUDO_NOEXEC and _PATH_SUDO_SESH
+dnl until after exec_prefix is set
 dnl XXX - this is gross!
 dnl
-if test "$with_noexec" != "no"; then
-    PROGS="${PROGS} sudo_noexec.la"
-    INSTALL_NOEXEC="install-noexec"
-
+if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no"; then
     oexec_prefix="$exec_prefix"
     if test "$exec_prefix" = '$(prefix)'; then
        if test "$prefix" = "NONE"; then
@@ -2375,8 +2398,17 @@ if test "$with_noexec" != "no"; then
            exec_prefix="$prefix"
        fi
     fi
-    eval noexec_file="$with_noexec"
-    AC_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so])
+    if test X"$with_noexec" != X"no"; then
+       PROGS="${PROGS} sudo_noexec.la"
+       INSTALL_NOEXEC="install-noexec"
+
+       eval noexec_file="$with_noexec"
+       AC_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so])
+    fi
+    if test X"$with_selinux" != X"no"; then
+       eval sesh_file="$libexecdir/sesh"
+       AC_DEFINE_UNQUOTED(_PATH_SUDO_SESH, "$sesh_file", [The fully qualified pathname of sesh])
+    fi
     exec_prefix="$oexec_prefix"
 fi
 
@@ -2437,6 +2469,7 @@ AH_TEMPLATE(HAVE_OPIE, [Define to 1 if you use NRL OPIE.])
 AH_TEMPLATE(HAVE_PAM, [Define to 1 if you use PAM authentication.])
 AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the <project.h> header file.])
 AH_TEMPLATE(HAVE_SECURID, [Define to 1 if you use SecurID for authentication.])
+AH_TEMPLATE(HAVE_SELINUX, [Define to 1 to enable SELinux RBAC support.])
 AH_TEMPLATE(HAVE_SIA, [Define to 1 if you use SIA authentication.])
 AH_TEMPLATE(HAVE_SIGACTION_T, [Define to 1 if <signal.h> has the sigaction_t typedef.])
 AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.])
index 944a55c2355b9ebb882b483274e88492bbd3bd2c..412d0b8ac3a7337106343dc8077944a7babb27c6 100644 (file)
@@ -263,6 +263,14 @@ struct sudo_defs_types sudo_defs_table[] = {
        "env_keep", T_LIST|T_BOOL,
        "Environment variables to preserve:",
        NULL,
+    }, {
+       "role", T_STR,
+       "SELinux role to use in the new security context",
+       NULL,
+    }, {
+       "type", T_STR,
+       "SELinux type to use in the new security context",
+       NULL,
     }, {
        NULL, 0, NULL
     }
index 13d81bf7089a98ce532b71d3ea9cbadf510f7f40..bbbd2ab0a5f6d10148bb83e31a90e75e88bc0309 100644 (file)
 #define I_ENV_DELETE            58
 #define def_env_keep            (sudo_defs_table[59].sd_un.list)
 #define I_ENV_KEEP              59
+#define def_role                (sudo_defs_table[60].sd_un.str)
+#define I_ROLE                  60
+#define def_type                (sudo_defs_table[61].sd_un.str)
+#define I_TYPE                  61
 
 enum def_tupple {
        never,
index 47370b83ecf80ee0fc5e5bf9f0eac63f4dd1cc58..fb16f7554bf7dd165608e90544f9bbf4e4aa5247 100644 (file)
@@ -191,3 +191,9 @@ env_delete
 env_keep
        T_LIST|T_BOOL
        "Environment variables to preserve:"
+role
+       T_STR
+       "SELinux role to use in the new security context"
+type
+       T_STR
+       "SELinux type to use in the new security context"
diff --git a/ldap.c b/ldap.c
index 9097310cbf9354c96596a085ac46eba7c733fea8..0477f81231f4dfbc3d97dbd2b939d7c3ea847d18 100644 (file)
--- a/ldap.c
+++ b/ldap.c
@@ -71,7 +71,7 @@
 #include "parse.h"
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: ldap.c,v 1.11.2.36 2008/01/21 16:08:26 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: ldap.c,v 1.11.2.37 2008/02/09 14:44:47 millert Exp $";
 #endif /* lint */
 
 #ifndef LINE_MAX
@@ -1189,6 +1189,13 @@ sudo_ldap_check(pwflag)
                if (setenv_implied)
                    def_setenv = TRUE;
                sudo_ldap_parse_options(ld, entry);
+#ifdef HAVE_SELINUX
+               /* Set role and type if not specified on command line. */
+               if (user_role == NULL)
+                   user_role = def_role;
+               if (user_type == NULL)
+                   user_type = def_type;
+#endif /* HAVE_SELINUX */
                /* make sure we don't reenter loop */
                ret = VALIDATE_OK;
                /* break from inside for loop */
index 47cd239dbbab4c433df820bc2a49382d3183791d..68405fbd7388e180ab1f591721e25ff991ffde56 100644 (file)
--- a/lex.yy.c
+++ b/lex.yy.c
@@ -3,7 +3,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /home/cvs/courtesan/sudo/Attic/lex.yy.c,v 1.46.2.8 2007/08/25 02:48:01 millert Exp $
+ * $Header: /home/cvs/courtesan/sudo/Attic/lex.yy.c,v 1.46.2.9 2008/02/09 14:44:47 millert Exp $
  */
 
 #define FLEX_SCANNER
@@ -1480,7 +1480,7 @@ char *yytext;
 #include <sudo.tab.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: lex.yy.c,v 1.46.2.8 2007/08/25 02:48:01 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: lex.yy.c,v 1.46.2.9 2008/02/09 14:44:47 millert Exp $";
 #endif /* lint */
 
 #undef yywrap          /* guard against a yywrap macro */
@@ -2076,16 +2076,26 @@ YY_RULE_SETUP
                            if (strcmp(yytext, "ALL") == 0) {
                                LEXTRACE("ALL ");
                                return(ALL);
-                           } else {
-                               fill(yytext, yyleng);
-                               LEXTRACE("ALIAS ");
-                               return(ALIAS);
                            }
+#ifdef HAVE_SELINUX
+                           /* XXX - restrict type/role to initial state */
+                           if (strcmp(yytext, "TYPE") == 0) {
+                               LEXTRACE("TYPE ");
+                               return(TYPE);
+                           }
+                           if (strcmp(yytext, "ROLE") == 0) {
+                               LEXTRACE("ROLE ");
+                               return(ROLE);
+                           }
+#endif /* HAVE_SELINUX */
+                           fill(yytext, yyleng);
+                           LEXTRACE("ALIAS ");
+                           return(ALIAS);
                        }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 336 "parse.lex"
+#line 346 "parse.lex"
 {
                            /* username/uid that user can run command as */
                            fill(yytext, yyleng);
@@ -2095,7 +2105,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 343 "parse.lex"
+#line 353 "parse.lex"
 {
                            BEGIN INITIAL;
                            ++sudolineno;
@@ -2105,14 +2115,14 @@ YY_RULE_SETUP
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 350 "parse.lex"
+#line 360 "parse.lex"
 {
                            BEGIN INITIAL;
                        }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 354 "parse.lex"
+#line 364 "parse.lex"
 {
                            BEGIN GOTCMND;
                            LEXTRACE("COMMAND ");
@@ -2121,7 +2131,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 360 "parse.lex"
+#line 370 "parse.lex"
 {
                            /* directories can't have args... */
                            if (yytext[yyleng - 1] == '/') {
@@ -2137,7 +2147,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 373 "parse.lex"
+#line 383 "parse.lex"
 {
                            /* a word */
                            fill(yytext, yyleng);
@@ -2147,7 +2157,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 380 "parse.lex"
+#line 390 "parse.lex"
 {
                            LEXTRACE(", ");
                            return(',');
@@ -2155,7 +2165,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 385 "parse.lex"
+#line 395 "parse.lex"
 {
                            LEXTRACE("= ");
                            return('=');
@@ -2163,7 +2173,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 390 "parse.lex"
+#line 400 "parse.lex"
 {
                            LEXTRACE(": ");
                            return(':');
@@ -2171,7 +2181,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 395 "parse.lex"
+#line 405 "parse.lex"
 {
                            if (yyleng % 2 == 1)
                                return('!');    /* return '!' */
@@ -2179,7 +2189,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 400 "parse.lex"
+#line 410 "parse.lex"
 {
                            BEGIN INITIAL;
                            ++sudolineno;
@@ -2189,14 +2199,14 @@ YY_RULE_SETUP
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 407 "parse.lex"
+#line 417 "parse.lex"
 {                      /* throw away space/tabs */
                            sawspace = TRUE;    /* but remember for fill_args */
                        }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 411 "parse.lex"
+#line 421 "parse.lex"
 {
                            sawspace = TRUE;    /* remember for fill_args */
                            ++sudolineno;
@@ -2205,7 +2215,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 417 "parse.lex"
+#line 427 "parse.lex"
 {
                            BEGIN INITIAL;
                            ++sudolineno;
@@ -2215,7 +2225,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 424 "parse.lex"
+#line 434 "parse.lex"
 {
                            LEXTRACE("ERROR ");
                            return(ERROR);
@@ -2228,7 +2238,7 @@ case YY_STATE_EOF(GOTCMND):
 case YY_STATE_EOF(STARTDEFS):
 case YY_STATE_EOF(INDEFS):
 case YY_STATE_EOF(INSTR):
-#line 429 "parse.lex"
+#line 439 "parse.lex"
 {
                            if (YY_START != INITIAL) {
                                BEGIN INITIAL;
@@ -2240,10 +2250,10 @@ case YY_STATE_EOF(INSTR):
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 438 "parse.lex"
+#line 448 "parse.lex"
 ECHO;
        YY_BREAK
-#line 2247 "lex.yy.c"
+#line 2257 "lex.yy.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -3132,7 +3142,7 @@ int main()
        return 0;
        }
 #endif
-#line 438 "parse.lex"
+#line 448 "parse.lex"
 
 static void
 _fill(src, len, olen)
diff --git a/parse.c b/parse.c
index ce943f64eff1e86c7334bd382b8fff4117fdd457..8c4a1e5bb5935d0ab172bfafe51a0b253d175149 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -90,7 +90,7 @@
 #endif /* HAVE_EXTENDED_GLOB */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: parse.c,v 1.160.2.15 2007/12/04 15:26:40 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: parse.c,v 1.160.2.16 2008/02/09 14:44:48 millert Exp $";
 #endif /* lint */
 
 /*
@@ -198,6 +198,21 @@ sudoers_lookup(pwflag)
                    /*
                     * User was granted access to cmnd on host as user.
                     */
+#ifdef HAVE_SELINUX
+                   /* Set role and type if not specified on command line. */
+                   if (user_role == NULL) {
+                       if (match[top-1].role != NULL)
+                           user_role = match[top-1].role;
+                       else
+                           user_role = def_role;
+                   }
+                   if (user_type == NULL) {
+                       if (match[top-1].type != NULL)
+                           user_type = match[top-1].type;
+                       else
+                           user_type = def_type;
+                   }
+#endif
                    set_perms(PERM_ROOT);
                    return(VALIDATE_OK |
                        (no_passwd == TRUE ? FLAG_NOPASS : 0) |
diff --git a/parse.h b/parse.h
index 9ad008a3ae9a4a9940a8ec4de1f39f0713ed115f..a9bbc8e0e7a40910688cce66cab347b3cfebdf07 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Sudo: parse.h,v 1.14.2.1 2007/06/23 21:36:48 millert Exp $
+ * $Sudo: parse.h,v 1.14.2.2 2008/02/09 14:44:48 millert Exp $
  */
 
 #ifndef _SUDO_PARSE_H
@@ -35,6 +35,8 @@ struct matchstack {
        int nopass;
        int noexec;
        int setenv;
+       char *role;
+       char *type;
 };
 
 /*
@@ -46,6 +48,15 @@ struct sudo_command {
     char *args;
 };
 
+/*
+ * SELinux-specific container struct.
+ * Currently just contains a role and type.
+ */
+struct selinux_info {
+    char *role;
+    char *type;
+};
+
 #define user_matches   (match[top-1].user)
 #define cmnd_matches   (match[top-1].cmnd)
 #define host_matches   (match[top-1].host)
@@ -64,6 +75,12 @@ struct command_match {
     char *cmnd;
     size_t cmnd_len;
     size_t cmnd_size;
+    char *role;
+    size_t role_len;
+    size_t role_size;
+    char *type;
+    size_t type_len;
+    size_t type_size;
     int nopasswd;
     int noexecve;
     int setenv;
index 1c4bbc79b9a3cf2e657c24e20be8e53b4e1fcd55..f1ffddcf2f6adb3311f9c2f6dc543f1b4240fbc8 100644 (file)
--- a/parse.lex
+++ b/parse.lex
@@ -55,7 +55,7 @@
 #include <sudo.tab.h>
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: parse.lex,v 1.132.2.7 2007/08/25 02:48:01 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: parse.lex,v 1.132.2.8 2008/02/09 14:44:48 millert Exp $";
 #endif /* lint */
 
 #undef yywrap          /* guard against a yywrap macro */
@@ -326,11 +326,21 @@ NOSETENV[[:blank:]]*:     {
                            if (strcmp(yytext, "ALL") == 0) {
                                LEXTRACE("ALL ");
                                return(ALL);
-                           } else {
-                               fill(yytext, yyleng);
-                               LEXTRACE("ALIAS ");
-                               return(ALIAS);
                            }
+#ifdef HAVE_SELINUX
+                           /* XXX - restrict type/role to initial state */
+                           if (strcmp(yytext, "TYPE") == 0) {
+                               LEXTRACE("TYPE ");
+                               return(TYPE);
+                           }
+                           if (strcmp(yytext, "ROLE") == 0) {
+                               LEXTRACE("ROLE ");
+                               return(ROLE);
+                           }
+#endif /* HAVE_SELINUX */
+                           fill(yytext, yyleng);
+                           LEXTRACE("ALIAS ");
+                           return(ALIAS);
                        }
 
 <GOTRUNAS>(#[0-9-]+|{WORD}) {
index 5b1c856bb167912791c539f44b0271e7e9a60060..93871b23892b6ce8f97fa48bf84b738b56bb2780 100644 (file)
@@ -70,7 +70,7 @@
 #endif /* HAVE_LSEARCH */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: parse.yacc,v 1.204.2.10 2008/01/16 23:20:53 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: parse.yacc,v 1.204.2.13 2008/02/27 20:34:42 millert Exp $";
 #endif /* lint */
 
 /*
@@ -140,6 +140,8 @@ int top = 0, stacksize = 0;
        match[top].nopass = def_authenticate ? UNSPEC : TRUE; \
        match[top].noexec = def_noexec ? TRUE : UNSPEC; \
        match[top].setenv = def_setenv ? TRUE : UNSPEC; \
+       match[top].role = NULL; \
+       match[top].type = NULL; \
        top++; \
     } while (0)
 
@@ -156,6 +158,8 @@ int top = 0, stacksize = 0;
        match[top].nopass = match[top-1].nopass; \
        match[top].noexec = match[top-1].noexec; \
        match[top].setenv = match[top-1].setenv; \
+       match[top].role   = estrdup(match[top-1].role); \
+       match[top].type   = estrdup(match[top-1].type); \
        top++; \
     } while (0)
 
@@ -163,8 +167,11 @@ int top = 0, stacksize = 0;
     do { \
        if (top == 0) \
            yyerror("matching stack underflow"); \
-       else \
+       else { \
+           efree(match[top-1].role); \
+           efree(match[top-1].type); \
            top--; \
+       } \
     } while (0)
 
 
@@ -182,6 +189,12 @@ int top = 0, stacksize = 0;
 #define append_runas(s, p) append(s, &cm_list[cm_list_len].runas, \
        &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, p)
 
+#define append_role(s, p) append(s, &cm_list[cm_list_len].role, \
+       &cm_list[cm_list_len].role_len, &cm_list[cm_list_len].role_size, p)
+
+#define append_type(s, p) append(s, &cm_list[cm_list_len].type, \
+       &cm_list[cm_list_len].type_len, &cm_list[cm_list_len].type_size, p)
+
 #define append_entries(s, p) append(s, &ga_list[ga_list_len-1].entries, \
        &ga_list[ga_list_len-1].entries_len, \
        &ga_list[ga_list_len-1].entries_size, p)
@@ -240,6 +253,7 @@ yyerror(s)
     int BOOLEAN;
     struct sudo_command command;
     int tok;
+    struct selinux_info seinfo;
 }
 
 %start file                            /* special start symbol */
@@ -269,6 +283,8 @@ yyerror(s)
 %token <tok>    RUNASALIAS             /* Runas_Alias keyword */
 %token <tok>    ':' '=' ',' '!' '+' '-' /* union member tokens */
 %token <tok>    ERROR
+%token <tok>    TYPE                   /* SELinux type */
+%token <tok>    ROLE                   /* SELinux role */
 
 /*
  * NOTE: these are not true booleans as there are actually 4 possible values:
@@ -283,6 +299,9 @@ yyerror(s)
 %type <BOOLEAN>         oprunasuser
 %type <BOOLEAN>         runaslist
 %type <BOOLEAN>         user
+%type <seinfo>  selinux
+%type <string>  rolespec
+%type <string>  typespec
 
 %%
 
@@ -394,6 +413,12 @@ privilege  :       hostlist '=' cmndspeclist {
                            no_passwd = def_authenticate ? UNSPEC : TRUE;
                            no_execve = def_noexec ? TRUE : UNSPEC;
                            setenv_ok = def_setenv ? TRUE : UNSPEC;
+#ifdef HAVE_SELINUX
+                           efree(match[top-1].role);
+                           match[top-1].role = NULL;
+                           efree(match[top-1].type);
+                           match[top-1].type = NULL;
+#endif
                        }
                ;
 
@@ -457,7 +482,18 @@ cmndspeclist       :       cmndspec
                |       cmndspeclist ',' cmndspec
                ;
 
-cmndspec       :       { SETENV_RESET; } runasspec cmndtag opcmnd {
+cmndspec       :       { SETENV_RESET; } runasspec selinux cmndtag opcmnd {
+#ifdef HAVE_SELINUX
+                           /* Replace inherited role/type as needed. */
+                           if ($3.role != NULL) {
+                               efree(match[top-1].role);
+                               match[top-1].role = $3.role;
+                           }
+                           if ($3.type != NULL) {
+                               efree(match[top-1].type);
+                               match[top-1].type = $3.type;
+                           }
+#endif
                            /*
                             * Push the entry onto the stack if it is worth
                             * saving and reset cmnd_matches for next cmnd.
@@ -482,6 +518,7 @@ cmndspec    :       { SETENV_RESET; } runasspec cmndtag opcmnd {
                                pushcp;
                            else if (user_matches == TRUE && keepall)
                                pushcp;
+
                            cmnd_matches = UNSPEC;
                        }
                ;
@@ -502,6 +539,97 @@ opcmnd             :       cmnd {
                        }
                ;
 
+rolespec       :       ROLE '=' WORD {
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE)
+                               append_role($3, NULL);
+                           $$ = $3;
+#else
+                           free($3);
+                           $$ = NULL;
+#endif /* HAVE_SELINUX */
+                       }
+               ;
+
+typespec       :       TYPE '=' WORD {
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE)
+                               append_type($3, NULL);
+                           $$ = $3;
+#else
+                           free($3);
+                           $$ = NULL;
+#endif /* HAVE_SELINUX */
+                       }
+               ;
+
+selinux                :       /* empty */ {
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit role. */
+                               cm_list[cm_list_len].role =
+                                   estrdup(cm_list[cm_list_len-1].role);
+                               cm_list[cm_list_len].role_len =
+                                   cm_list[cm_list_len-1].role_len;
+                               cm_list[cm_list_len].role_size =
+                                   cm_list[cm_list_len-1].role_len + 1;
+                               /* Inherit type. */
+                               cm_list[cm_list_len].type =
+                                   estrdup(cm_list[cm_list_len-1].type);
+                               cm_list[cm_list_len].type_len =
+                                   cm_list[cm_list_len-1].type_len;
+                               cm_list[cm_list_len].type_size =
+                                   cm_list[cm_list_len-1].type_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           $$.role = NULL;
+                           $$.type = NULL;
+                       }
+               |       rolespec {
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit type. */
+                               cm_list[cm_list_len].type =
+                                   estrdup(cm_list[cm_list_len-1].type);
+                               cm_list[cm_list_len].type_len =
+                                   cm_list[cm_list_len-1].type_len;
+                               cm_list[cm_list_len].type_size =
+                                   cm_list[cm_list_len-1].type_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           $$.role = $1;
+                           $$.type = NULL;
+                       }
+               |       typespec {
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit role. */
+                               cm_list[cm_list_len].role =
+                                   estrdup(cm_list[cm_list_len-1].role);
+                               cm_list[cm_list_len].role_len =
+                                   cm_list[cm_list_len-1].role_len;
+                               cm_list[cm_list_len].role_size =
+                                   cm_list[cm_list_len-1].role_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           $$.type = $1;
+                           $$.role = NULL;
+                       }
+               |       rolespec typespec {
+                           $$.role = $1;
+                           $$.type = $2;
+                       }
+               |       typespec rolespec {
+                           $$.type = $1;
+                           $$.role = $2;
+                       }
+               ;
+
 runasspec      :       /* empty */ {
                            if (printmatches == TRUE && host_matches == TRUE &&
                                user_matches == TRUE) {
@@ -514,7 +642,7 @@ runasspec   :       /* empty */ {
                                    cm_list[cm_list_len].runas_len =
                                        cm_list[cm_list_len-1].runas_len;
                                    cm_list[cm_list_len].runas_size =
-                                       cm_list[cm_list_len-1].runas_size;
+                                       cm_list[cm_list_len-1].runas_len + 1;
                                }
                            }
                            /*
@@ -1102,6 +1230,14 @@ list_matches()
            (void) printf("(%s) ", def_runas_default);
        }
 
+#ifdef HAVE_SELINUX
+       /* SELinux role and type */
+       if (cm_list[count].role != NULL)
+           (void) printf("ROLE=%s ", cm_list[count].role);
+       if (cm_list[count].type != NULL)
+           (void) printf("TYPE=%s ", cm_list[count].type);
+#endif
+
        /* Is execve(2) disabled? */
        if (cm_list[count].noexecve == TRUE && !def_noexec)
            (void) fputs("NOEXEC: ", stdout);
@@ -1141,6 +1277,8 @@ list_matches()
     for (count = 0; count < cm_list_len; count++) {
        efree(cm_list[count].runas);
        efree(cm_list[count].cmnd);
+       efree(cm_list[count].role);
+       efree(cm_list[count].type);
     }
     efree(cm_list);
     cm_list = NULL;
@@ -1245,6 +1383,7 @@ expand_match_list()
     }
 
     cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
+    cm_list[cm_list_len].type = cm_list[cm_list_len].role = NULL;
     cm_list[cm_list_len].nopasswd = FALSE;
     cm_list[cm_list_len].noexecve = FALSE;
     cm_list[cm_list_len].setenv = FALSE;
index cef07932eb6f0c66edcd5a366704d26d7c027018..3fc32495cf1d17ba7b96617d62b312777b1159a4 100644 (file)
@@ -18,7 +18,7 @@
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  *
- * $Sudo: pathnames.h.in,v 1.51.2.3 2007/06/19 21:25:48 millert Exp $
+ * $Sudo: pathnames.h.in,v 1.51.2.4 2008/02/09 14:44:48 millert Exp $
  */
 
 /*
 #undef _PATH_BSHELL
 #endif /* _PATH_BSHELL */
 
+#ifndef _PATH_SUDO_SESH
+#undef _PATH_SUDO_SESH
+#endif /* _PATH_SUDO_SESH */
+
 #ifndef _PATH_TMP
 #define        _PATH_TMP       "/tmp/"
 #endif /* _PATH_TMP */
diff --git a/selinux.c b/selinux.c
new file mode 100644 (file)
index 0000000..7d49854
--- /dev/null
+++ b/selinux.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2008 Dan Walsh <dwalsh@redhat.com>
+ *
+ * Borrowed heavily from newrole source code
+ * Authors:
+ *     Anthony Colatrella
+ *     Tim Fraser
+ *     Steve Grubb <sgrubb@redhat.com>
+ *     Darrel Goeddel <DGoeddel@trustedcs.com>
+ *     Michael Thompson <mcthomps@us.ibm.com>
+ *     Dan Walsh <dwalsh@redhat.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#ifdef WITH_AUDIT
+#include <libaudit.h>
+#endif
+
+#include <selinux/flask.h>             /* for SECCLASS_CHR_FILE */
+#include <selinux/selinux.h>           /* for is_selinux_enabled() */
+#include <selinux/context.h>           /* for context-mangling functions */
+#include <selinux/get_default_type.h>
+#include <selinux/get_context_list.h>
+
+#include "sudo.h"
+#include "pathnames.h"
+
+#ifndef lint
+__unused static const char rcsid[] = "$Sudo: selinux.c,v 1.2.2.4 2008/02/22 20:33:10 millert Exp $";
+#endif /* lint */
+
+/*
+ * This function attempts to revert the relabeling done to the tty.
+ * fd             - referencing the opened ttyn
+ * ttyn                   - name of tty to restore
+ * tty_context    - original context of the tty
+ * new_tty_context - context tty was relabeled to
+ *
+ * Returns zero on success, non-zero otherwise
+ */
+static int
+restore_tty_label(int fd, const char *ttyn, security_context_t tty_context,
+    security_context_t new_tty_context)
+{
+    int rc = 0;
+    security_context_t chk_tty_context = NULL;
+
+    if (!ttyn)
+           goto skip_relabel;
+
+    if (!new_tty_context)
+           goto skip_relabel;
+
+    /* Verify that the tty still has the context set by sudo. */
+    if ((rc = fgetfilecon(fd, &chk_tty_context)) < 0) {
+           warn("unable to fgetfilecon %s", ttyn);
+           goto skip_relabel;
+    }
+
+    if ((rc = strcmp(chk_tty_context, new_tty_context))) {
+           warnx("%s changed labels.", ttyn);
+           goto skip_relabel;
+    }
+
+    if ((rc = fsetfilecon(fd, tty_context)) < 0)
+       warn("unable to restore context for %s", ttyn);
+
+skip_relabel:
+    freecon(chk_tty_context);
+    return(rc);
+}
+
+/*
+ * This function attempts to relabel the tty. If this function fails, then
+ * the fd is closed, the contexts are free'd and -1 is returned. On success,
+ * a valid fd is returned and tty_context and new_tty_context are set.
+ *
+ * This function will not fail if it can not relabel the tty when selinux is
+ * in permissive mode.
+ */
+static int
+relabel_tty(const char *ttyn, security_context_t new_context,
+    security_context_t * tty_context, security_context_t * new_tty_context,
+    int enforcing)
+{
+    int fd;
+    security_context_t tty_con = NULL;
+    security_context_t new_tty_con = NULL;
+
+    if (!ttyn)
+       return(0);
+
+    /* Re-open TTY descriptor */
+    fd = open(ttyn, O_RDWR | O_NONBLOCK);
+    if (fd == -1) {
+       warn("unable to open %s", ttyn);
+       return(-1);
+    }
+    (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+
+    if (fgetfilecon(fd, &tty_con) < 0) {
+       warn("unable to get current context for %s, not relabeling tty",
+           ttyn);
+       if (enforcing)
+           goto error;
+    }
+
+    if (tty_con && (security_compute_relabel(new_context, tty_con,
+       SECCLASS_CHR_FILE, &new_tty_con) < 0)) {
+       warn("unable to get new context for %s, not relabeling tty", ttyn);
+       if (enforcing)
+           goto error;
+    }
+
+    if (new_tty_con != NULL) {
+       if (fsetfilecon(fd, new_tty_con) < 0) {
+           warn("unable to set new context for %s", ttyn);
+           if (enforcing)
+               goto error;
+       }
+    }
+
+    *tty_context = tty_con;
+    *new_tty_context = new_tty_con;
+    return(fd);
+
+error:
+    freecon(tty_con);
+    close(fd);
+    return(-1);
+}
+
+/*
+ * Returns a new security context based on the old context and the
+ * specified role and type.
+ */
+security_context_t
+get_exec_context(security_context_t old_context, char *role, char *type)
+{
+    security_context_t new_context = NULL;
+    context_t context = NULL;
+    char *typebuf = NULL;
+    
+    /* We must have a role, the type is optional (we can use the default). */
+    if (!role) {
+       warnx("you must specify a role.");
+       return(NULL);
+    }
+    if (!type) {
+       if (get_default_type(role, &typebuf)) {
+           warnx("unable to get default type");
+           return(NULL);
+       }
+       type = typebuf;
+    }
+    
+    /* 
+     * Expand old_context into a context_t so that we extract and modify 
+     * its components easily. 
+     */
+    context = context_new(old_context);
+    
+    /*
+     * Replace the role and type in "context" with the role and
+     * type we will be running the command as.
+     */
+    if (context_role_set(context, role)) {
+       warnx("failed to set new role %s", role);
+       goto error;
+    }
+    if (context_type_set(context, type)) {
+       warnx("failed to set new type %s", type);
+       goto error;
+    }
+      
+    /*
+     * Convert "context" back into a string and verify it.
+     */
+    new_context = estrdup(context_str(context));
+    if (security_check_context(new_context) < 0) {
+       warnx("%s is not a valid context", new_context);
+       goto error;
+    }
+
+#ifdef DEBUG
+    warnx("Your new context is %s", new_context);
+#endif
+
+    context_free(context);
+    return(new_context);
+
+error:
+    free(typebuf);
+    context_free(context);
+    freecon(new_context);
+    return(NULL);
+}
+
+/* 
+ * If the program is being run with a different security context we
+ * need to go through an intermediary process for the transition to
+ * be allowed by the policy.  We use the "sesh" shell for this, which
+ * will simply execute the command pass to it on the command line.
+ */
+void
+selinux_exec(char *role, char *type, char **argv, char **envp, int login_shell)
+{
+    security_context_t old_context = NULL;
+    security_context_t new_context = NULL;
+    security_context_t tty_context = NULL;
+    security_context_t new_tty_context = NULL;
+    pid_t childPid;
+    int enforcing, ttyfd;
+
+    /* Must have a tty. */
+    if (user_ttypath == NULL || *user_ttypath == '\0')
+       err(EXIT_FAILURE, "unable to determine tty");
+
+    /* Store the caller's SID in old_context. */
+    if (getprevcon(&old_context))
+       err(EXIT_FAILURE, "failed to get old_context");
+
+    enforcing = security_getenforce();
+    if (enforcing < 0)
+       err(EXIT_FAILURE, "unable to determine enforcing mode.");
+
+    
+#ifdef DEBUG
+    warnx("your old context was %s", old_context);
+#endif
+    new_context = get_exec_context(old_context, role, type);
+    if (!new_context)
+       exit(EXIT_FAILURE);
+    
+    ttyfd = relabel_tty(user_ttypath, new_context, &tty_context,
+       &new_tty_context, enforcing);
+    if (ttyfd < 0)
+       err(EXIT_FAILURE, "unable to setup tty context for %s", new_context);
+
+#ifdef DEBUG
+    warnx("your old tty context is %s", tty_context);
+    warnx("your new tty context is %s", new_tty_context);
+#endif
+
+    childPid = fork();
+    if (childPid < 0) {
+       /* fork failed, no child to worry about */
+       warn("unable to fork");
+       if (restore_tty_label(ttyfd, user_ttypath, tty_context, new_tty_context))
+           warnx("unable to restore tty label");
+       exit(EXIT_FAILURE);
+    } else if (childPid) {
+       pid_t pid;
+       int status;
+       
+       /* Parent, wait for child to finish. */
+       do {
+               pid = waitpid(childPid, &status, 0);
+       } while (pid == -1 && errno == EINTR);
+
+       if (pid == -1)
+           err(EXIT_FAILURE, "waitpid");
+       
+       if (restore_tty_label(ttyfd, user_ttypath, tty_context, new_tty_context))
+           errx(EXIT_FAILURE, "unable to restore tty label");
+
+       /* Preserve child exit status. */
+       if (WIFEXITED(status))
+           exit(WEXITSTATUS(status));
+       exit(EXIT_FAILURE);
+    }
+    /* Child */
+    /* Close the tty and reopen descriptors 0 through 2 */
+    if (close(ttyfd) || close(STDIN_FILENO) || close(STDOUT_FILENO) ||
+       close(STDERR_FILENO)) {
+       warn("could not close descriptors");
+       goto error;
+    }
+    ttyfd = open(user_ttypath, O_RDONLY | O_NONBLOCK);
+    if (ttyfd != STDIN_FILENO)
+       goto error;
+    fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
+    ttyfd = open(user_ttypath, O_RDWR | O_NONBLOCK);
+    if (ttyfd != STDOUT_FILENO)
+       goto error;
+    fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
+    ttyfd = dup(STDOUT_FILENO);
+    if (ttyfd != STDERR_FILENO)
+       goto error;
+
+    if (setexeccon(new_context)) {
+       warn("unable to set exec context to %s", new_context);
+       if (enforcing)
+           goto error;
+    }
+
+    if (setkeycreatecon(new_context)) {
+       warn("unable to set key creation context to %s", new_context);
+       if (enforcing)
+           goto error;
+    }
+
+#ifdef WITH_AUDIT
+    if (send_audit_message(1, old_context, new_context, user_ttypath)) 
+       goto error;
+#endif
+
+    /* We use the "spare" slot in argv to store sesh. */
+    --argv;
+    argv[0] = login_shell ? "-sesh" : "sesh";
+    argv[1] = safe_cmnd;
+
+    execve(_PATH_SUDO_SESH, argv, envp);
+    warn("%s", safe_cmnd);
+
+error:
+    _exit(EXIT_FAILURE);
+}
diff --git a/sesh.c b/sesh.c
new file mode 100644 (file)
index 0000000..06728d4
--- /dev/null
+++ b/sesh.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2008 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "compat.h"
+
+#ifndef lint
+__unused static const char rcsid[] = "$Sudo: sesh.c,v 1.1.2.1 2008/02/09 14:44:49 millert Exp $";
+#endif /* lint */
+
+int
+main (int argc, char **argv)
+{
+    char *cp, *cmnd;
+
+    if (argc < 2)
+       errx(EXIT_FAILURE, "requires at least one argument");
+
+    /* Shift argv and make a copy of the command to execute. */
+    argv++;
+    argc--;
+    cmnd = strdup(argv[0]);
+    if (cmnd == NULL)
+       err(EXIT_FAILURE, NULL);
+
+    /* If invoked as a login shell, modify argv[0] accordingly. */
+    if (argv[0][0] == '-') {
+       if ((cp = strrchr(argv[0], '/')) == NULL)
+           cp = argv[0];
+       *cp = '-';
+    }
+    execv(cmnd, argv);
+    warn("unable to execute %s", argv[0]);
+    _exit(EXIT_FAILURE);
+}
diff --git a/sudo.c b/sudo.c
index 021e0e560b7c6441ce3a193e3b9b2c3c1b1a8706..0e7f6c7efb0401abb7d667bc24279a223880ba0d 100644 (file)
--- a/sudo.c
+++ b/sudo.c
 # include <project.h>
 # include <sys/task.h>
 #endif
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
 
 #include "sudo.h"
 #include "interfaces.h"
 #include "version.h"
 
 #ifndef lint
-__unused __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.369.2.34 2007/12/13 14:12:49 millert Exp $";
+__unused __unused static const char rcsid[] = "$Sudo: sudo.c,v 1.369.2.38 2008/03/05 19:34:49 millert Exp $";
 #endif /* lint */
 
 /*
@@ -270,25 +273,22 @@ main(argc, argv, envp)
     validated = sudo_ldap_check(pwflag);
 
     /* Skip reading /etc/sudoers if LDAP told us to */
-    if (def_ignore_local_sudoers); /* skips */
-    else if (ISSET(validated, VALIDATE_OK) && !printmatches); /* skips */
-    else if (ISSET(validated, VALIDATE_OK) && printmatches)
-    {
-       check_sudoers();        /* check mode/owner on _PATH_SUDOERS */
+    if (!def_ignore_local_sudoers) {
+       int v;
 
-       /* User is found in LDAP and we want a list of all sudo commands the
-        * user can do, so consult sudoers but throw away result.
-        */
-       sudoers_lookup(pwflag);
-    }
-    else
-#endif
-    {
        check_sudoers();        /* check mode/owner on _PATH_SUDOERS */
 
-       /* Validate the user but don't search for pseudo-commands. */
-       validated = sudoers_lookup(pwflag);
+       /* Local sudoers file overrides LDAP if we have a match. */
+       v = sudoers_lookup(pwflag);
+       if (ISSET(v, VALIDATE_OK))
+           validated = v;
     }
+#else
+    check_sudoers();   /* check mode/owner on _PATH_SUDOERS */
+
+    /* Validate the user but don't search for pseudo-commands. */
+    validated = sudoers_lookup(pwflag);
+#endif
     if (safe_cmnd == NULL)
        safe_cmnd = estrdup(user_cmnd);
 
@@ -442,8 +442,14 @@ main(argc, argv, envp)
 #ifndef PROFILING
        if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
            exit(0);
-       else
+       else {
+#ifdef HAVE_SELINUX
+           if (is_selinux_enabled() > 0 && user_role != NULL)
+               selinux_exec(user_role, user_type, NewArgv, environ,
+                   ISSET(sudo_mode, MODE_LOGIN_SHELL));
+#endif
            execve(safe_cmnd, NewArgv, environ);
+       }
 #else
        exit(0);
 #endif /* PROFILING */
@@ -858,6 +864,28 @@ parse_args(argc, argv)
                case 'E':
                    SET(rval, MODE_PRESERVE_ENV);
                    break;
+#ifdef HAVE_SELINUX
+               case 'r':
+                   /* Must have an associated SELinux role. */
+                   if (NewArgv[1] == NULL)
+                       usage(1);
+
+                   user_role = NewArgv[1];
+
+                   NewArgc--;
+                   NewArgv++;
+                   break;
+               case 't':
+                   /* Must have an associated SELinux type. */
+                   if (NewArgv[1] == NULL)
+                       usage(1);
+
+                   user_type = NewArgv[1];
+
+                   NewArgc--;
+                   NewArgv++;
+                   break;
+#endif
                case '-':
                    NewArgc--;
                    NewArgv++;
@@ -992,9 +1020,25 @@ static void
 initial_setup()
 {
     int miss[3], devnull = -1;
-#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+#if defined(__linux__) || (defined(RLIMIT_CORE) && !defined(SUDO_DEVEL))
     struct rlimit rl;
+#endif
 
+#if defined(__linux__)
+    /*
+     * Unlimit the number of processes since Linux's setuid() will
+     * apply resource limits when changing uid and return EAGAIN if
+     * nproc would be violated by the uid switch.
+     */
+    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+    if (setrlimit(RLIMIT_NPROC, &rl)) {
+       if (getrlimit(RLIMIT_NPROC, &rl) == 0) {
+           rl.rlim_cur = rl.rlim_max;
+           (void)setrlimit(RLIMIT_NPROC, &rl);
+       }
+    }
+#endif /* __linux__ */
+#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
     /*
      * Turn off core dumps.
      */
@@ -1272,8 +1316,14 @@ usage(exit_val)
 #endif
 #ifdef HAVE_LOGIN_CAP_H
        " [-c class|-]",
+#endif
+#ifdef HAVE_SELINUX
+       " [-r role]",
 #endif
        " [-p prompt]",
+#ifdef HAVE_SELINUX
+       " [-t type]",
+#endif
        " [-u username|#uid]",
        " [VAR=value]",
        " {-i | -s | <command>}",
index e8aca6f118a6a0ac564835f8a275616053d2b5c3..eec5ed47e62855103bab8278bc01cf7b4680a7cb 100644 (file)
--- a/sudo.cat
+++ b/sudo.cat
@@ -61,7 +61,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
 
 
-1.6.9p12                 January 14, 2008                       1
+1.6.9p14                February 19, 2008                       1
 
 
 
@@ -127,7 +127,7 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
 
 
-1.6.9p12                 January 14, 2008                       2
+1.6.9p14                February 19, 2008                       2
 
 
 
@@ -193,7 +193,7 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
 
-1.6.9p12                 January 14, 2008                       3
+1.6.9p14                February 19, 2008                       3
 
 
 
@@ -259,7 +259,7 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
 
-1.6.9p12                 January 14, 2008                       4
+1.6.9p14                February 19, 2008                       4
 
 
 
@@ -325,7 +325,7 @@ S\bSE\bEC\bCU\bUR\bRI\bIT\bTY\bY N\bNO\bOT\bTE\bES\bS
 
 
 
-1.6.9p12                 January 14, 2008                       5
+1.6.9p14                February 19, 2008                       5
 
 
 
@@ -391,7 +391,7 @@ SUDO(1m)               MAINTENANCE COMMANDS              SUDO(1m)
 
 
 
-1.6.9p12                 January 14, 2008                       6
+1.6.9p14                February 19, 2008                       6
 
 
 
@@ -450,14 +450,14 @@ E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
                        mode
 
 F\bFI\bIL\bLE\bES\bS
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs        List of who can run what
-       _\b/_\bv_\ba_\br_\b/_\br_\bu_\bn_\b/_\bs_\bu_\bd_\bo       Directory containing timestamps
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs            List of who can run what
 
+       _\b/_\bv_\ba_\br_\b/_\br_\bu_\bn_\b/_\bs_\bu_\bd_\bo           Directory containing timestamps
 
 
 
 
-1.6.9p12                 January 14, 2008                       7
+1.6.9p14                February 19, 2008                       7
 
 
 
@@ -496,7 +496,7 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
 
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        _\bg_\br_\be_\bp(1), _\bs_\bu(1), _\bs_\bt_\ba_\bt(2), _\bl_\bo_\bg_\bi_\bn_\b__\bc_\ba_\bp(3), _\bp_\ba_\bs_\bs_\bw_\bd(4),
-       _\bs_\bu_\bd_\bo_\be_\br_\bs(4), _\bv_\bi_\bs_\bu_\bd_\bo(1m)
+       _\bs_\bu_\bd_\bo_\be_\br_\bs(5), _\bv_\bi_\bs_\bu_\bd_\bo(1m)
 
 A\bAU\bUT\bTH\bHO\bOR\bRS\bS
        Many people have worked on s\bsu\bud\bdo\bo over the years; this ver­
@@ -523,7 +523,7 @@ C\bCA\bAV\bVE\bEA\bAT\bTS\bS
 
 
 
-1.6.9p12                 January 14, 2008                       8
+1.6.9p14                February 19, 2008                       8
 
 
 
@@ -589,6 +589,6 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.6.9p12                 January 14, 2008                       9
+1.6.9p14                February 19, 2008                       9
 
 
diff --git a/sudo.h b/sudo.h
index 665deb639f4e19b4304beff74190ad30fc833e92..889cd4abc8361f93be86eaaad5fbac31d800f4af 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -17,7 +17,7 @@
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  *
- * $Sudo: sudo.h,v 1.209.2.13 2007/11/27 23:41:23 millert Exp $
+ * $Sudo: sudo.h,v 1.209.2.14 2008/02/09 14:44:48 millert Exp $
  */
 
 #ifndef _SUDO_SUDO_H
@@ -53,6 +53,10 @@ struct sudo_user {
     int ngroups;
     GETGROUPS_T *groups;
     struct list_member *env_vars;
+#ifdef HAVE_SELINUX
+    char *role;
+    char *type;
+#endif
 };
 
 /*
@@ -149,6 +153,8 @@ struct sudo_user {
 #define safe_cmnd              (sudo_user.cmnd_safe)
 #define login_class            (sudo_user.class_name)
 #define runas_pw               (sudo_user._runas_pw)
+#define user_role              (sudo_user.role)
+#define user_type              (sudo_user.type)
 
 /*
  * We used to use the system definition of PASS_MAX or _PASSWD_LEN,
@@ -262,6 +268,9 @@ char *sudo_getepw   __P((const struct passwd *));
 int pam_prep_user      __P((struct passwd *));
 void zero_bytes                __P((volatile VOID *, size_t));
 int gettime            __P((struct timespec *));
+#ifdef HAVE_SELINUX
+void selinux_exec      __P((char *, char *, char **, char **, int));
+#endif
 YY_DECL;
 
 /* Only provide extern declarations outside of sudo.c. */
index 93dd0b181773d9fb7edeca965406a2143e80b966..8d02797d743ecd0d0ae87185ce8199c7b3aaf2e3 100644 (file)
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: sudo.man.in,v 1.29.2.20 2008/01/14 12:22:57 millert Exp $
+.\" $Sudo: sudo.man.in,v 1.29.2.24 2008/03/05 13:05:05 millert Exp $
 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "SUDO @mansectsu@"
-.TH SUDO @mansectsu@ "January 14, 2008" "1.6.9p12" "MAINTENANCE COMMANDS"
+.TH SUDO @mansectsu@ "February 19, 2008" "1.6.9p14" "MAINTENANCE COMMANDS"
 .SH "NAME"
 sudo, sudoedit \- execute a command as another user
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
 \&\fBsudo\fR \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-L\fR | \fB\-l\fR | \fB\-V\fR | \fB\-v\fR
 .PP
-\&\fBsudo\fR [\fB\-bEHPS\fR] [\fB\-a\fR\ \fIauth_type\fR]
-[\fB\-c\fR\ \fIclass\fR|\fI\-\fR] [\fB\-p\fR\ \fIprompt\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
+\&\fBsudo\fR [\fB\-bEHPS\fR]
+@BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+@LCMAN@[\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+@SEMAN@[\fB\-r\fR\ \fIrole\fR] [\fB\-t\fR\ \fItype\fR]
+[\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
 [\fB\s-1VAR\s0\fR=\fIvalue\fR] {\fB\-i\fR\ |\ \fB\-s\fR\ |\ \fIcommand\fR}
 .PP
-\&\fBsudoedit\fR [\fB\-S\fR] [\fB\-a\fR\ \fIauth_type\fR] [\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
+\&\fBsudoedit\fR [\fB\-S\fR]
+@BAMAN@[\fB\-a\fR\ \fIauth_type\fR]
+@LCMAN@[\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
 [\fB\-p\fR\ \fIprompt\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
 file ...
 .SH "DESCRIPTION"
@@ -213,30 +219,30 @@ or via the \fIsudoers\fR file.
 .SH "OPTIONS"
 .IX Header "OPTIONS"
 \&\fBsudo\fR accepts the following command line options:
-.IP "\-a" 4
-.IX Item "-a"
-The \fB\-a\fR (\fIauthentication type\fR) option causes \fBsudo\fR to use the
-specified authentication type when validating the user, as allowed
-by \fI/etc/login.conf\fR.  The system administrator may specify a list
-of sudo-specific authentication methods by adding an \*(L"auth\-sudo\*(R"
-entry in \fI/etc/login.conf\fR.  This option is only available on systems
-that support \s-1BSD\s0 authentication.
+@BAMAN@.IP "\-a" 4
+@BAMAN@.IX Item "-a"
+@BAMAN@The \fB\-a\fR (\fIauthentication type\fR) option causes \fBsudo\fR to use the
+@BAMAN@specified authentication type when validating the user, as allowed
+@BAMAN@by \fI/etc/login.conf\fR.  The system administrator may specify a list
+@BAMAN@of sudo-specific authentication methods by adding an \*(L"auth\-sudo\*(R"
+@BAMAN@entry in \fI/etc/login.conf\fR.  This option is only available on systems
+@BAMAN@that support \s-1BSD\s0 authentication.
 .IP "\-b" 4
 .IX Item "-b"
 The \fB\-b\fR (\fIbackground\fR) option tells \fBsudo\fR to run the given
 command in the background.  Note that if you use the \fB\-b\fR
 option you cannot use shell job control to manipulate the process.
-.IP "\-c" 4
-.IX Item "-c"
-The \fB\-c\fR (\fIclass\fR) option causes \fBsudo\fR to run the specified command
-with resources limited by the specified login class.  The \fIclass\fR
-argument can be either a class name as defined in \f(CW\*(C`/etc/login.conf\*(C'\fR,
-or a single '\-' character.  Specifying a \fIclass\fR of \f(CW\*(C`\-\*(C'\fR indicates
-that the command should be run restricted by the default login
-capabilities for the user the command is run as.  If the \fIclass\fR
-argument specifies an existing user class, the command must be run
-as root, or the \fBsudo\fR command must be run from a shell that is already
-root.  This option is only available on systems with \s-1BSD\s0 login classes.
+@LCMAN@.IP "\-c" 4
+@LCMAN@.IX Item "-c"
+@LCMAN@The \fB\-c\fR (\fIclass\fR) option causes \fBsudo\fR to run the specified command
+@LCMAN@with resources limited by the specified login class.  The \fIclass\fR
+@LCMAN@argument can be either a class name as defined in \f(CW\*(C`/etc/login.conf\*(C'\fR,
+@LCMAN@or a single '\-' character.  Specifying a \fIclass\fR of \f(CW\*(C`\-\*(C'\fR indicates
+@LCMAN@that the command should be run restricted by the default login
+@LCMAN@capabilities for the user the command is run as.  If the \fIclass\fR
+@LCMAN@argument specifies an existing user class, the command must be run
+@LCMAN@as root, or the \fBsudo\fR command must be run from a shell that is already
+@LCMAN@root.  This option is only available on systems with \s-1BSD\s0 login classes.
 .IP "\-E" 4
 .IX Item "-E"
 The \fB\-E\fR (\fIpreserve\fR \fIenvironment\fR) option will override the
@@ -360,6 +366,10 @@ two consecutive \f(CW\*(C`%\*(C'\fR characters are collapsed into a single \f(CW
 .RE
 .RS 4
 .RE
+@SEMAN@.IP "\-r" 4
+@SEMAN@.IX Item "-r"
+@SEMAN@The \fB\-r\fR (\fIrole\fR) option causes the new (SELinux) security context to 
+@SEMAN@have the role specified by \fIrole\fR.
 .IP "\-S" 4
 .IX Item "-S"
 The \fB\-S\fR (\fIstdin\fR) option causes \fBsudo\fR to read the password from
@@ -369,6 +379,11 @@ the standard input instead of the terminal device.
 The \fB\-s\fR (\fIshell\fR) option runs the shell specified by the \fI\s-1SHELL\s0\fR
 environment variable if it is set or the shell as specified
 in \fIpasswd\fR\|(@mansectform@).
+@SEMAN@.IP "\-t" 4
+@SEMAN@.IX Item "-t"
+@SEMAN@The \fB\-t\fR (\fItype\fR) option causes the new (SELinux) security context to 
+@SEMAN@have the type specified by \fItype\fR.  If no type is specified, the default
+@SEMAN@type is derived from the specified role.
 .IP "\-u" 4
 .IX Item "-u"
 The \fB\-u\fR (\fIuser\fR) option causes \fBsudo\fR to run the specified
@@ -544,14 +559,12 @@ Set to the target user (root unless the \fB\-u\fR option is specified)
 Default editor to use in \fB\-e\fR (sudoedit) mode
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI@sysconfdir@/sudoers\fR\*(C`             \*(C'List of who can run what" 4
-.el .IP "\fI@sysconfdir@/sudoers\fR\f(CW\*(C`          \*(C'\fRList of who can run what" 4
-.IX Item "@sysconfdir@/sudoers         List of who can run what"
-.PD 0
-.ie n .IP "\fI@timedir@\fR\*(C`                \*(C'Directory containing timestamps" 4
-.el .IP "\fI@timedir@\fR\f(CW\*(C`             \*(C'\fRDirectory containing timestamps" 4
-.IX Item "@timedir@            Directory containing timestamps"
-.PD
+.IP "\fI@sysconfdir@/sudoers\fR" 24
+.IX Item "@sysconfdir@/sudoers"
+List of who can run what
+.IP "\fI@timedir@\fR" 24
+.IX Item "@timedir@"
+Directory containing timestamps
 .SH "EXAMPLES"
 .IX Header "EXAMPLES"
 Note: the following examples assume suitable \fIsudoers\fR\|(@mansectform@) entries.
@@ -590,8 +603,9 @@ to make the \f(CW\*(C`cd\*(C'\fR and file redirection work.
 .Ve
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
-\&\fIgrep\fR\|(1), \fIsu\fR\|(1), \fIstat\fR\|(2), \fIlogin_cap\fR\|(3), \fIpasswd\fR\|(@mansectform@),
-\&\fIsudoers\fR\|(@mansectform@), \fIvisudo\fR\|(@mansectsu@)
+\&\fIgrep\fR\|(1), \fIsu\fR\|(1), \fIstat\fR\|(2),
+@LCMAN@\&\fIlogin_cap\fR\|(3),
+\&\fIpasswd\fR\|(@mansectform@), \fIsudoers\fR\|(5), \fIvisudo\fR\|(@mansectsu@)
 .SH "AUTHORS"
 .IX Header "AUTHORS"
 Many people have worked on \fBsudo\fR over the years; this
index b6562b08ac3c5b4b0153151f26a2f2c32a3c99e4..33fe5d2314e45f4185d1e2cdbc1e3c8d922695a5 100644 (file)
--- a/sudo.pod
+++ b/sudo.pod
@@ -1,4 +1,3 @@
-=cut
 Copyright (c) 1994-1996, 1998-2005, 2007
        Todd C. Miller <Todd.Miller@courtesan.com>
 
@@ -19,7 +18,7 @@ Sponsored in part by the Defense Advanced Research Projects
 Agency (DARPA) and Air Force Research Laboratory, Air Force
 Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-$Sudo: sudo.pod,v 1.70.2.20 2008/01/05 23:59:42 millert Exp $
+$Sudo: sudo.pod,v 1.70.2.24 2008/02/19 18:22:11 millert Exp $
 =pod
 
 =head1 NAME
@@ -30,11 +29,17 @@ sudo, sudoedit - execute a command as another user
 
 B<sudo> B<-h> | B<-K> | B<-k> | B<-L> | B<-l> | B<-V> | B<-v>
 
-B<sudo> [B<-bEHPS>] S<[B<-a> I<auth_type>]>
-S<[B<-c> I<class>|I<->]> S<[B<-p> I<prompt>]> S<[B<-u> I<username>|I<#uid>]>
+B<sudo> [B<-bEHPS>]
+S<[B<-a> I<auth_type>]>
+S<[B<-c> I<class>|I<->]>
+S<[B<-p> I<prompt>]>
+S<[B<-r> I<role>]> S<[B<-t> I<type>]>
+S<[B<-u> I<username>|I<#uid>]>
 S<[B<VAR>=I<value>]> S<{B<-i> | B<-s> | I<command>}>
 
-B<sudoedit> [B<-S>] S<[B<-a> I<auth_type>]> S<[B<-c> I<class>|I<->]>
+B<sudoedit> [B<-S>]
+S<[B<-a> I<auth_type>]>
+S<[B<-c> I<class>|I<->]>
 S<[B<-p> I<prompt>]> S<[B<-u> I<username>|I<#uid>]>
 file ...
 
@@ -258,6 +263,11 @@ two consecutive C<%> characters are collapsed into a single C<%> character
 
 =back
 
+=item -r
+
+The B<-r> (I<role>) option causes the new (SELinux) security context to 
+have the role specified by I<role>.
+
 =item -S
 
 The B<-S> (I<stdin>) option causes B<sudo> to read the password from
@@ -269,6 +279,12 @@ The B<-s> (I<shell>) option runs the shell specified by the I<SHELL>
 environment variable if it is set or the shell as specified
 in L<passwd(5)>.
 
+=item -t
+
+The B<-t> (I<type>) option causes the new (SELinux) security context to 
+have the type specified by I<type>.  If no type is specified, the default
+type is derived from the specified role.
+
 =item -u
 
 The B<-u> (I<user>) option causes B<sudo> to run the specified
@@ -458,11 +474,15 @@ Default editor to use in B<-e> (sudoedit) mode
 
 =head1 FILES
 
-=over 4
+=over 24
+
+=item F<@sysconfdir@/sudoers>
+
+List of who can run what
 
-=item F<@sysconfdir@/sudoers>C<                >List of who can run what
+=item F<@timedir@>
 
-=item F<@timedir@>C<           >Directory containing timestamps
+Directory containing timestamps
 
 =back
 
@@ -495,8 +515,9 @@ to make the C<cd> and file redirection work.
 
 =head1 SEE ALSO
 
-L<grep(1)>, L<su(1)>, L<stat(2)>, L<login_cap(3)>, L<passwd(5)>,
-L<sudoers(5)>, L<visudo(8)>
+L<grep(1)>, L<su(1)>, L<stat(2)>,
+L<login_cap(3)>,
+L<passwd(5)>, L<sudoers(5)>, L<visudo(8)>
 
 =head1 AUTHORS
 
index 46b2529aca2957be18bf92c3dd72f4e891982dfa..0e40bef7e4850929382fe615a21077022a5c3864 100644 (file)
@@ -88,7 +88,7 @@ static char yyrcsid[]
 #endif /* HAVE_LSEARCH */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.76.2.11 2008/01/16 23:20:54 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.76.2.14 2008/02/27 20:34:42 millert Exp $";
 #endif /* lint */
 
 /*
@@ -158,6 +158,8 @@ int top = 0, stacksize = 0;
        match[top].nopass = def_authenticate ? UNSPEC : TRUE; \
        match[top].noexec = def_noexec ? TRUE : UNSPEC; \
        match[top].setenv = def_setenv ? TRUE : UNSPEC; \
+       match[top].role = NULL; \
+       match[top].type = NULL; \
        top++; \
     } while (0)
 
@@ -174,6 +176,8 @@ int top = 0, stacksize = 0;
        match[top].nopass = match[top-1].nopass; \
        match[top].noexec = match[top-1].noexec; \
        match[top].setenv = match[top-1].setenv; \
+       match[top].role   = estrdup(match[top-1].role); \
+       match[top].type   = estrdup(match[top-1].type); \
        top++; \
     } while (0)
 
@@ -181,8 +185,11 @@ int top = 0, stacksize = 0;
     do { \
        if (top == 0) \
            yyerror("matching stack underflow"); \
-       else \
+       else { \
+           efree(match[top-1].role); \
+           efree(match[top-1].type); \
            top--; \
+       } \
     } while (0)
 
 
@@ -200,6 +207,12 @@ int top = 0, stacksize = 0;
 #define append_runas(s, p) append(s, &cm_list[cm_list_len].runas, \
        &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, p)
 
+#define append_role(s, p) append(s, &cm_list[cm_list_len].role, \
+       &cm_list[cm_list_len].role_len, &cm_list[cm_list_len].role_size, p)
+
+#define append_type(s, p) append(s, &cm_list[cm_list_len].type, \
+       &cm_list[cm_list_len].type_len, &cm_list[cm_list_len].type_size, p)
+
 #define append_entries(s, p) append(s, &ga_list[ga_list_len-1].entries, \
        &ga_list[ga_list_len-1].entries_len, \
        &ga_list[ga_list_len-1].entries_size, p)
@@ -251,7 +264,7 @@ yyerror(s)
     }
     parse_error = TRUE;
 }
-#line 238 "parse.yacc"
+#line 251 "parse.yacc"
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
@@ -259,9 +272,10 @@ typedef union {
     int BOOLEAN;
     struct sudo_command command;
     int tok;
+    struct selinux_info seinfo;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
-#line 265 "sudo.tab.c"
+#line 279 "sudo.tab.c"
 #define COMMAND 257
 #define ALIAS 258
 #define DEFVAR 259
@@ -287,6 +301,8 @@ typedef union {
 #define USERALIAS 279
 #define RUNASALIAS 280
 #define ERROR 281
+#define TYPE 282
+#define ROLE 283
 #define YYERRCODE 256
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylhs[] =
@@ -294,16 +310,17 @@ const short yylhs[] =
 short yylhs[] =
 #endif
        {                                        -1,
-    0,    0,    7,    7,    9,    7,    7,    7,    7,    7,
-    7,   15,   16,   18,   16,   19,   16,   21,   16,   17,
-   17,   22,   22,   22,   22,   22,   10,   10,   23,   25,
-   25,    2,    2,    2,    2,    2,   24,   24,   28,   26,
-   30,   31,   30,   27,   27,    5,    5,    4,   32,    4,
-    3,    3,    3,    3,    3,   29,   29,   29,   29,   29,
-   29,   29,    1,    1,    1,   12,   12,   34,   33,   20,
-   20,   13,   13,   36,   35,   37,   37,   14,   14,   39,
-   38,   11,   11,   41,   40,    8,    8,   42,   42,    6,
-    6,    6,    6,    6,
+    0,    0,   10,   10,   12,   10,   10,   10,   10,   10,
+   10,   18,   19,   21,   19,   22,   19,   24,   19,   20,
+   20,   25,   25,   25,   25,   25,   13,   13,   26,   28,
+   28,    2,    2,    2,    2,    2,   27,   27,   31,   29,
+   33,   34,   33,    8,    9,    7,    7,    7,    7,    7,
+   30,   30,    5,    5,    4,   35,    4,    3,    3,    3,
+    3,    3,   32,   32,   32,   32,   32,   32,   32,    1,
+    1,    1,   15,   15,   37,   36,   23,   23,   16,   16,
+   39,   38,   40,   40,   17,   17,   42,   41,   14,   14,
+   44,   43,   11,   11,   45,   45,    6,    6,    6,    6,
+    6,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylen[] =
@@ -314,13 +331,14 @@ short yylen[] =
     1,    2,    1,    2,    0,    3,    2,    2,    2,    2,
     1,    2,    1,    0,    3,    0,    3,    0,    3,    1,
     3,    1,    2,    3,    3,    3,    1,    3,    3,    1,
-    2,    1,    1,    1,    1,    1,    1,    3,    0,    4,
-    1,    0,    3,    0,    2,    1,    3,    1,    0,    3,
-    1,    1,    1,    1,    1,    0,    2,    2,    2,    2,
-    2,    2,    1,    1,    1,    1,    3,    0,    4,    1,
-    3,    1,    3,    0,    4,    1,    3,    1,    3,    0,
-    4,    1,    3,    0,    4,    1,    3,    1,    2,    1,
-    1,    1,    1,    1,
+    2,    1,    1,    1,    1,    1,    1,    3,    0,    5,
+    1,    0,    3,    3,    3,    0,    1,    1,    2,    2,
+    0,    2,    1,    3,    1,    0,    3,    1,    1,    1,
+    1,    1,    0,    2,    2,    2,    2,    2,    2,    1,
+    1,    1,    1,    3,    0,    4,    1,    3,    1,    3,
+    0,    4,    1,    3,    1,    3,    0,    4,    1,    3,
+    0,    4,    1,    3,    1,    2,    1,    1,    1,    1,
+    1,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydefred[] =
@@ -329,19 +347,20 @@ short yydefred[] =
 #endif
        {                                      0,
     0,   13,   18,   14,   16,    3,    0,    0,    0,    0,
-    0,    1,    0,   11,    0,    4,    0,    0,    0,   68,
-    0,   66,   74,    0,   72,   84,    0,   82,   80,    0,
-   78,    2,   93,   92,   91,   90,   94,    0,   88,    0,
-   86,    0,    0,   12,    0,   36,   33,   34,   35,   32,
-    0,   30,    0,   70,    0,   54,   53,   52,   51,   55,
-   49,   48,   46,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   89,    0,    0,    0,   27,    0,    0,    0,
-   23,    0,   31,    0,    0,    0,    0,   67,    0,   73,
-    0,   83,    0,   79,   87,    0,   39,   24,   25,   26,
-   21,   71,   50,   47,    0,   65,   64,   63,   42,   41,
-   76,    0,    0,    0,   28,    0,   37,    0,    0,    0,
-   39,    0,   56,   43,   77,   38,    0,    0,   57,   58,
-   59,   60,   61,   62,   40,
+    0,    1,    0,   11,    0,    4,    0,    0,    0,   75,
+    0,   73,   81,    0,   79,   91,    0,   89,   87,    0,
+   85,    2,  100,   99,   98,   97,  101,    0,   95,    0,
+   93,    0,    0,   12,    0,   36,   33,   34,   35,   32,
+    0,   30,    0,   77,    0,   61,   60,   59,   58,   62,
+   56,   55,   53,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   96,    0,    0,    0,   27,    0,    0,    0,
+   23,    0,   31,    0,    0,    0,    0,   74,    0,   80,
+    0,   90,    0,   86,   94,    0,   39,   24,   25,   26,
+   21,   78,   57,   54,    0,   72,   71,   70,   42,   41,
+   83,    0,    0,    0,   28,    0,   37,    0,    0,    0,
+   39,    0,    0,   43,   84,   38,    0,    0,    0,   63,
+    0,    0,    0,    0,    0,   49,   50,   45,   44,   64,
+   65,   66,   67,   68,   69,   40,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydgoto[] =
@@ -349,114 +368,116 @@ const short yydgoto[] =
 short yydgoto[] =
 #endif
        {                                      11,
-  110,   52,   62,   63,   64,   39,   12,   40,   13,   75,
-   27,   21,   24,   30,   14,   15,   44,   18,   19,   76,
-   17,   45,   77,  116,   54,  117,  123,  118,  128,  111,
-  119,   85,   22,   65,   25,   67,  112,   31,   71,   28,
-   69,   41,
+  110,   52,   62,   63,   64,   39,  130,  131,  132,   12,
+   40,   13,   75,   27,   21,   24,   30,   14,   15,   44,
+   18,   19,   76,   17,   45,   77,  116,   54,  117,  123,
+  118,  135,  111,  119,   85,   22,   65,   25,   67,  112,
+   31,   71,   28,   69,   41,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yysindex[] =
 #else
 short yysindex[] =
 #endif
-       {                                   -223,
- -256,    0,    0,    0,    0,    0, -237, -234, -231, -226,
- -223,    0,   62,    0,  -33,    0,   88,   62,  114,    0,
-  -22,    0,    0,  -21,    0,    0,  -19,    0,    0,  -18,
-    0,    0,    0,    0,    0,    0,    0, -244,    0,  -28,
-    0,  -36, -221,    0,    3,    0,    0,    0,    0,    0,
- -212,    0,    6,    0,   14,    0,    0,    0,    0,    0,
-    0,    0,    0,   16,    7, -237,    8, -234,    9, -231,
-   10, -226,    0,   62,   18,  -32,    0, -202, -199, -191,
-    0,  -33,    0,   88, -196,  114,   88,    0,  276,    0,
-   62,    0,  114,    0,    0,   88,    0,    0,    0,    0,
-    0,    0,    0,    0,    6,    0,    0,    0,    0,    0,
-    0,   30,   14,   16,    0,   33,    0, -188, -247,  276,
-    0,  114,    0,    0,    0,    0,   16,  -29,    0,    0,
-    0,    0,    0,    0,    0,};
+       {                                   -247,
+ -248,    0,    0,    0,    0,    0, -211, -210, -205, -201,
+ -247,    0,   62,    0,  -33,    0,   89,   62,  114,    0,
+    2,    0,    0,    3,    0,    0,    4,    0,    0,    6,
+    0,    0,    0,    0,    0,    0,    0, -251,    0,  -28,
+    0,  -18, -194,    0,   14,    0,    0,    0,    0,    0,
+ -219,    0,   22,    0,   23,    0,    0,    0,    0,    0,
+    0,    0,    0,   24,    8, -211,    9, -210,   10, -205,
+   11, -201,    0,   62,   16,  -23,    0, -187, -186, -184,
+    0,  -33,    0,   89, -212,  114,   89,    0,  -20,    0,
+   62,    0,  114,    0,    0,   89,    0,    0,    0,    0,
+    0,    0,    0,    0,   22,    0,    0,    0,    0,    0,
+    0,   36,   23,   24,    0,   37,    0, -185, -221,  -20,
+    0,  114, -268,    0,    0,    0,   24,   21,   25,    0,
+ -195, -193, -175, -174,  274,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yyrindex[] =
 #else
 short yyrindex[] =
 #endif
-       {                                    140,
+       {                                    141,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-  140,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  141,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   156,    0,    0,  181,    0,    0,  206,    0,    0,  236,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    1,    0,    0,  261,    0,    0,    0,    0,    0,
     0,    0,  -25,    0,  -11,    0,    0,    0,    0,    0,
-    0,    0,    0,   -3,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  -10,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,  300,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,   26,    0,    0,    0,    0,    0,
-    0,   52,   78,  104,    0,  130,    0,  -20,    0,    0,
-    0,    0,    0,    0,    0,    0,  274,    0,    0,    0,
-    0,    0,    0,    0,    0,};
+    0,   52,   78,  104,    0,  130,    0,  -29,    0,    0,
+    0,    0,  340,    0,    0,    0,  313,    0,    0,    0,
+  365,  391,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yygindex[] =
 #else
 short yygindex[] =
 #endif
        {                                      0,
-  -38,   31,   -2,    2,  -87,   48,   76,  -16,    0,    0,
-    0,    0,    0,    0,    0,    0,   11,    0,    0,  -14,
-    0,    0,   -7,    0,   12,  -31,    0,    0,    0, -105,
-    0,    0,   25,    0,   24,    0,    0,   22,    0,   27,
-    0,   28,
+  -27,   40,   12,    7,  -87,   56,    0,  -36,  -32,   87,
+  -16,    0,    0,    0,    0,    0,    0,    0,    0,   18,
+    0,    0,  -14,    0,    0,    5,    0,   19,  -19,    0,
+    0,    0,  -80,    0,    0,   39,    0,   38,    0,    0,
+   35,    0,   42,    0,   34,
 };
-#define YYTABLESIZE 580
+#define YYTABLESIZE 666
 #if defined(__cplusplus) || defined(__STDC__)
 const short yytable[] =
 #else
 short yytable[] =
 #endif
        {                                      43,
-   22,   55,   53,  109,   51,  114,   79,   19,   80,  106,
-  107,   84,   44,   33,  125,   74,   34,   35,   36,   16,
-   20,   15,  135,   23,   78,   69,   26,  108,   97,   17,
-   37,   29,    1,   22,  127,   66,   68,   81,   70,   72,
-    2,    3,    4,    5,   22,   46,   82,   47,   48,   84,
-   49,   75,    6,    7,    8,    9,   10,   74,   69,   86,
-   98,   56,   50,   99,   57,   58,   59,   87,   89,   91,
-   93,  100,  105,  120,  113,   96,  121,   85,   60,  122,
-  124,   83,  103,   69,   75,   73,   32,  104,  115,  126,
-   88,   90,  101,   94,   38,  102,   92,    0,    0,    0,
-    0,   95,    0,   81,    0,    0,    0,    0,    0,   75,
-   85,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-   51,    0,    0,    0,    0,    0,    0,    0,    0,   29,
-    0,    0,    0,    0,    0,   85,   81,    0,    0,    0,
+   22,   55,   53,   51,   51,  114,   33,   19,    1,   34,
+   35,   36,  109,  128,  129,   74,    2,    3,    4,    5,
+   84,   15,   17,   37,   79,   76,   80,   16,    6,    7,
+    8,    9,   10,   22,  127,  106,  107,   97,   46,  125,
+   47,   48,   78,   49,   22,   56,   20,   23,   57,   58,
+   59,   82,   26,  108,  146,   50,   29,   82,   76,   66,
+   68,   70,   60,   72,   81,   84,   74,   86,   87,   89,
+   91,   93,  105,   96,  113,   98,   99,   92,  100,  120,
+  121,  133,  122,   76,   82,  134,  128,  138,  139,  129,
+   83,  124,  104,   73,   38,  137,  103,   32,  136,  101,
+  115,  126,  102,   88,   88,   90,   94,   95,    0,   82,
+   92,   92,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   51,    0,    0,    0,    0,    0,    0,    0,   29,
+    0,    0,    0,    0,    0,   92,   88,    0,    0,    0,
     0,    0,    0,    0,    0,    0,   61,    0,    0,    0,
     0,    0,    0,    0,    0,    8,    0,    0,    0,    0,
-    0,   81,   29,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    5,    0,    0,    0,    0,    0,    0,    0,
+    0,   88,   29,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    5,    0,    0,    0,    0,    0,    0,
     9,    0,    0,    0,    0,    0,    0,   29,    8,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
     0,    0,    0,    9,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   42,    0,  106,  107,   46,
-    0,   47,   48,   19,   49,   10,   44,   44,    7,  129,
-  130,  131,  132,  133,  134,  108,   50,   15,   44,   44,
-   44,   44,   44,   44,   44,   17,   22,    0,   22,    0,
+    0,    0,    0,    0,    0,   42,    0,   51,   51,   46,
+    0,   47,   48,   19,   49,   10,  106,  107,    7,   51,
+   51,   51,   51,   51,   51,   51,   50,   15,   17,    0,
+    0,    0,   51,   51,  108,    0,   22,    0,   22,    0,
    20,   22,   22,   22,   22,   22,   22,   22,   10,    0,
     0,    0,    0,    0,    0,   22,   22,   22,   22,   22,
-   22,   69,    0,   69,    0,    0,   69,   69,   69,   69,
-   69,   69,   69,   20,    0,    0,    0,    0,    0,    6,
-   69,   69,   69,   69,   69,   69,   45,   75,  109,   75,
-    0,    0,   75,   75,   75,   75,   75,   75,   75,   33,
-    0,    0,   34,   35,   36,    0,   75,   75,   75,   75,
-   75,   75,    6,   85,    0,   85,   37,    0,   85,   85,
-   85,   85,   85,   85,   85,   46,    0,   47,   48,    0,
-   49,    0,   85,   85,   85,   85,   85,   85,    0,   81,
-    0,   81,   50,    0,   81,   81,   81,   81,   81,   81,
-   81,   56,    0,    0,   57,   58,   59,    0,   81,   81,
-   81,   81,   81,   81,    0,   29,    0,   29,   60,    0,
-   29,   29,   29,   29,   29,   29,   29,    5,    0,    0,
-    5,    5,    5,    0,   29,   29,   29,   29,   29,   29,
-    0,    8,    0,    8,    5,    0,    8,    8,    8,    8,
-    8,    8,    8,    0,    0,    0,    0,    0,    0,    0,
+   22,   76,    0,   76,    0,    0,   76,   76,   76,   76,
+   76,   76,   76,   20,    0,    0,    0,    0,    0,    6,
+   76,   76,   76,   76,   76,   76,  109,   82,    0,   82,
+    0,    0,   82,   82,   82,   82,   82,   82,   82,   33,
+    0,    0,   34,   35,   36,    0,   82,   82,   82,   82,
+   82,   82,    6,   92,    0,   92,   37,    0,   92,   92,
+   92,   92,   92,   92,   92,   52,   46,    0,   47,   48,
+    0,   49,   92,   92,   92,   92,   92,   92,    0,   88,
+    0,   88,    0,   50,   88,   88,   88,   88,   88,   88,
+   88,   56,   46,    0,   57,   58,   59,    0,   88,   88,
+   88,   88,   88,   88,    0,   29,    0,   29,   60,    0,
+   29,   29,   29,   29,   29,   29,   29,   47,    5,    0,
+    0,    5,    5,    5,   29,   29,   29,   29,   29,   29,
+    0,    8,    0,    8,    0,    5,    8,    8,    8,    8,
+    8,    8,    8,   48,    0,    0,    0,    0,    0,    0,
     8,    8,    8,    8,    8,    8,    9,    0,    9,    0,
     0,    9,    9,    9,    9,    9,    9,    9,    0,    0,
     0,    0,    0,    0,    0,    9,    9,    9,    9,    9,
@@ -467,11 +488,20 @@ short yytable[] =
    10,   10,   10,    0,    0,    0,    0,    0,    0,    0,
    10,   10,   10,   10,   10,   10,   20,    0,   20,    0,
     0,   20,   20,   20,   20,   20,   20,   20,    0,    0,
-   45,   45,  106,  107,    0,   20,   20,   20,   20,   20,
-   20,    0,   45,   45,   45,   45,   45,   45,   45,    0,
-  108,    0,    0,    0,    0,    6,    0,    6,    0,    0,
-    6,    6,    6,    6,    6,    6,    6,    0,    0,    0,
-    0,    0,    0,    0,    6,    6,    6,    6,    6,    6,
+  106,  107,    0,    0,    0,   20,   20,   20,   20,   20,
+   20,    0,  140,  141,  142,  143,  144,  145,  108,    0,
+    0,    0,    0,    0,    0,    6,    0,    6,    0,    0,
+    6,    6,    6,    6,    6,    6,    6,    0,    0,   52,
+   52,    0,    0,    0,    6,    6,    6,    6,    6,    6,
+    0,   52,   52,   52,   52,   52,   52,   52,    0,    0,
+    0,    0,    0,    0,   52,   52,   46,   46,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,   46,   46,
+   46,   46,   46,   46,   46,    0,    0,    0,    0,    0,
+    0,   47,   47,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   47,   47,   47,   47,   47,   47,   47,
+    0,    0,    0,    0,    0,    0,    0,   48,   48,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,   48,
+   48,   48,   48,   48,   48,   48,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yycheck[] =
@@ -479,49 +509,49 @@ const short yycheck[] =
 short yycheck[] =
 #endif
        {                                      33,
-    0,   18,   17,   33,   33,   93,   43,   33,   45,  257,
-  258,   44,   33,  258,  120,   44,  261,  262,  263,  276,
-  258,   33,  128,  258,   61,    0,  258,  275,   61,   33,
-  275,  258,  256,   33,  122,   58,   58,  259,   58,   58,
-  264,  265,  266,  267,   44,  258,   44,  260,  261,   44,
-  263,    0,  276,  277,  278,  279,  280,   44,   33,   44,
-  263,  258,  275,  263,  261,  262,  263,   61,   61,   61,
-   61,  263,   87,   44,   91,   58,   44,    0,  275,  268,
-  119,   51,   85,   58,   33,   38,   11,   86,   96,  121,
-   66,   68,   82,   72,   33,   84,   70,   -1,   -1,   -1,
-   -1,   74,   -1,    0,   -1,   -1,   -1,   -1,   -1,   58,
-   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,
+    0,   18,   17,   33,   33,   93,  258,   33,  256,  261,
+  262,  263,   33,  282,  283,   44,  264,  265,  266,  267,
+   44,   33,   33,  275,   43,    0,   45,  276,  276,  277,
+  278,  279,  280,   33,  122,  257,  258,   61,  258,  120,
+  260,  261,   61,  263,   44,  258,  258,  258,  261,  262,
+  263,    0,  258,  275,  135,  275,  258,   44,   33,   58,
+   58,   58,  275,   58,  259,   44,   44,   44,   61,   61,
+   61,   61,   87,   58,   91,  263,  263,    0,  263,   44,
+   44,   61,  268,   58,   33,   61,  282,  263,  263,  283,
+   51,  119,   86,   38,   33,  132,   85,   11,  131,   82,
+   96,  121,   84,    0,   66,   68,   72,   74,   -1,   58,
+   33,   70,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,
    -1,   -1,   -1,   -1,   -1,   58,   33,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
    -1,   58,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
     0,   -1,   -1,   -1,   -1,   -1,   -1,   58,   33,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,  259,   -1,  257,  258,  258,
    -1,  260,  261,  259,  263,    0,  257,  258,   33,  269,
-  270,  271,  272,  273,  274,  275,  275,  259,  269,  270,
-  271,  272,  273,  274,  275,  259,  256,   -1,  258,   -1,
+  270,  271,  272,  273,  274,  275,  275,  259,  259,   -1,
+   -1,   -1,  282,  283,  275,   -1,  256,   -1,  258,   -1,
     0,  261,  262,  263,  264,  265,  266,  267,   33,   -1,
    -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
   280,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
   265,  266,  267,   33,   -1,   -1,   -1,   -1,   -1,    0,
-  275,  276,  277,  278,  279,  280,   33,  256,   33,  258,
+  275,  276,  277,  278,  279,  280,   33,  256,   -1,  258,
    -1,   -1,  261,  262,  263,  264,  265,  266,  267,  258,
    -1,   -1,  261,  262,  263,   -1,  275,  276,  277,  278,
   279,  280,   33,  256,   -1,  258,  275,   -1,  261,  262,
-  263,  264,  265,  266,  267,  258,   -1,  260,  261,   -1,
-  263,   -1,  275,  276,  277,  278,  279,  280,   -1,  256,
-   -1,  258,  275,   -1,  261,  262,  263,  264,  265,  266,
-  267,  258,   -1,   -1,  261,  262,  263,   -1,  275,  276,
+  263,  264,  265,  266,  267,   33,  258,   -1,  260,  261,
+   -1,  263,  275,  276,  277,  278,  279,  280,   -1,  256,
+   -1,  258,   -1,  275,  261,  262,  263,  264,  265,  266,
+  267,  258,   33,   -1,  261,  262,  263,   -1,  275,  276,
   277,  278,  279,  280,   -1,  256,   -1,  258,  275,   -1,
-  261,  262,  263,  264,  265,  266,  267,  258,   -1,   -1,
-  261,  262,  263,   -1,  275,  276,  277,  278,  279,  280,
-   -1,  256,   -1,  258,  275,   -1,  261,  262,  263,  264,
-  265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  261,  262,  263,  264,  265,  266,  267,   33,  258,   -1,
+   -1,  261,  262,  263,  275,  276,  277,  278,  279,  280,
+   -1,  256,   -1,  258,   -1,  275,  261,  262,  263,  264,
+  265,  266,  267,   33,   -1,   -1,   -1,   -1,   -1,   -1,
   275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
    -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
@@ -532,17 +562,26 @@ short yycheck[] =
   265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
    -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
-  257,  258,  257,  258,   -1,  275,  276,  277,  278,  279,
+  257,  258,   -1,   -1,   -1,  275,  276,  277,  278,  279,
   280,   -1,  269,  270,  271,  272,  273,  274,  275,   -1,
-  275,   -1,   -1,   -1,   -1,  256,   -1,  258,   -1,   -1,
-  261,  262,  263,  264,  265,  266,  267,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,  280,
+   -1,   -1,   -1,   -1,   -1,  256,   -1,  258,   -1,   -1,
+  261,  262,  263,  264,  265,  266,  267,   -1,   -1,  257,
+  258,   -1,   -1,   -1,  275,  276,  277,  278,  279,  280,
+   -1,  269,  270,  271,  272,  273,  274,  275,   -1,   -1,
+   -1,   -1,   -1,   -1,  282,  283,  257,  258,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  269,  270,
+  271,  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,
+   -1,  257,  258,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  269,  270,  271,  272,  273,  274,  275,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  257,  258,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  269,
+  270,  271,  272,  273,  274,  275,
 };
 #define YYFINAL 11
 #ifndef YYDEBUG
 #define YYDEBUG 0
 #endif
-#define YYMAXTOKEN 281
+#define YYMAXTOKEN 283
 #if YYDEBUG
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyname[] =
@@ -560,7 +599,7 @@ char *yyname[] =
 "COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
 "DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","RUNAS","NOPASSWD","PASSWD",
 "NOEXEC","EXEC","SETENV","NOSETENV","ALL","COMMENT","HOSTALIAS","CMNDALIAS",
-"USERALIAS","RUNASALIAS","ERROR",
+"USERALIAS","RUNASALIAS","ERROR","TYPE","ROLE",
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyrule[] =
@@ -607,10 +646,17 @@ char *yyrule[] =
 "cmndspeclist : cmndspec",
 "cmndspeclist : cmndspeclist ',' cmndspec",
 "$$5 :",
-"cmndspec : $$5 runasspec cmndtag opcmnd",
+"cmndspec : $$5 runasspec selinux cmndtag opcmnd",
 "opcmnd : cmnd",
 "$$6 :",
 "opcmnd : '!' $$6 cmnd",
+"rolespec : ROLE '=' WORD",
+"typespec : TYPE '=' WORD",
+"selinux :",
+"selinux : rolespec",
+"selinux : typespec",
+"selinux : rolespec typespec",
+"selinux : typespec rolespec",
 "runasspec :",
 "runasspec : RUNAS runaslist",
 "runaslist : oprunasuser",
@@ -689,7 +735,7 @@ short *yyss;
 short *yysslim;
 YYSTYPE *yyvs;
 int yystacksize;
-#line 925 "parse.yacc"
+#line 1053 "parse.yacc"
 
 #define MOREALIASES (32)
 aliasinfo *aliases = NULL;
@@ -870,6 +916,14 @@ list_matches()
            (void) printf("(%s) ", def_runas_default);
        }
 
+#ifdef HAVE_SELINUX
+       /* SELinux role and type */
+       if (cm_list[count].role != NULL)
+           (void) printf("ROLE=%s ", cm_list[count].role);
+       if (cm_list[count].type != NULL)
+           (void) printf("TYPE=%s ", cm_list[count].type);
+#endif
+
        /* Is execve(2) disabled? */
        if (cm_list[count].noexecve == TRUE && !def_noexec)
            (void) fputs("NOEXEC: ", stdout);
@@ -909,6 +963,8 @@ list_matches()
     for (count = 0; count < cm_list_len; count++) {
        efree(cm_list[count].runas);
        efree(cm_list[count].cmnd);
+       efree(cm_list[count].role);
+       efree(cm_list[count].type);
     }
     efree(cm_list);
     cm_list = NULL;
@@ -1013,6 +1069,7 @@ expand_match_list()
     }
 
     cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
+    cm_list[cm_list_len].type = cm_list[cm_list_len].role = NULL;
     cm_list[cm_list_len].nopasswd = FALSE;
     cm_list[cm_list_len].noexecve = FALSE;
     cm_list[cm_list_len].setenv = FALSE;
@@ -1045,7 +1102,7 @@ init_parser()
     if (printmatches == TRUE)
        expand_match_list();
 }
-#line 997 "sudo.tab.c"
+#line 1054 "sudo.tab.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1248,85 +1305,85 @@ yyreduce:
     switch (yyn)
     {
 case 3:
-#line 294 "parse.yacc"
+#line 313 "parse.yacc"
 { ; }
 break;
 case 4:
-#line 296 "parse.yacc"
+#line 315 "parse.yacc"
 { yyerrok; }
 break;
 case 5:
-#line 297 "parse.yacc"
+#line 316 "parse.yacc"
 { push; }
 break;
 case 6:
-#line 297 "parse.yacc"
+#line 316 "parse.yacc"
 {
                            while (top && user_matches != TRUE)
                                pop;
                        }
 break;
 case 7:
-#line 302 "parse.yacc"
+#line 321 "parse.yacc"
 { ; }
 break;
 case 8:
-#line 304 "parse.yacc"
+#line 323 "parse.yacc"
 { ; }
 break;
 case 9:
-#line 306 "parse.yacc"
+#line 325 "parse.yacc"
 { ; }
 break;
 case 10:
-#line 308 "parse.yacc"
+#line 327 "parse.yacc"
 { ; }
 break;
 case 11:
-#line 310 "parse.yacc"
+#line 329 "parse.yacc"
 { ; }
 break;
 case 13:
-#line 316 "parse.yacc"
+#line 335 "parse.yacc"
 {
                            defaults_matches = TRUE;
                        }
 break;
 case 14:
-#line 319 "parse.yacc"
+#line 338 "parse.yacc"
 { push; }
 break;
 case 15:
-#line 319 "parse.yacc"
+#line 338 "parse.yacc"
 {
                            defaults_matches = user_matches;
                            pop;
                        }
 break;
 case 16:
-#line 323 "parse.yacc"
+#line 342 "parse.yacc"
 { push; }
 break;
 case 17:
-#line 323 "parse.yacc"
+#line 342 "parse.yacc"
 {
                            defaults_matches = yyvsp[0].BOOLEAN == TRUE;
                            pop;
                        }
 break;
 case 18:
-#line 327 "parse.yacc"
+#line 346 "parse.yacc"
 { push; }
 break;
 case 19:
-#line 327 "parse.yacc"
+#line 346 "parse.yacc"
 {
                            defaults_matches = host_matches;
                            pop;
                        }
 break;
 case 22:
-#line 337 "parse.yacc"
+#line 356 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[0].string, NULL, TRUE)) {
@@ -1337,7 +1394,7 @@ case 22:
                        }
 break;
 case 23:
-#line 345 "parse.yacc"
+#line 364 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[0].string, NULL, FALSE)) {
@@ -1348,7 +1405,7 @@ case 23:
                        }
 break;
 case 24:
-#line 353 "parse.yacc"
+#line 372 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, TRUE)) {
@@ -1360,7 +1417,7 @@ case 24:
                        }
 break;
 case 25:
-#line 362 "parse.yacc"
+#line 381 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, '+')) {
@@ -1372,7 +1429,7 @@ case 25:
                        }
 break;
 case 26:
-#line 371 "parse.yacc"
+#line 390 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, '-')) {
@@ -1384,7 +1441,7 @@ case 26:
                        }
 break;
 case 29:
-#line 386 "parse.yacc"
+#line 405 "parse.yacc"
 {
                            /*
                             * We already did a push if necessary in
@@ -1396,28 +1453,34 @@ case 29:
                            no_passwd = def_authenticate ? UNSPEC : TRUE;
                            no_execve = def_noexec ? TRUE : UNSPEC;
                            setenv_ok = def_setenv ? TRUE : UNSPEC;
+#ifdef HAVE_SELINUX
+                           efree(match[top-1].role);
+                           match[top-1].role = NULL;
+                           efree(match[top-1].type);
+                           match[top-1].type = NULL;
+#endif
                        }
 break;
 case 30:
-#line 400 "parse.yacc"
+#line 425 "parse.yacc"
 {
                            SETMATCH(host_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 31:
-#line 403 "parse.yacc"
+#line 428 "parse.yacc"
 {
                            SETNMATCH(host_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 32:
-#line 408 "parse.yacc"
+#line 433 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
 break;
 case 33:
-#line 411 "parse.yacc"
+#line 436 "parse.yacc"
 {
                            if (addr_matches(yyvsp[0].string))
                                yyval.BOOLEAN = TRUE;
@@ -1427,7 +1490,7 @@ case 33:
                        }
 break;
 case 34:
-#line 418 "parse.yacc"
+#line 443 "parse.yacc"
 {
                            if (netgr_matches(yyvsp[0].string, user_host, user_shost, NULL))
                                yyval.BOOLEAN = TRUE;
@@ -1437,7 +1500,7 @@ case 34:
                        }
 break;
 case 35:
-#line 425 "parse.yacc"
+#line 450 "parse.yacc"
 {
                            if (hostname_matches(user_shost, user_host, yyvsp[0].string) == 0)
                                yyval.BOOLEAN = TRUE;
@@ -1447,7 +1510,7 @@ case 35:
                        }
 break;
 case 36:
-#line 432 "parse.yacc"
+#line 457 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, HOST_ALIAS);
 
@@ -1472,12 +1535,23 @@ case 36:
                        }
 break;
 case 39:
-#line 460 "parse.yacc"
+#line 485 "parse.yacc"
 { SETENV_RESET; }
 break;
 case 40:
-#line 460 "parse.yacc"
+#line 485 "parse.yacc"
 {
+#ifdef HAVE_SELINUX
+                           /* Replace inherited role/type as needed. */
+                           if (yyvsp[-2].seinfo.role != NULL) {
+                               efree(match[top-1].role);
+                               match[top-1].role = yyvsp[-2].seinfo.role;
+                           }
+                           if (yyvsp[-2].seinfo.type != NULL) {
+                               efree(match[top-1].type);
+                               match[top-1].type = yyvsp[-2].seinfo.type;
+                           }
+#endif
                            /*
                             * Push the entry onto the stack if it is worth
                             * saving and reset cmnd_matches for next cmnd.
@@ -1502,17 +1576,18 @@ case 40:
                                pushcp;
                            else if (user_matches == TRUE && keepall)
                                pushcp;
+
                            cmnd_matches = UNSPEC;
                        }
 break;
 case 41:
-#line 489 "parse.yacc"
+#line 526 "parse.yacc"
 {
                            SETMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 42:
-#line 492 "parse.yacc"
+#line 529 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1524,13 +1599,119 @@ case 42:
                        }
 break;
 case 43:
-#line 500 "parse.yacc"
+#line 537 "parse.yacc"
 {
                            SETNMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 44:
-#line 505 "parse.yacc"
+#line 542 "parse.yacc"
+{
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE)
+                               append_role(yyvsp[0].string, NULL);
+                           yyval.string = yyvsp[0].string;
+#else
+                           free(yyvsp[0].string);
+                           yyval.string = NULL;
+#endif /* HAVE_SELINUX */
+                       }
+break;
+case 45:
+#line 555 "parse.yacc"
+{
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE)
+                               append_type(yyvsp[0].string, NULL);
+                           yyval.string = yyvsp[0].string;
+#else
+                           free(yyvsp[0].string);
+                           yyval.string = NULL;
+#endif /* HAVE_SELINUX */
+                       }
+break;
+case 46:
+#line 568 "parse.yacc"
+{
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit role. */
+                               cm_list[cm_list_len].role =
+                                   estrdup(cm_list[cm_list_len-1].role);
+                               cm_list[cm_list_len].role_len =
+                                   cm_list[cm_list_len-1].role_len;
+                               cm_list[cm_list_len].role_size =
+                                   cm_list[cm_list_len-1].role_len + 1;
+                               /* Inherit type. */
+                               cm_list[cm_list_len].type =
+                                   estrdup(cm_list[cm_list_len-1].type);
+                               cm_list[cm_list_len].type_len =
+                                   cm_list[cm_list_len-1].type_len;
+                               cm_list[cm_list_len].type_size =
+                                   cm_list[cm_list_len-1].type_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           yyval.seinfo.role = NULL;
+                           yyval.seinfo.type = NULL;
+                       }
+break;
+case 47:
+#line 591 "parse.yacc"
+{
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit type. */
+                               cm_list[cm_list_len].type =
+                                   estrdup(cm_list[cm_list_len-1].type);
+                               cm_list[cm_list_len].type_len =
+                                   cm_list[cm_list_len-1].type_len;
+                               cm_list[cm_list_len].type_size =
+                                   cm_list[cm_list_len-1].type_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           yyval.seinfo.role = yyvsp[0].string;
+                           yyval.seinfo.type = NULL;
+                       }
+break;
+case 48:
+#line 607 "parse.yacc"
+{
+#ifdef HAVE_SELINUX
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE && runas_matches == TRUE) {
+                               /* Inherit role. */
+                               cm_list[cm_list_len].role =
+                                   estrdup(cm_list[cm_list_len-1].role);
+                               cm_list[cm_list_len].role_len =
+                                   cm_list[cm_list_len-1].role_len;
+                               cm_list[cm_list_len].role_size =
+                                   cm_list[cm_list_len-1].role_len + 1;
+                           }
+#endif /* HAVE_SELINUX */
+                           yyval.seinfo.type = yyvsp[0].string;
+                           yyval.seinfo.role = NULL;
+                       }
+break;
+case 49:
+#line 623 "parse.yacc"
+{
+                           yyval.seinfo.role = yyvsp[-1].string;
+                           yyval.seinfo.type = yyvsp[0].string;
+                       }
+break;
+case 50:
+#line 627 "parse.yacc"
+{
+                           yyval.seinfo.type = yyvsp[-1].string;
+                           yyval.seinfo.role = yyvsp[0].string;
+                       }
+break;
+case 51:
+#line 633 "parse.yacc"
 {
                            if (printmatches == TRUE && host_matches == TRUE &&
                                user_matches == TRUE) {
@@ -1543,7 +1724,7 @@ case 44:
                                    cm_list[cm_list_len].runas_len =
                                        cm_list[cm_list_len-1].runas_len;
                                    cm_list[cm_list_len].runas_size =
-                                       cm_list[cm_list_len-1].runas_size;
+                                       cm_list[cm_list_len-1].runas_len + 1;
                                }
                            }
                            /*
@@ -1556,18 +1737,18 @@ case 44:
                            }
                        }
 break;
-case 45:
-#line 529 "parse.yacc"
+case 52:
+#line 657 "parse.yacc"
 {
                            runas_matches = yyvsp[0].BOOLEAN;
                        }
 break;
-case 46:
-#line 534 "parse.yacc"
+case 53:
+#line 662 "parse.yacc"
 { ; }
 break;
-case 47:
-#line 535 "parse.yacc"
+case 54:
+#line 663 "parse.yacc"
 {
                            /* Later entries override earlier ones. */
                            if (yyvsp[0].BOOLEAN != NOMATCH)
@@ -1576,12 +1757,12 @@ case 47:
                                yyval.BOOLEAN = yyvsp[-2].BOOLEAN;
                        }
 break;
-case 48:
-#line 544 "parse.yacc"
+case 55:
+#line 672 "parse.yacc"
 { ; }
 break;
-case 49:
-#line 545 "parse.yacc"
+case 56:
+#line 673 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1592,15 +1773,15 @@ case 49:
                            }
                        }
 break;
-case 50:
-#line 553 "parse.yacc"
+case 57:
+#line 681 "parse.yacc"
 {
                            /* Set $$ to the negation of runasuser */
                            yyval.BOOLEAN = (yyvsp[0].BOOLEAN == NOMATCH ? NOMATCH : ! yyvsp[0].BOOLEAN);
                        }
 break;
-case 51:
-#line 559 "parse.yacc"
+case 58:
+#line 687 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1617,8 +1798,8 @@ case 51:
                            used_runas = TRUE;
                        }
 break;
-case 52:
-#line 574 "parse.yacc"
+case 59:
+#line 702 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1635,8 +1816,8 @@ case 52:
                            used_runas = TRUE;
                        }
 break;
-case 53:
-#line 589 "parse.yacc"
+case 60:
+#line 717 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1653,8 +1834,8 @@ case 53:
                            used_runas = TRUE;
                        }
 break;
-case 54:
-#line 604 "parse.yacc"
+case 61:
+#line 732 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, RUNAS_ALIAS);
 
@@ -1686,8 +1867,8 @@ case 54:
                            used_runas = TRUE;
                        }
 break;
-case 55:
-#line 634 "parse.yacc"
+case 62:
+#line 762 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1699,8 +1880,8 @@ case 55:
                            yyval.BOOLEAN = TRUE;
                        }
 break;
-case 56:
-#line 646 "parse.yacc"
+case 63:
+#line 774 "parse.yacc"
 {
                            /* Inherit {NO,}{PASSWD,EXEC,SETENV} status. */
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1720,8 +1901,8 @@ case 56:
                            }
                        }
 break;
-case 57:
-#line 664 "parse.yacc"
+case 64:
+#line 792 "parse.yacc"
 {
                            no_passwd = TRUE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1729,8 +1910,8 @@ case 57:
                                cm_list[cm_list_len].nopasswd = TRUE;
                        }
 break;
-case 58:
-#line 670 "parse.yacc"
+case 65:
+#line 798 "parse.yacc"
 {
                            no_passwd = FALSE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1738,8 +1919,8 @@ case 58:
                                cm_list[cm_list_len].nopasswd = FALSE;
                        }
 break;
-case 59:
-#line 676 "parse.yacc"
+case 66:
+#line 804 "parse.yacc"
 {
                            no_execve = TRUE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1747,8 +1928,8 @@ case 59:
                                cm_list[cm_list_len].noexecve = TRUE;
                        }
 break;
-case 60:
-#line 682 "parse.yacc"
+case 67:
+#line 810 "parse.yacc"
 {
                            no_execve = FALSE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1756,8 +1937,8 @@ case 60:
                                cm_list[cm_list_len].noexecve = FALSE;
                        }
 break;
-case 61:
-#line 688 "parse.yacc"
+case 68:
+#line 816 "parse.yacc"
 {
                            setenv_ok = TRUE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1765,8 +1946,8 @@ case 61:
                                cm_list[cm_list_len].setenv = TRUE;
                        }
 break;
-case 62:
-#line 694 "parse.yacc"
+case 69:
+#line 822 "parse.yacc"
 {
                            setenv_ok = FALSE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1774,8 +1955,8 @@ case 62:
                                cm_list[cm_list_len].setenv = FALSE;
                        }
 break;
-case 63:
-#line 702 "parse.yacc"
+case 70:
+#line 830 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1795,8 +1976,8 @@ case 63:
                            yyval.BOOLEAN = TRUE;
                        }
 break;
-case 64:
-#line 720 "parse.yacc"
+case 71:
+#line 848 "parse.yacc"
 {
                            aliasinfo *aip;
 
@@ -1827,8 +2008,8 @@ case 64:
                            efree(yyvsp[0].string);
                        }
 break;
-case 65:
-#line 749 "parse.yacc"
+case 72:
+#line 877 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE) {
@@ -1854,12 +2035,12 @@ case 65:
                            efree(yyvsp[0].command.args);
                        }
 break;
-case 68:
-#line 779 "parse.yacc"
+case 75:
+#line 907 "parse.yacc"
 { push; }
 break;
-case 69:
-#line 779 "parse.yacc"
+case 76:
+#line 907 "parse.yacc"
 {
                            if ((MATCHED(host_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, HOST_ALIAS, host_matches)) {
@@ -1869,8 +2050,8 @@ case 69:
                            pop;
                        }
 break;
-case 74:
-#line 797 "parse.yacc"
+case 81:
+#line 925 "parse.yacc"
 {
                            push;
                            if (printmatches == TRUE) {
@@ -1882,8 +2063,8 @@ case 74:
                             }
                        }
 break;
-case 75:
-#line 806 "parse.yacc"
+case 82:
+#line 934 "parse.yacc"
 {
                            if ((MATCHED(cmnd_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, CMND_ALIAS, cmnd_matches)) {
@@ -1897,12 +2078,12 @@ case 75:
                                in_alias = FALSE;
                        }
 break;
-case 76:
-#line 820 "parse.yacc"
+case 83:
+#line 948 "parse.yacc"
 { ; }
 break;
-case 80:
-#line 828 "parse.yacc"
+case 87:
+#line 956 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                in_alias = TRUE;
@@ -1913,8 +2094,8 @@ case 80:
                            }
                        }
 break;
-case 81:
-#line 836 "parse.yacc"
+case 88:
+#line 964 "parse.yacc"
 {
                            if ((yyvsp[0].BOOLEAN != NOMATCH || pedantic) &&
                                !add_alias(yyvsp[-3].string, RUNAS_ALIAS, yyvsp[0].BOOLEAN)) {
@@ -1927,12 +2108,12 @@ case 81:
                                in_alias = FALSE;
                        }
 break;
-case 84:
-#line 853 "parse.yacc"
+case 91:
+#line 981 "parse.yacc"
 { push; }
 break;
-case 85:
-#line 853 "parse.yacc"
+case 92:
+#line 981 "parse.yacc"
 {
                            if ((MATCHED(user_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, USER_ALIAS, user_matches)) {
@@ -1943,20 +2124,20 @@ case 85:
                            efree(yyvsp[-3].string);
                        }
 break;
-case 88:
-#line 868 "parse.yacc"
+case 95:
+#line 996 "parse.yacc"
 {
                            SETMATCH(user_matches, yyvsp[0].BOOLEAN);
                        }
 break;
-case 89:
-#line 871 "parse.yacc"
+case 96:
+#line 999 "parse.yacc"
 {
                            SETNMATCH(user_matches, yyvsp[0].BOOLEAN);
                        }
 break;
-case 90:
-#line 876 "parse.yacc"
+case 97:
+#line 1004 "parse.yacc"
 {
                            if (userpw_matches(yyvsp[0].string, user_name, sudo_user.pw))
                                yyval.BOOLEAN = TRUE;
@@ -1965,8 +2146,8 @@ case 90:
                            efree(yyvsp[0].string);
                        }
 break;
-case 91:
-#line 883 "parse.yacc"
+case 98:
+#line 1011 "parse.yacc"
 {
                            if (usergr_matches(yyvsp[0].string, user_name, sudo_user.pw))
                                yyval.BOOLEAN = TRUE;
@@ -1975,8 +2156,8 @@ case 91:
                            efree(yyvsp[0].string);
                        }
 break;
-case 92:
-#line 890 "parse.yacc"
+case 99:
+#line 1018 "parse.yacc"
 {
                            if (netgr_matches(yyvsp[0].string, NULL, NULL, user_name))
                                yyval.BOOLEAN = TRUE;
@@ -1985,8 +2166,8 @@ case 92:
                            efree(yyvsp[0].string);
                        }
 break;
-case 93:
-#line 897 "parse.yacc"
+case 100:
+#line 1025 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, USER_ALIAS);
 
@@ -2010,13 +2191,13 @@ case 93:
                            efree(yyvsp[0].string);
                        }
 break;
-case 94:
-#line 919 "parse.yacc"
+case 101:
+#line 1047 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
 break;
-#line 1968 "sudo.tab.c"
+#line 2149 "sudo.tab.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 36fc3364b12a7d012f2f760c7a4ff0c57a90f36f..ba97b3a266b7c85a1157ba5d2480042036abf924 100644 (file)
@@ -23,6 +23,8 @@
 #define USERALIAS 279
 #define RUNASALIAS 280
 #define ERROR 281
+#define TYPE 282
+#define ROLE 283
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
@@ -30,6 +32,7 @@ typedef union {
     int BOOLEAN;
     struct sudo_command command;
     int tok;
+    struct selinux_info seinfo;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
 extern YYSTYPE yylval;
index d1714cf105f3b3ffebf613f144a25f655b7f7af2..eeeb52d2183cb6bee18dfd604eee7edee28b2478 100644 (file)
@@ -61,7 +61,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
 
 
-1.6.9p12                 January 14, 2008                       1
+1.6.9p14                February 19, 2008                       1
 
 
 
@@ -127,7 +127,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       2
+1.6.9p14                February 19, 2008                       2
 
 
 
@@ -193,7 +193,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       3
+1.6.9p14                February 19, 2008                       3
 
 
 
@@ -259,7 +259,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       4
+1.6.9p14                February 19, 2008                       4
 
 
 
@@ -325,7 +325,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       5
+1.6.9p14                February 19, 2008                       5
 
 
 
@@ -391,7 +391,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       6
+1.6.9p14                February 19, 2008                       6
 
 
 
@@ -457,7 +457,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                       7
+1.6.9p14                February 19, 2008                       7
 
 
 
@@ -523,7 +523,7 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
 
 
-1.6.9p12                 January 14, 2008                       8
+1.6.9p14                February 19, 2008                       8
 
 
 
@@ -579,17 +579,17 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        s\bsu\bud\bdo\bo).
 
        ignore_local_sudoers
-                       If set via LDAP, parsing of
-                       @sysconfdir@/sudoers will be skipped.
-                       This is intended for Enterprises that wish
-                       to prevent the usage of local sudoers
-                       files so that only LDAP is used.  This
-                       thwarts the efforts of rogue operators who
-                       would attempt to add roles to
+                       If set via LDAP, parsing of _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs
+                       will be skipped.  This is intended for
+                       Enterprises that wish to prevent the usage
+                       of local sudoers files so that only LDAP
+                       is used.  This thwarts the efforts of
+                       rogue operators who would attempt to add
+                       roles to _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs.  When this option
 
 
 
-1.6.9p12                 January 14, 2008                       9
+1.6.9p14                February 19, 2008                       9
 
 
 
@@ -598,14 +598,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-                       @sysconfdir@/sudoers.  When this option is
-                       present, @sysconfdir@/sudoers does not
-                       even need to exist.  Since this option
-                       tells s\bsu\bud\bdo\bo how to behave when no specific
-                       LDAP entries have been matched, this
-                       sudoOption is only meaningful for the
-                       cn=defaults section.  This flag is _\bo_\bf_\bf by
-                       default.
+                       is present, _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs does not even
+                       need to exist. Since this option tells
+                       s\bsu\bud\bdo\bo how to behave when no specific LDAP
+                       entries have been matched, this sudoOption
+                       is only meaningful for the cn=defaults
+                       section.  This flag is _\bo_\bf_\bf by default.
 
        insults         If set, s\bsu\bud\bdo\bo will insult users when they
                        enter an incorrect password.  This flag is
@@ -652,10 +650,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        user if the invoking user is not in the
                        _\bs_\bu_\bd_\bo_\be_\br_\bs file.  This flag is _\bo_\bn by default.
 
+       noexec          If set, all commands run via s\bsu\bud\bdo\bo will
+                       behave as if the NOEXEC tag has been set,
 
 
 
-1.6.9p12                 January 14, 2008                      10
+1.6.9p14                February 19, 2008                      10
 
 
 
@@ -664,8 +664,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-       noexec          If set, all commands run via s\bsu\bud\bdo\bo will
-                       behave as if the NOEXEC tag has been set,
                        unless overridden by a EXEC tag.  See the
                        description of _\bN_\bO_\bE_\bX_\bE_\bC _\ba_\bn_\bd _\bE_\bX_\bE_\bC below as
                        well as the "PREVENTING SHELL ESCAPES"
@@ -718,10 +716,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        Note, however, that turning off _\br_\bo_\bo_\bt_\b__\bs_\bu_\bd_\bo
                        will also prevent root and from running
                        s\bsu\bud\bdo\boe\bed\bdi\bit\bt.  Disabling _\br_\bo_\bo_\bt_\b__\bs_\bu_\bd_\bo provides no
+                       real additional security; it exists purely
+                       for historical reasons.  This flag is _\bo_\bn
 
 
 
-1.6.9p12                 January 14, 2008                      11
+1.6.9p14                February 19, 2008                      11
 
 
 
@@ -730,8 +730,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-                       real additional security; it exists purely
-                       for historical reasons.  This flag is _\bo_\bn
                        by default.
 
        rootpw          If set, s\bsu\bud\bdo\bo will prompt for the root
@@ -784,10 +782,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        (the shell is determined by the SHELL
                        environment variable if it is set, falling
                        back on the shell listed in the invoking
+                       user's /etc/passwd entry if not).  This
+                       flag is _\bo_\bf_\bf by default.
 
 
 
-1.6.9p12                 January 14, 2008                      12
+1.6.9p14                February 19, 2008                      12
 
 
 
@@ -796,9 +796,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-                       user's /etc/passwd entry if not).  This
-                       flag is _\bo_\bf_\bf by default.
-
        stay_setuid     Normally, when s\bsu\bud\bdo\bo executes a command the
                        real and effective UIDs are set to the
                        target user (root by default).  This
@@ -850,10 +847,13 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        file log.  The default is 80 (use 0 or
                        negate the option to disable word wrap).
 
+       passwd_timeout  Number of minutes before the s\bsu\bud\bdo\bo password
+                       prompt times out.  The default is 5; set
+                       this to 0 for no password timeout.
 
 
 
-1.6.9p12                 January 14, 2008                      13
+1.6.9p14                February 19, 2008                      13
 
 
 
@@ -862,10 +862,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-       passwd_timeout  Number of minutes before the s\bsu\bud\bdo\bo password
-                       prompt times out.  The default is 5; set
-                       this to 0 for no password timeout.
-
        timestamp_timeout
                        Number of minutes that can elapse before
                        s\bsu\bud\bdo\bo will ask for a passwd again.  The
@@ -917,9 +913,13 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        variable.  The following percent (`%')
                        escapes are supported:
 
+                       %H  expanded to the local hostname includ­
+                           ing the domain name (on if the
+                           machine's hostname is fully qualified
+
 
 
-1.6.9p12                 January 14, 2008                      14
+1.6.9p14                February 19, 2008                      14
 
 
 
@@ -928,9 +928,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-                       %H  expanded to the local hostname includ­
-                           ing the domain name (on if the
-                           machine's hostname is fully qualified
                            or the _\bf_\bq_\bd_\bn option is set)
 
                        %h  expanded to the local hostname without
@@ -983,18 +980,19 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                    be printed along with the password prompt.  It
                    has the following possible values:
 
+                   always  Always lecture the user.
 
 
-1.6.9p12                 January 14, 2008                      15
 
 
+1.6.9p14                February 19, 2008                      15
 
 
 
-SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-                   always  Always lecture the user.
+SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
+
 
                    never   Never lecture the user.
 
@@ -1048,10 +1046,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                    mail.  Defaults to the path to sendmail found
                    at configure time.
 
+       mailto      Address to send warning and error mail to.
+                   The address should be enclosed in double
 
 
 
-1.6.9p12                 January 14, 2008                      16
+1.6.9p14                February 19, 2008                      16
 
 
 
@@ -1060,8 +1060,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-       mailto      Address to send warning and error mail to.
-                   The address should be enclosed in double
                    quotes (") to protect against s\bsu\bud\bdo\bo interpret­
                    ing the @ sign.  Defaults to root.
 
@@ -1114,10 +1112,12 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
                        check is displayed when s\bsu\bud\bdo\bo is run by
                        root with the _\b-_\bV option.
 
+       env_delete      Environment variables to be removed from
+                       the user's environment.  The argument may
 
 
 
-1.6.9p12                 January 14, 2008                      17
+1.6.9p14                February 19, 2008                      17
 
 
 
@@ -1126,8 +1126,6 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
-       env_delete      Environment variables to be removed from
-                       the user's environment.  The argument may
                        be a double-quoted, space-separated list
                        or a single value without double-quotes.
                        The list can be replaced, added to,
@@ -1163,9 +1161,11 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
        and w\bwa\bar\brn\bni\bin\bng\bg.
 
 F\bFI\bIL\bLE\bES\bS
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs         List of who can run what
-       _\b/_\be_\bt_\bc_\b/_\bg_\br_\bo_\bu_\bp           Local groups file
-       _\b/_\be_\bt_\bc_\b/_\bn_\be_\bt_\bg_\br_\bo_\bu_\bp        List of network groups
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs            List of who can run what
+
+       _\b/_\be_\bt_\bc_\b/_\bg_\br_\bo_\bu_\bp              Local groups file
+
+       _\b/_\be_\bt_\bc_\b/_\bn_\be_\bt_\bg_\br_\bo_\bu_\bp           List of network groups
 
 E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
        Since the _\bs_\bu_\bd_\bo_\be_\br_\bs file is parsed in a single pass, order
@@ -1183,7 +1183,7 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
 
 
 
-1.6.9p12                 January 14, 2008                      18
+1.6.9p14                February 19, 2008                      18
 
 
 
@@ -1249,7 +1249,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                      19
+1.6.9p14                February 19, 2008                      19
 
 
 
@@ -1315,7 +1315,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                      20
+1.6.9p14                February 19, 2008                      20
 
 
 
@@ -1381,7 +1381,7 @@ SUDOERS(4)             MAINTENANCE COMMANDS            SUDOERS(4)
 
 
 
-1.6.9p12                 January 14, 2008                      21
+1.6.9p14                February 19, 2008                      21
 
 
 
@@ -1447,7 +1447,7 @@ P\bPR\bRE\bEV\bVE\bEN\bNT\bTI\bIN\bNG\bG S\bSH\bHE\bEL\bLL\bL E\bES\bSC\bCA\bAP\bPE\bES\bS
 
 
 
-1.6.9p12                 January 14, 2008                      22
+1.6.9p14                February 19, 2008                      22
 
 
 
@@ -1513,7 +1513,7 @@ C\bCA\bAV\bVE\bEA\bAT\bTS\bS
 
 
 
-1.6.9p12                 January 14, 2008                      23
+1.6.9p14                February 19, 2008                      23
 
 
 
@@ -1579,6 +1579,6 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.6.9p12                 January 14, 2008                      24
+1.6.9p14                February 19, 2008                      24
 
 
index 8f2604a76a412b5eda22890a87abfac6caae820b..bd4b27129591503df942b0c331b6c4279eccf400 100644 (file)
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: sudoers.man.in,v 1.45.2.22 2008/01/14 12:22:57 millert Exp $
+.\" $Sudo: sudoers.man.in,v 1.45.2.26 2008/03/05 13:05:05 millert Exp $
 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "SUDOERS @mansectform@"
-.TH SUDOERS @mansectform@ "January 14, 2008" "1.6.9p12" "MAINTENANCE COMMANDS"
+.TH SUDOERS @mansectform@ "February 19, 2008" "1.6.9p14" "MAINTENANCE COMMANDS"
 .SH "NAME"
 sudoers \- list of which users may execute what
 .SH "DESCRIPTION"
@@ -667,14 +667,14 @@ should be considered read-only (it will be fixed in a future version
 of \fBsudo\fR).
 .IP "ignore_local_sudoers" 16
 .IX Item "ignore_local_sudoers"
-If set via \s-1LDAP\s0, parsing of \f(CW@sysconfdir\fR@/sudoers will be skipped.
+If set via \s-1LDAP\s0, parsing of \fI@sysconfdir@/sudoers\fR will be skipped.
 This is intended for Enterprises that wish to prevent the usage of local
 sudoers files so that only \s-1LDAP\s0 is used.  This thwarts the efforts of
-rogue operators who would attempt to add roles to \f(CW@sysconfdir\fR@/sudoers.
-When this option is present, \f(CW@sysconfdir\fR@/sudoers does not even need to exist. 
-Since this option tells \fBsudo\fR how to behave when no specific \s-1LDAP\s0 entries
-have been matched, this sudoOption is only meaningful for the cn=defaults
-section.  This flag is \fIoff\fR by default.
+rogue operators who would attempt to add roles to \fI@sysconfdir@/sudoers\fR.
+When this option is present, \fI@sysconfdir@/sudoers\fR does not even need to
+exist. Since this option tells \fBsudo\fR how to behave when no specific \s-1LDAP\s0
+entries have been matched, this sudoOption is only meaningful for the
+\&\f(CW\*(C`cn=defaults\*(C'\fR section.  This flag is \fIoff\fR by default.
 .IP "insults" 16
 .IX Item "insults"
 If set, \fBsudo\fR will insult users when they enter an incorrect
@@ -828,11 +828,11 @@ If set, users must authenticate on a per-tty basis.  Normally,
 the user running it.  With this flag enabled, \fBsudo\fR will use a
 file named for the tty the user is logged in on in that directory.
 This flag is \fI@tty_tickets@\fR by default.
-.IP "use_loginclass" 16
-.IX Item "use_loginclass"
-If set, \fBsudo\fR will apply the defaults specified for the target user's
-login class if one exists.  Only available if \fBsudo\fR is configured with
-the \-\-with\-logincap option.  This flag is \fIoff\fR by default.
+@LCMAN@.IP "use_loginclass" 16
+@LCMAN@.IX Item "use_loginclass"
+@LCMAN@If set, \fBsudo\fR will apply the defaults specified for the target user's
+@LCMAN@login class if one exists.  Only available if \fBsudo\fR is configured with
+@LCMAN@the \-\-with\-logincap option.  This flag is \fIoff\fR by default.
 .PP
 \&\fBIntegers\fR:
 .IP "passwd_tries" 16
@@ -926,6 +926,12 @@ two consecutive \f(CW\*(C`%\*(C'\fR characters are collapsed into a single \f(CW
 .Sp
 The default value is \f(CW\*(C`@passprompt@\*(C'\fR.
 .RE
+@SEMAN@.IP "role" 16
+@SEMAN@.IX Item "role"
+@SEMAN@The default SELinux role to use when constructing a new security
+@SEMAN@context to run the command.  The default role may be overridden on
+@SEMAN@a per-command basis in \fIsudoers\fR or via command line options.
+@SEMAN@This option is only available whe \fBsudo\fR is built with SELinux support.
 .IP "runas_default" 16
 .IX Item "runas_default"
 The default user to run commands as if the \fB\-u\fR flag is not specified
@@ -948,6 +954,12 @@ The default is \fI@timedir@\fR.
 .IX Item "timestampowner"
 The owner of the timestamp directory and the timestamps stored therein.
 The default is \f(CW\*(C`root\*(C'\fR.
+@SEMAN@.IP "type" 16
+@SEMAN@.IX Item "type"
+@SEMAN@The default SELinux type to use when constructing a new security
+@SEMAN@context to run the command.  The default type may be overridden on
+@SEMAN@a per-command basis in \fIsudoers\fR or via command line options.
+@SEMAN@This option is only available whe \fBsudo\fR is built with SELinux support.
 .PP
 \&\fBStrings that can be used in a boolean context\fR:
 .IP "exempt_group" 12
@@ -1100,17 +1112,15 @@ supported: \fBalert\fR, \fBcrit\fR, \fBdebug\fR, \fBemerg\fR, \fBerr\fR, \fBinfo
 \&\fBnotice\fR, and \fBwarning\fR.
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI@sysconfdir@/sudoers\fR\*(C`             \*(C' List of who can run what" 4
-.el .IP "\fI@sysconfdir@/sudoers\fR\f(CW\*(C`          \*(C'\fR List of who can run what" 4
-.IX Item "@sysconfdir@/sudoers          List of who can run what"
-.PD 0
-.ie n .IP "\fI/etc/group\fR\*(C`               \*(C' Local groups file" 4
-.el .IP "\fI/etc/group\fR\f(CW\*(C`            \*(C'\fR Local groups file" 4
-.IX Item "/etc/group            Local groups file"
-.ie n .IP "\fI/etc/netgroup\fR\*(C`            \*(C' List of network groups" 4
-.el .IP "\fI/etc/netgroup\fR\f(CW\*(C`         \*(C'\fR List of network groups" 4
-.IX Item "/etc/netgroup                 List of network groups"
-.PD
+.IP "\fI@sysconfdir@/sudoers\fR" 24
+.IX Item "@sysconfdir@/sudoers"
+List of who can run what
+.IP "\fI/etc/group\fR" 24
+.IX Item "/etc/group"
+Local groups file
+.IP "\fI/etc/netgroup\fR" 24
+.IX Item "/etc/netgroup"
+List of network groups
 .SH "EXAMPLES"
 .IX Header "EXAMPLES"
 Since the \fIsudoers\fR file is parsed in a single pass, order is
index 91dfd8494465d7f01822172530e6d7f6e8d92e2e..f65db6b51de6e8c318041b52a00468812f00feeb 100644 (file)
@@ -1,4 +1,3 @@
-=cut
 Copyright (c) 1994-1996, 1998-2005, 2007
        Todd C. Miller <Todd.Miller@courtesan.com>
 
@@ -19,7 +18,7 @@ Sponsored in part by the Defense Advanced Research Projects
 Agency (DARPA) and Air Force Research Laboratory, Air Force
 Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-$Sudo: sudoers.pod,v 1.95.2.23 2008/01/05 23:59:42 millert Exp $
+$Sudo: sudoers.pod,v 1.95.2.26 2008/02/19 18:13:17 millert Exp $
 =pod
 
 =head1 NAME
@@ -500,14 +499,14 @@ of B<sudo>).
 
 =item ignore_local_sudoers
 
-If set via LDAP, parsing of @sysconfdir@/sudoers will be skipped.
+If set via LDAP, parsing of F<@sysconfdir@/sudoers> will be skipped.
 This is intended for Enterprises that wish to prevent the usage of local
 sudoers files so that only LDAP is used.  This thwarts the efforts of
-rogue operators who would attempt to add roles to @sysconfdir@/sudoers.
-When this option is present, @sysconfdir@/sudoers does not even need to exist. 
-Since this option tells B<sudo> how to behave when no specific LDAP entries
-have been matched, this sudoOption is only meaningful for the cn=defaults
-section.  This flag is I<off> by default.
+rogue operators who would attempt to add roles to F<@sysconfdir@/sudoers>.
+When this option is present, F<@sysconfdir@/sudoers> does not even need to
+exist. Since this option tells B<sudo> how to behave when no specific LDAP
+entries have been matched, this sudoOption is only meaningful for the
+C<cn=defaults> section.  This flag is I<off> by default.
 
 =item insults
 
@@ -808,6 +807,13 @@ two consecutive C<%> characters are collapsed into a single C<%> character
 
 The default value is C<@passprompt@>.
 
+=item role
+
+The default SELinux role to use when constructing a new security
+context to run the command.  The default role may be overridden on
+a per-command basis in I<sudoers> or via command line options.
+This option is only available whe B<sudo> is built with SELinux support.
+
 =item runas_default
 
 The default user to run commands as if the B<-u> flag is not specified
@@ -835,6 +841,13 @@ The default is F<@timedir@>.
 The owner of the timestamp directory and the timestamps stored therein.
 The default is C<root>.
 
+=item type
+
+The default SELinux type to use when constructing a new security
+context to run the command.  The default type may be overridden on
+a per-command basis in I<sudoers> or via command line options.
+This option is only available whe B<sudo> is built with SELinux support.
+
 =back
 
 B<Strings that can be used in a boolean context>:
@@ -1021,15 +1034,18 @@ B<notice>, and B<warning>.
 
 =head1 FILES
 
-=over 4
+=over 24
+
+=item F<@sysconfdir@/sudoers>
 
-=item F<@sysconfdir@/sudoers>C<                >
 List of who can run what
 
-=item F</etc/group>C<          >
+=item F</etc/group>
+
 Local groups file
 
-=item F</etc/netgroup>C<               >
+=item F</etc/netgroup>
+
 List of network groups
 
 =back
index 756d331e74ecf4dc7dfb5a2b380208be4a09a52a..3b213f36f2bb4602e7458b0216bfccf890820284 100644 (file)
@@ -75,7 +75,7 @@
 #endif /* HAVE_FNMATCH */
 
 #ifndef lint
-__unused static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88.2.6 2007/10/24 16:43:27 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88.2.7 2008/02/09 14:44:49 millert Exp $";
 #endif /* lint */
 
 
@@ -542,6 +542,10 @@ main(argc, argv)
            (void) printf("no_passwd  : %d\n", no_passwd);
            (void) printf("runas_match: %d\n", runas_matches);
            (void) printf("runas      : %s\n", *user_runas);
+           if (match[top-1].role)
+               (void) printf("role       : %s\n", match[top-1].role);
+           if (match[top-1].type)
+               (void) printf("type       : %s\n", match[top-1].type);
            top--;
        }
     }
index a51e62a4f0dcb081b5211e7e3026bcea6bf6bf41..8ab11dafd74c13238b5a67944debcb648561f734 100644 (file)
--- a/version.h
+++ b/version.h
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
  *
- * $Sudo: version.h,v 1.66.2.15 2008/01/14 12:22:57 millert Exp $
+ * $Sudo: version.h,v 1.66.2.17 2008/03/05 12:41:08 millert Exp $
  */
 
 #ifndef _SUDO_VERSION_H
 #define _SUDO_VERSION_H
 
-static const char version[] = "1.6.9p12";
+static const char version[] = "1.6.9p14";
 
 #endif /* _SUDO_VERSION_H */
index de2e7650b2db46b5cced1412dcac1e080b263fde..d8c0f43d79bfe0ba7bdf4e95b34ec19556150a84 100644 (file)
@@ -61,7 +61,7 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
 
 
-1.6.9p12                 January 14, 2008                       1
+1.6.9p14                February 19, 2008                       1
 
 
 
@@ -98,8 +98,9 @@ E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
        EDITOR          Used by visudo if VISUAL is not set
 
 F\bFI\bIL\bLE\bES\bS
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs             List of who can run what
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bt_\bm_\bp         Lock file for visudo
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs            List of who can run what
+
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bt_\bm_\bp        Lock file for visudo
 
 D\bDI\bIA\bAG\bGN\bNO\bOS\bST\bTI\bIC\bCS\bS
        sudoers file busy, try again later.
@@ -123,11 +124,10 @@ D\bDI\bIA\bAG\bGN\bNO\bOS\bST\bTI\bIC\bCS\bS
        Warning: runas_default set after old value is in use ...
            You have a _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt Defaults setting listed in
            the _\bs_\bu_\bd_\bo_\be_\br_\bs file after its value has already been
-           used.  This means that entries prior to the
 
 
 
-1.6.9p12                 January 14, 2008                       2
+1.6.9p14                February 19, 2008                       2
 
 
 
@@ -136,6 +136,7 @@ D\bDI\bIA\bAG\bGN\bNO\bOS\bST\bTI\bIC\bCS\bS
 VISUDO(1m)             MAINTENANCE COMMANDS            VISUDO(1m)
 
 
+           used.  This means that entries prior to the
            _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt setting will match based on the default
            value of _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt (root) whereas entries a\baf\bft\bte\ber\br
            the _\br_\bu_\bn_\ba_\bs_\b__\bd_\be_\bf_\ba_\bu_\bl_\bt setting will match based on the new
@@ -192,7 +193,6 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-
-1.6.9p12                 January 14, 2008                       3
+1.6.9p14                February 19, 2008                       3
 
 
index 371965c599f36ba1fab49df32ebff0bcf9d33a7a..b1662faaaf974fd59c306b06df9efeb977e4922b 100644 (file)
@@ -17,7 +17,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\" 
-.\" $Sudo: visudo.man.in,v 1.20.2.17 2008/01/14 12:22:57 millert Exp $
+.\" $Sudo: visudo.man.in,v 1.20.2.19 2008/03/05 13:05:05 millert Exp $
 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .IX Title "VISUDO @mansectsu@"
-.TH VISUDO @mansectsu@ "January 14, 2008" "1.6.9p12" "MAINTENANCE COMMANDS"
+.TH VISUDO @mansectsu@ "February 19, 2008" "1.6.9p14" "MAINTENANCE COMMANDS"
 .SH "NAME"
 visudo \- edit the sudoers file
 .SH "SYNOPSIS"
@@ -235,14 +235,12 @@ Invoked by visudo as the editor to use
 Used by visudo if \s-1VISUAL\s0 is not set
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI@sysconfdir@/sudoers\fR\*(C`             \*(C'List of who can run what" 4
-.el .IP "\fI@sysconfdir@/sudoers\fR\f(CW\*(C`                  \*(C'\fRList of who can run what" 4
-.IX Item "@sysconfdir@/sudoers                 List of who can run what"
-.PD 0
-.ie n .IP "\fI@sysconfdir@/sudoers.tmp\fR\*(C`         \*(C'Lock file for visudo" 4
-.el .IP "\fI@sysconfdir@/sudoers.tmp\fR\f(CW\*(C`              \*(C'\fRLock file for visudo" 4
-.IX Item "@sysconfdir@/sudoers.tmp             Lock file for visudo"
-.PD
+.IP "\fI@sysconfdir@/sudoers\fR" 24
+.IX Item "@sysconfdir@/sudoers"
+List of who can run what
+.IP "\fI@sysconfdir@/sudoers.tmp\fR" 24
+.IX Item "@sysconfdir@/sudoers.tmp"
+Lock file for visudo
 .SH "DIAGNOSTICS"
 .IX Header "DIAGNOSTICS"
 .IP "sudoers file busy, try again later." 4
index 0743b938672332a111c2aceec335d60cdbb3a2fe..d914fab45e7aff10b3d868408514fb7f361cc35a 100644 (file)
@@ -1,4 +1,3 @@
-=cut
 Copyright (c) 1996,1998-2005, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -18,7 +17,7 @@ Sponsored in part by the Defense Advanced Research Projects
 Agency (DARPA) and Air Force Research Laboratory, Air Force
 Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-$Sudo: visudo.pod,v 1.38.2.9 2007/08/13 16:23:31 millert Exp $
+$Sudo: visudo.pod,v 1.38.2.10 2008/02/19 15:45:12 millert Exp $
 =pod
 
 =head1 NAME
@@ -125,11 +124,15 @@ Used by visudo if VISUAL is not set
 
 =head1 FILES
 
-=over 4
+=over 24
+
+=item F<@sysconfdir@/sudoers>
+
+List of who can run what
 
-=item F<@sysconfdir@/sudoers>C<                >List of who can run what
+=item F<@sysconfdir@/sudoers.tmp>
 
-=item F<@sysconfdir@/sudoers.tmp>C<            >Lock file for visudo
+Lock file for visudo
 
 =back