From: Bdale Garbee Date: Wed, 14 May 2008 18:04:25 +0000 (-0600) Subject: Imported Upstream version 1.6.9p14 X-Git-Tag: upstream/1.6.9p14^0 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=6850c41061e133f6ab21bc84330f62d6058fd27c;p=debian%2Fsudo Imported Upstream version 1.6.9p14 --- diff --git a/CHANGES b/CHANGES index fcb8d55..6e11ab9 100644 --- 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 b03d9e8..1692887 100644 --- 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 diff --git a/Makefile.in b/Makefile.in index 1ed0b8b..badea37 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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) diff --git a/auth/kerb5.c b/auth/kerb5.c index 763ce85..89d43a7 100644 --- a/auth/kerb5.c +++ b/auth/kerb5.c @@ -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); diff --git a/auth/pam.c b/auth/pam.c index f602478..b2fe41a 100644 --- a/auth/pam.c +++ b/auth/pam.c @@ -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 || diff --git a/config.h.in b/config.h.in index 2ce67d7..ab33f13 100644 --- a/config.h.in +++ b/config.h.in @@ -305,6 +305,9 @@ /* Define to 1 if you have the 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 diff --git a/configure b/configure index fd21e63..047edea 100755 --- 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 < conftest.$ac_ext <>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 + #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 @@ -22985,10 +22942,7 @@ fi 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 + + diff --git a/configure.in b/configure.in index 0760e35..4449b00 100644 --- a/configure.in +++ b/configure.in @@ -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 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 ]) 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 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 has the sigaction_t typedef.]) AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.]) diff --git a/def_data.c b/def_data.c index 944a55c..412d0b8 100644 --- a/def_data.c +++ b/def_data.c @@ -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 } diff --git a/def_data.h b/def_data.h index 13d81bf..bbbd2ab 100644 --- a/def_data.h +++ b/def_data.h @@ -118,6 +118,10 @@ #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, diff --git a/def_data.in b/def_data.in index 47370b8..fb16f75 100644 --- a/def_data.in +++ b/def_data.in @@ -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 9097310..0477f81 100644 --- 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 */ diff --git a/lex.yy.c b/lex.yy.c index 47cd239..68405fb 100644 --- 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 #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 ce943f6..8c4a1e5 100644 --- 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 9ad008a..a9bbc8e 100644 --- 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; diff --git a/parse.lex b/parse.lex index 1c4bbc7..f1ffddc 100644 --- a/parse.lex +++ b/parse.lex @@ -55,7 +55,7 @@ #include #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); } (#[0-9-]+|{WORD}) { diff --git a/parse.yacc b/parse.yacc index 5b1c856..93871b2 100644 --- a/parse.yacc +++ b/parse.yacc @@ -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 RUNASALIAS /* Runas_Alias keyword */ %token ':' '=' ',' '!' '+' '-' /* union member tokens */ %token ERROR +%token TYPE /* SELinux type */ +%token ROLE /* SELinux role */ /* * NOTE: these are not true booleans as there are actually 4 possible values: @@ -283,6 +299,9 @@ yyerror(s) %type oprunasuser %type runaslist %type user +%type selinux +%type rolespec +%type 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; diff --git a/pathnames.h.in b/pathnames.h.in index cef0793..3fc3249 100644 --- a/pathnames.h.in +++ b/pathnames.h.in @@ -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 $ */ /* @@ -101,6 +101,10 @@ #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 index 0000000..7d49854 --- /dev/null +++ b/selinux.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2008 Dan Walsh + * + * Borrowed heavily from newrole source code + * Authors: + * Anthony Colatrella + * Tim Fraser + * Steve Grubb + * Darrel Goeddel + * Michael Thompson + * Dan Walsh + * + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_AUDIT +#include +#endif + +#include /* for SECCLASS_CHR_FILE */ +#include /* for is_selinux_enabled() */ +#include /* for context-mangling functions */ +#include +#include + +#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 index 0000000..06728d4 --- /dev/null +++ b/sesh.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008 Todd C. Miller + * + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 021e0e5..0e7f6c7 100644 --- a/sudo.c +++ b/sudo.c @@ -96,13 +96,16 @@ # include # include #endif +#ifdef HAVE_SELINUX +# include +#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 | }", diff --git a/sudo.cat b/sudo.cat index e8aca6f..eec5ed4 100644 --- a/sudo.cat +++ b/sudo.cat @@ -61,7 +61,7 @@ DDEESSCCRRIIPPTTIIOONN -1.6.9p12 January 14, 2008 1 +1.6.9p14 February 19, 2008 1 @@ -127,7 +127,7 @@ OOPPTTIIOONNSS -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 @@ SSEECCUURRIITTYY NNOOTTEESS -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 @@ EENNVVIIRROONNMMEENNTT mode FFIILLEESS - _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what - _/_v_a_r_/_r_u_n_/_s_u_d_o Directory containing timestamps + _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what + _/_v_a_r_/_r_u_n_/_s_u_d_o Directory containing timestamps -1.6.9p12 January 14, 2008 7 +1.6.9p14 February 19, 2008 7 @@ -496,7 +496,7 @@ EEXXAAMMPPLLEESS SSEEEE AALLSSOO _g_r_e_p(1), _s_u(1), _s_t_a_t(2), _l_o_g_i_n___c_a_p(3), _p_a_s_s_w_d(4), - _s_u_d_o_e_r_s(4), _v_i_s_u_d_o(1m) + _s_u_d_o_e_r_s(5), _v_i_s_u_d_o(1m) AAUUTTHHOORRSS Many people have worked on ssuuddoo over the years; this ver­ @@ -523,7 +523,7 @@ CCAAVVEEAATTSS -1.6.9p12 January 14, 2008 8 +1.6.9p14 February 19, 2008 8 @@ -589,6 +589,6 @@ DDIISSCCLLAAIIMMEERR -1.6.9p12 January 14, 2008 9 +1.6.9p14 February 19, 2008 9 diff --git a/sudo.h b/sudo.h index 665deb6..889cd4a 100644 --- 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. */ diff --git a/sudo.man.in b/sudo.man.in index 93dd0b1..8d02797 100644 --- a/sudo.man.in +++ b/sudo.man.in @@ -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: @@ -150,18 +150,24 @@ .\" ======================================================================== .\" .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 diff --git a/sudo.pod b/sudo.pod index b6562b0..33fe5d2 100644 --- a/sudo.pod +++ b/sudo.pod @@ -1,4 +1,3 @@ -=cut Copyright (c) 1994-1996, 1998-2005, 2007 Todd C. Miller @@ -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 B<-h> | B<-K> | B<-k> | B<-L> | B<-l> | B<-V> | B<-v> -B [B<-bEHPS>] S<[B<-a> I]> -S<[B<-c> I|I<->]> S<[B<-p> I]> S<[B<-u> I|I<#uid>]> +B [B<-bEHPS>] +S<[B<-a> I]> +S<[B<-c> I|I<->]> +S<[B<-p> I]> +S<[B<-r> I]> S<[B<-t> I]> +S<[B<-u> I|I<#uid>]> S<[B=I]> S<{B<-i> | B<-s> | I}> -B [B<-S>] S<[B<-a> I]> S<[B<-c> I|I<->]> +B [B<-S>] +S<[B<-a> I]> +S<[B<-c> I|I<->]> S<[B<-p> I]> S<[B<-u> I|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) option causes the new (SELinux) security context to +have the role specified by I. + =item -S The B<-S> (I) option causes B to read the password from @@ -269,6 +279,12 @@ The B<-s> (I) option runs the shell specified by the I environment variable if it is set or the shell as specified in L. +=item -t + +The B<-t> (I) option causes the new (SELinux) security context to +have the type specified by I. If no type is specified, the default +type is derived from the specified role. + =item -u The B<-u> (I) option causes B 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 and file redirection work. =head1 SEE ALSO -L, L, L, L, L, -L, L +L, L, L, +L, +L, L, L =head1 AUTHORS diff --git a/sudo.tab.c b/sudo.tab.c index 46b2529..0e40bef 100644 --- a/sudo.tab.c +++ b/sudo.tab.c @@ -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; diff --git a/sudo.tab.h b/sudo.tab.h index 36fc336..ba97b3a 100644 --- a/sudo.tab.h +++ b/sudo.tab.h @@ -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; diff --git a/sudoers.cat b/sudoers.cat index d1714cf..eeeb52d 100644 --- a/sudoers.cat +++ b/sudoers.cat @@ -61,7 +61,7 @@ DDEESSCCRRIIPPTTIIOONN -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 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS -1.6.9p12 January 14, 2008 8 +1.6.9p14 February 19, 2008 8 @@ -579,17 +579,17 @@ SUDOERS(4) MAINTENANCE COMMANDS SUDOERS(4) ssuuddoo). 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 _/_e_t_c_/_s_u_d_o_e_r_s + 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 _/_e_t_c_/_s_u_d_o_e_r_s. 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 ssuuddoo how to behave when no specific - LDAP entries have been matched, this - sudoOption is only meaningful for the - cn=defaults section. This flag is _o_f_f by - default. + is present, _/_e_t_c_/_s_u_d_o_e_r_s does not even + need to exist. Since this option tells + ssuuddoo how to behave when no specific LDAP + entries have been matched, this sudoOption + is only meaningful for the cn=defaults + section. This flag is _o_f_f by default. insults If set, ssuuddoo 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 _s_u_d_o_e_r_s file. This flag is _o_n by default. + noexec If set, all commands run via ssuuddoo 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 ssuuddoo will - behave as if the NOEXEC tag has been set, unless overridden by a EXEC tag. See the description of _N_O_E_X_E_C _a_n_d _E_X_E_C below as well as the "PREVENTING SHELL ESCAPES" @@ -718,10 +716,12 @@ SUDOERS(4) MAINTENANCE COMMANDS SUDOERS(4) Note, however, that turning off _r_o_o_t___s_u_d_o will also prevent root and from running ssuuddooeeddiitt. Disabling _r_o_o_t___s_u_d_o provides no + real additional security; it exists purely + for historical reasons. This flag is _o_n -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 _o_n by default. rootpw If set, ssuuddoo 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 _o_f_f 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 _o_f_f by default. - stay_setuid Normally, when ssuuddoo 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 ssuuddoo 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 ssuuddoo 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 ssuuddoo 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 _f_q_d_n 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 ssuuddoo interpret­ ing the @ sign. Defaults to root. @@ -1114,10 +1112,12 @@ SUDOERS(4) MAINTENANCE COMMANDS SUDOERS(4) check is displayed when ssuuddoo is run by root with the _-_V 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 wwaarrnniinngg. FFIILLEESS - _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what - _/_e_t_c_/_g_r_o_u_p Local groups file - _/_e_t_c_/_n_e_t_g_r_o_u_p List of network groups + _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what + + _/_e_t_c_/_g_r_o_u_p Local groups file + + _/_e_t_c_/_n_e_t_g_r_o_u_p List of network groups EEXXAAMMPPLLEESS Since the _s_u_d_o_e_r_s file is parsed in a single pass, order @@ -1183,7 +1183,7 @@ EEXXAAMMPPLLEESS -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 @@ PPRREEVVEENNTTIINNGG SSHHEELLLL EESSCCAAPPEESS -1.6.9p12 January 14, 2008 22 +1.6.9p14 February 19, 2008 22 @@ -1513,7 +1513,7 @@ CCAAVVEEAATTSS -1.6.9p12 January 14, 2008 23 +1.6.9p14 February 19, 2008 23 @@ -1579,6 +1579,6 @@ DDIISSCCLLAAIIMMEERR -1.6.9p12 January 14, 2008 24 +1.6.9p14 February 19, 2008 24 diff --git a/sudoers.man.in b/sudoers.man.in index 8f2604a..bd4b271 100644 --- a/sudoers.man.in +++ b/sudoers.man.in @@ -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: @@ -150,7 +150,7 @@ .\" ======================================================================== .\" .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 diff --git a/sudoers.pod b/sudoers.pod index 91dfd84..f65db6b 100644 --- a/sudoers.pod +++ b/sudoers.pod @@ -1,4 +1,3 @@ -=cut Copyright (c) 1994-1996, 1998-2005, 2007 Todd C. Miller @@ -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). =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 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 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 how to behave when no specific LDAP +entries have been matched, this sudoOption is only meaningful for the +C section. This flag is I 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 or via command line options. +This option is only available whe B 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. +=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 or via command line options. +This option is only available whe B is built with SELinux support. + =back B: @@ -1021,15 +1034,18 @@ B, and B. =head1 FILES -=over 4 +=over 24 + +=item F<@sysconfdir@/sudoers> -=item F<@sysconfdir@/sudoers>C< > List of who can run what -=item FC< > +=item F + Local groups file -=item FC< > +=item F + List of network groups =back diff --git a/testsudoers.c b/testsudoers.c index 756d331..3b213f3 100644 --- a/testsudoers.c +++ b/testsudoers.c @@ -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--; } } diff --git a/version.h b/version.h index a51e62a..8ab11da 100644 --- a/version.h +++ b/version.h @@ -17,12 +17,12 @@ * 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 */ diff --git a/visudo.cat b/visudo.cat index de2e765..d8c0f43 100644 --- a/visudo.cat +++ b/visudo.cat @@ -61,7 +61,7 @@ OOPPTTIIOONNSS -1.6.9p12 January 14, 2008 1 +1.6.9p14 February 19, 2008 1 @@ -98,8 +98,9 @@ EENNVVIIRROONNMMEENNTT EDITOR Used by visudo if VISUAL is not set FFIILLEESS - _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what - _/_e_t_c_/_s_u_d_o_e_r_s_._t_m_p Lock file for visudo + _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what + + _/_e_t_c_/_s_u_d_o_e_r_s_._t_m_p Lock file for visudo DDIIAAGGNNOOSSTTIICCSS sudoers file busy, try again later. @@ -123,11 +124,10 @@ DDIIAAGGNNOOSSTTIICCSS Warning: runas_default set after old value is in use ... You have a _r_u_n_a_s___d_e_f_a_u_l_t Defaults setting listed in the _s_u_d_o_e_r_s 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 @@ DDIIAAGGNNOOSSTTIICCSS VISUDO(1m) MAINTENANCE COMMANDS VISUDO(1m) + used. This means that entries prior to the _r_u_n_a_s___d_e_f_a_u_l_t setting will match based on the default value of _r_u_n_a_s___d_e_f_a_u_l_t (root) whereas entries aafftteerr the _r_u_n_a_s___d_e_f_a_u_l_t setting will match based on the new @@ -192,7 +193,6 @@ DDIISSCCLLAAIIMMEERR - -1.6.9p12 January 14, 2008 3 +1.6.9p14 February 19, 2008 3 diff --git a/visudo.man.in b/visudo.man.in index 371965c..b1662fa 100644 --- a/visudo.man.in +++ b/visudo.man.in @@ -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: @@ -149,7 +149,7 @@ .\" ======================================================================== .\" .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 diff --git a/visudo.pod b/visudo.pod index 0743b93..d914fab 100644 --- a/visudo.pod +++ b/visudo.pod @@ -1,4 +1,3 @@ -=cut Copyright (c) 1996,1998-2005, 2007 Todd C. Miller 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