From d25f1af881c2cc2ad09053ce57d4a63677aa959b Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 9 Jul 2010 17:08:58 -0400 Subject: [PATCH] Add support for a sudo-i pam.d file to be used for "sudo -i". Adapted from a RedHat patch. --HG-- branch : 1.7 --- auth/pam.c | 8 +++++++- config.h.in | 3 +++ configure | 51 +++++++++++++++++++++++++++++++++++++-------------- configure.in | 14 ++++++++++++++ env.c | 3 +-- sudo.c | 11 +++++------ sudo.h | 3 ++- 7 files changed, 69 insertions(+), 24 deletions(-) diff --git a/auth/pam.c b/auth/pam.c index 257b64d86..9b04219fc 100644 --- a/auth/pam.c +++ b/auth/pam.c @@ -93,7 +93,13 @@ pam_init(pw, promptp, auth) if (auth != NULL) auth->data = (void *) &pam_status; pam_conv.conv = sudo_conv; - pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh); +#ifdef HAVE_PAM_LOGIN + if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) + pam_status = pam_start("sudo-i", pw->pw_name, &pam_conv, &pamh); + else +#endif + pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh); + if (pam_status != PAM_SUCCESS) { log_error(USE_ERRNO|NO_EXIT|NO_MAIL, "unable to initialize PAM"); return(AUTH_FATAL); diff --git a/config.h.in b/config.h.in index 47a7ed3e3..eeb444f06 100644 --- a/config.h.in +++ b/config.h.in @@ -361,6 +361,9 @@ /* Define to 1 if you use PAM authentication. */ #undef HAVE_PAM +/* Define to 1 if you use a specific PAM session for sudo -i. */ +#undef HAVE_PAM_LOGIN + /* Define to 1 if you have the header file. */ #undef HAVE_PAM_PAM_APPL_H diff --git a/configure b/configure index 6f33c65dd..e2bc5b340 100755 --- a/configure +++ b/configure @@ -995,6 +995,7 @@ enable_libtool_lock with_noexec with_netsvc enable_sia +with_pam_login enable_pam_session enable_zlib ' @@ -1742,6 +1743,7 @@ Optional Packages: --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-noexec=PATH fully qualified pathname of sudo_noexec.so --with-netsvc[=PATH] path to netsvc.conf + --with-pam-login enable specific PAM session for sudo -i Some influential environment variables: CC C compiler command @@ -6619,13 +6621,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:6622: $ac_compile\"" >&5) + (eval echo "\"\$as_me:6624: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:6625: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:6627: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:6628: output\"" >&5) + (eval echo "\"\$as_me:6630: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -7830,7 +7832,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 7833 "configure"' > conftest.$ac_ext + echo '#line 7835 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -9223,11 +9225,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:9226: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9228: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9230: \$? = $ac_status" >&5 + echo "$as_me:9232: \$? = $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. @@ -9562,11 +9564,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:9565: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9567: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9569: \$? = $ac_status" >&5 + echo "$as_me:9571: \$? = $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. @@ -9667,11 +9669,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:9670: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9672: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9674: \$? = $ac_status" >&5 + echo "$as_me:9676: \$? = $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 @@ -9722,11 +9724,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:9725: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9727: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9729: \$? = $ac_status" >&5 + echo "$as_me:9731: \$? = $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 @@ -12089,7 +12091,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12092 "configure" +#line 12094 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12185,7 +12187,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12188 "configure" +#line 12190 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -16141,6 +16143,25 @@ done AUTH_OBJS="$AUTH_OBJS pam.o"; AUTH_EXCL=PAM + + +# Check whether --with-pam-login was given. +if test "${with_pam_login+set}" = set; then : + withval=$with_pam_login; case $with_pam_login in + yes) $as_echo "#define HAVE_PAM_LOGIN 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM login" >&5 +$as_echo_n "checking whether to use PAM login... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ;; + no) ;; + *) as_fn_error "\"--with-pam-login does not take an argument.\"" "$LINENO" 5 + ;; + esac +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM session support" >&5 $as_echo_n "checking whether to use PAM session support... " >&6; } # Check whether --enable-pam_session was given. @@ -16166,6 +16187,7 @@ else $as_echo "yes" >&6; } fi + case $host in *-*-linux*|*-*-solaris*) # dgettext() may be defined to dgettext_libintl in the @@ -20542,5 +20564,6 @@ fi + diff --git a/configure.in b/configure.in index d7ad654de..5e04e9533 100644 --- a/configure.in +++ b/configure.in @@ -2100,6 +2100,18 @@ if test ${with_pam-"no"} != "no"; then AC_DEFINE(HAVE_PAM) AUTH_OBJS="$AUTH_OBJS pam.o"; AUTH_EXCL=PAM + + AC_ARG_WITH(pam-login, [AS_HELP_STRING([--with-pam-login], [enable specific PAM session for sudo -i])], + [case $with_pam_login in + yes) AC_DEFINE([HAVE_PAM_LOGIN]) + AC_MSG_CHECKING(whether to use PAM login) + AC_MSG_RESULT(yes) + ;; + no) ;; + *) AC_MSG_ERROR(["--with-pam-login does not take an argument."]) + ;; + esac]) + AC_MSG_CHECKING(whether to use PAM session support) AC_ARG_ENABLE(pam_session, [AS_HELP_STRING([--disable-pam-session], [Disable PAM session support])], @@ -2113,6 +2125,7 @@ if test ${with_pam-"no"} != "no"; then AC_MSG_WARN([Ignoring unknown argument to --enable-pam-session: $enableval]) ;; esac], AC_MSG_RESULT(yes)) + case $host in *-*-linux*|*-*-solaris*) # dgettext() may be defined to dgettext_libintl in the @@ -2828,6 +2841,7 @@ AH_TEMPLATE(HAVE_LDAP, [Define to 1 if you use LDAP for sudoers.]) AH_TEMPLATE(HAVE_LINUX_AUDIT, [Define to 1 to enable Linux audit support.]) 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_PAM_LOGIN, [Define to 1 if you use a specific PAM session for sudo -i.]) 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.]) diff --git a/env.c b/env.c index 366df078c..80f3a990c 100644 --- a/env.c +++ b/env.c @@ -584,8 +584,7 @@ matches_env_keep(var) * Also adds sudo-specific variables (SUDO_*). */ void -rebuild_env(sudo_mode, noexec) - int sudo_mode; +rebuild_env(noexec) int noexec; { char **old_envp, **ep, *cp, *ps1; diff --git a/sudo.c b/sudo.c index b219ea484..e9307d08d 100644 --- a/sudo.c +++ b/sudo.c @@ -108,7 +108,7 @@ /* * Prototypes */ -static void init_vars __P((int, char **)); +static void init_vars __P((char **)); static int set_cmnd __P((int)); static void initial_setup __P((void)); static void set_loginclass __P((struct passwd *)); @@ -147,7 +147,7 @@ sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp; char *runas_user; char *runas_group; static struct sudo_nss_list *snl; -static int sudo_mode; +int sudo_mode; /* For getopt(3) */ extern char *optarg; @@ -263,7 +263,7 @@ main(argc, argv, envp) if (user_cmnd == NULL && NewArgc == 0) usage(1); - init_vars(sudo_mode, envp); /* XXX - move this later? */ + init_vars(envp); /* XXX - move this later? */ #ifdef USING_NONUNIX_GROUPS sudo_nonunix_groupcheck_init(); /* initialise nonunix groups impl */ @@ -414,7 +414,7 @@ main(argc, argv, envp) def_env_reset = FALSE; /* Build a new environment that avoids any nasty bits. */ - rebuild_env(sudo_mode, def_noexec); + rebuild_env(def_noexec); /* Fill in passwd struct based on user we are authenticating as. */ auth_pw = get_authpw(); @@ -551,8 +551,7 @@ main(argc, argv, envp) * load the ``interfaces'' array. */ static void -init_vars(sudo_mode, envp) - int sudo_mode; +init_vars(envp) char **envp; { char *p, **ep, thost[MAXHOSTNAMELEN + 1]; diff --git a/sudo.h b/sudo.h index 0aedecbdf..6ce915f73 100644 --- a/sudo.h +++ b/sudo.h @@ -230,7 +230,7 @@ void env_init __P((int lazy)); void init_envtables __P((void)); void insert_env_vars __P((struct list_member *)); void read_env_file __P((const char *, int)); -void rebuild_env __P((int, int)); +void rebuild_env __P((int)); void validate_env_vars __P((struct list_member *)); /* exec.c */ @@ -355,6 +355,7 @@ extern struct passwd *auth_pw, *list_pw; extern int tgetpass_flags; extern int long_list; +extern int sudo_mode; extern uid_t timestamp_uid; /* XXX - conflicts with the one in visudo */ int run_command __P((const char *path, char *argv[], char *envp[], uid_t uid, int dowait)); -- 2.40.0