summaryrefslogtreecommitdiffstats
path: root/login-utils/su-common.c
diff options
context:
space:
mode:
authorKarel Zak2012-08-29 17:34:26 +0200
committerKarel Zak2012-09-04 17:00:31 +0200
commit7ec6adb1cc00719b10b21a732474fc444acaac95 (patch)
tree87e0d1910afdea7216f7b887fc3b79e4cea19687 /login-utils/su-common.c
parentsu: move generic su code to su-common.c (diff)
downloadkernel-qcow2-util-linux-7ec6adb1cc00719b10b21a732474fc444acaac95.tar.gz
kernel-qcow2-util-linux-7ec6adb1cc00719b10b21a732474fc444acaac95.tar.xz
kernel-qcow2-util-linux-7ec6adb1cc00719b10b21a732474fc444acaac95.zip
runuser: new command (derived from su(1))
This command is based on su(1), the differences: - based on Fedora runuser su(1) patch - not installed with suid rights - allowed for root users only - don't ask for password - uses PAM session, for example: $ cat /etc/pam.d/runuser auth sufficient pam_rootok.so session optional pam_keyinit.so revoke session required pam_limits.so session required pam_unix.so $ cat /etc/pam.d/runuser-l auth include runuser session optional pam_keyinit.so force revoke session include runuser Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/su-common.c')
-rw-r--r--login-utils/su-common.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index 4fc425055..d1fecd701 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -65,8 +65,14 @@ enum
#include "env.h"
/* name of the pam configuration files. separate configs for su and su - */
-#define PAM_SERVICE_NAME "su"
-#define PAM_SERVICE_NAME_L "su-l"
+#define PAM_SRVNAME_SU "su"
+#define PAM_SRVNAME_SU_L "su-l"
+
+#define PAM_SRVNAME_RUNUSER "runuser"
+#define PAM_SRVNAME_RUNUSER_L "runuser-l"
+
+#define _PATH_LOGINDEFS_SU "/etc/defaults/su"
+#define _PATH_LOGINDEFS_RUNUSER "/etc/defaults/runuser"
#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS)
@@ -106,6 +112,8 @@ static bool _pam_cred_established;
static sig_atomic_t volatile caught_signal = false;
static pam_handle_t *pamh = NULL;
+static int restricted = 1; /* zero for root user */
+
static struct option const longopts[] =
{
{"command", required_argument, NULL, 'c'},
@@ -146,7 +154,8 @@ log_su (struct passwd const *pw, bool successful)
openlog (program_invocation_short_name, 0 , LOG_AUTH);
syslog (LOG_NOTICE, "%s(to %s) %s on %s",
- successful ? "" : "FAILED SU ",
+ successful ? "" :
+ su_mode == RUNUSER_MODE ? "FAILED RUNUSER " : "FAILED SU ",
new_user, old_user, tty);
closelog ();
}
@@ -315,11 +324,19 @@ static void
authenticate (const struct passwd *pw)
{
const struct passwd *lpw;
- const char *cp;
+ const char *cp, *srvname = NULL;
int retval;
- retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME,
- pw->pw_name, &conv, &pamh);
+ switch (su_mode) {
+ case SU_MODE:
+ srvname = simulate_login ? PAM_SRVNAME_SU_L : PAM_SRVNAME_SU;
+ break;
+ case RUNUSER_MODE:
+ srvname = simulate_login ? PAM_SRVNAME_RUNUSER_L : PAM_SRVNAME_RUNUSER;
+ break;
+ }
+
+ retval = pam_start (srvname, pw->pw_name, &conv, &pamh);
if (is_pam_failure(retval))
goto done;
@@ -344,6 +361,17 @@ authenticate (const struct passwd *pw)
goto done;
}
+ if (su_mode == RUNUSER_MODE)
+ {
+ /*
+ * This is the only difference between runuser(1) and su(1). The command
+ * runuser(1) does not required authentication, because user is root.
+ */
+ if (restricted)
+ errx(EXIT_FAILURE, _("may not be used by non-root users"));
+ return;
+ }
+
retval = pam_authenticate (pamh, 0);
if (is_pam_failure(retval))
goto done;
@@ -691,7 +719,15 @@ usage (int status)
static
void load_config(void)
{
- logindefs_load_file("/etc/default/su");
+ switch (su_mode) {
+ case SU_MODE:
+ logindefs_load_file(_PATH_LOGINDEFS_SU);
+ break;
+ case RUNUSER_MODE:
+ logindefs_load_file(_PATH_LOGINDEFS_RUNUSER);
+ break;
+ }
+
logindefs_load_file(_PATH_LOGINDEFS);
}
@@ -722,7 +758,6 @@ su_main (int argc, char **argv, int mode)
gid_t groups[NGROUPS_MAX];
int num_supp_groups = 0;
int use_gid = 0;
- int restricted;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);