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>
This commit is contained in:
parent
cf1a99dacc
commit
7ec6adb1cc
|
@ -138,6 +138,7 @@ tests/run.sh.trs
|
|||
/resizepart
|
||||
/rev
|
||||
/rtcwake
|
||||
/runuser
|
||||
/sample-mkfs
|
||||
/sample-partitions
|
||||
/sample-superblocks
|
||||
|
|
|
@ -1154,6 +1154,15 @@ UL_REQUIRES_HAVE([su], [security_pam_misc_h], [PAM header file])
|
|||
AM_CONDITIONAL(BUILD_SU, test "x$build_su" = xyes)
|
||||
|
||||
|
||||
AC_ARG_ENABLE([runuser],
|
||||
AS_HELP_STRING([--disable-runuser], [do not build runuser]),
|
||||
[], enable_runuser=yes
|
||||
)
|
||||
UL_BUILD_INIT([runuser])
|
||||
UL_REQUIRES_HAVE([runuser], [security_pam_misc_h], [PAM header file])
|
||||
AM_CONDITIONAL(BUILD_RUNUSER, test "x$build_runuser" = xyes)
|
||||
|
||||
|
||||
AC_ARG_ENABLE([schedutils],
|
||||
AS_HELP_STRING([--disable-schedutils], [do not build chrt, ionice, teskset]),
|
||||
[], enable_schedutils=yes
|
||||
|
|
|
@ -92,6 +92,19 @@ su_LDADD = $(LDADD) -lpam -lpam_misc
|
|||
endif
|
||||
|
||||
|
||||
if BUILD_RUNUSER
|
||||
bin_PROGRAMS += runuser
|
||||
dist_man_MANS += login-utils/runuser.1
|
||||
runuser_SOURCES = \
|
||||
login-utils/runuser.c \
|
||||
login-utils/su-common.c \
|
||||
login-utils/su-common.h \
|
||||
login-utils/logindefs.c \
|
||||
login-utils/logindefs.h
|
||||
runuser_LDADD = $(LDADD) -lpam -lpam_misc
|
||||
endif
|
||||
|
||||
|
||||
if BUILD_NEWGRP
|
||||
usrbin_exec_PROGRAMS += newgrp
|
||||
dist_man_MANS += login-utils/newgrp.1
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
.TH RUNUSER "1" "August 2012" "util-linux" "User Commands"
|
||||
.SH NAME
|
||||
runuser \- run a command with substitute user and group ID
|
||||
.SH SYNOPSIS
|
||||
.B runuser
|
||||
[options...] [\-] [user [args...]]
|
||||
.SH DESCRIPTION
|
||||
.B runuser
|
||||
allows to run commands with substitute user and group ID.
|
||||
The difference between the commands
|
||||
.B runuser
|
||||
and
|
||||
.B su
|
||||
is that
|
||||
.B runuser
|
||||
does not ask for password, because it may be executed by root user only.
|
||||
The command
|
||||
.B runuser
|
||||
does not have to be installed with suid permissions.
|
||||
.PP
|
||||
When called without arguments
|
||||
.B runuser
|
||||
defaults to running an interactive shell as
|
||||
.IR root .
|
||||
.PP
|
||||
For backward compatibility
|
||||
.B runuser
|
||||
defaults to not change the current directory and to only set the
|
||||
environment variables
|
||||
.B HOME
|
||||
and
|
||||
.B SHELL
|
||||
(plus
|
||||
.B USER
|
||||
and
|
||||
.B LOGNAME
|
||||
if the target
|
||||
.I user
|
||||
is not root). It is recommended to always use the
|
||||
.B \-\-login
|
||||
option (instead it's shortcut
|
||||
.BR \- )
|
||||
to avoid side effects caused by mixing environments.
|
||||
.PP
|
||||
This version of
|
||||
.B runuser
|
||||
uses PAM for session management.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-c\fR \fIcommand\fR, \fB\-\-command\fR=\fIcommand\fR
|
||||
Pass
|
||||
.I command
|
||||
to the shell with the
|
||||
.B \-c
|
||||
option.
|
||||
.TP
|
||||
\fB\-\-session\-command\fR=\fIcommand\fR
|
||||
Same as
|
||||
.B \-c
|
||||
but do not create a new session (discouraged).
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-fast\fR
|
||||
Pass
|
||||
.B \-f
|
||||
to the shell which may or may not be useful depending on the
|
||||
shell.
|
||||
.TP
|
||||
\fB\-g\fR, \fB\-\-group\fR=\fIgroup\fR\fR
|
||||
specify the primary group, this option is allowed for root user only
|
||||
.TP
|
||||
\fB\-G\fR, \fB\-\-supp-group\fR=\fIgroup\fR\fR
|
||||
specify a supplemental group, this option is allowed for root user only
|
||||
.TP
|
||||
\fB\-\fR, \fB\-l\fR, \fB\-\-login\fR
|
||||
Starts the shell as login shell with an environment similar to a real
|
||||
login:
|
||||
.RS 10
|
||||
.TP
|
||||
o
|
||||
clears all environment variables except for
|
||||
.B TERM
|
||||
.TP
|
||||
o
|
||||
initializes the environment variables
|
||||
.BR HOME ,
|
||||
.BR SHELL ,
|
||||
.BR USER ,
|
||||
.BR LOGNAME ,
|
||||
.B PATH
|
||||
.TP
|
||||
o
|
||||
changes to the target user's home directory
|
||||
.TP
|
||||
o
|
||||
sets argv[0] of the shell to
|
||||
.RB ' \- '
|
||||
in order to make the shell a login shell
|
||||
.RE
|
||||
.TP
|
||||
\fB\-m\fR, \fB\-p\fR, \fB\-\-preserve-environment\fR
|
||||
Preserves the whole environment, ie does not set
|
||||
.BR HOME ,
|
||||
.BR SHELL ,
|
||||
.B USER
|
||||
nor
|
||||
.BR LOGNAME .
|
||||
.TP
|
||||
\fB\-s\fR \fISHELL\fR, \fB\-\-shell\fR=\fISHELL\fR
|
||||
Runs the specified shell instead of the default. The shell to run is
|
||||
selected according to the following rules in order:
|
||||
.RS 10
|
||||
.TP
|
||||
o
|
||||
the shell specified with
|
||||
.B \-\-shell
|
||||
.TP
|
||||
o
|
||||
The shell specified in the environment variable
|
||||
.B SHELL
|
||||
if the
|
||||
.B \-\-preserve-environment
|
||||
option is used.
|
||||
.TP
|
||||
o
|
||||
the shell listed in the passwd entry of the target user
|
||||
.TP
|
||||
o
|
||||
/bin/sh
|
||||
.RE
|
||||
.IP
|
||||
If the target user has a restricted shell (i.e. not listed in
|
||||
/etc/shells) the
|
||||
.B \-\-shell
|
||||
option and the
|
||||
.B SHELL
|
||||
environment variables are ignored unless the calling user is root.
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
Display help text and exit.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Display version information and exit.
|
||||
.SH CONFIG FILES
|
||||
.B runuser
|
||||
reads the
|
||||
.I /etc/default/runuser
|
||||
and
|
||||
.I /etc/login.defs
|
||||
configuration files. The following configuration items are relevant
|
||||
for
|
||||
.BR runuser :
|
||||
.PP
|
||||
.B ENV_PATH
|
||||
(string)
|
||||
.RS 4
|
||||
Defines the PATH environment variable for a regular user. The
|
||||
default value is
|
||||
.IR /usr/local/bin:\:/bin:\:/usr/bin .
|
||||
.RE
|
||||
.PP
|
||||
.B ENV_ROOTPATH
|
||||
(string)
|
||||
.br
|
||||
.B ENV_SUPATH
|
||||
(string)
|
||||
.RS 4
|
||||
Defines the PATH environment variable for root. The default value is
|
||||
.IR /usr/local/sbin:\:/usr/local/bin:\:/sbin:\:/bin:\:/usr/sbin:\:/usr/bin .
|
||||
.RE
|
||||
.PP
|
||||
.B ALWAYS_SET_PATH
|
||||
(boolean)
|
||||
.RS 4
|
||||
If set to
|
||||
.I yes
|
||||
and \-\-login and \-\-preserve\-environment were not specified
|
||||
.B runuser
|
||||
initializes
|
||||
.BR PATH .
|
||||
.RE
|
||||
.SH EXIT STATUS
|
||||
.B runuser
|
||||
normally returns the exit status of the command it executed. If the
|
||||
command was killed by a signal,
|
||||
.B runuser
|
||||
returns the number of the signal plus 128.
|
||||
.PP
|
||||
Exit status generated by
|
||||
.B runuser
|
||||
itself:
|
||||
.RS 10
|
||||
.TP
|
||||
1
|
||||
Generic error before executing the requested command
|
||||
.TP
|
||||
126
|
||||
The requested command could not be executed
|
||||
.TP
|
||||
127
|
||||
The requested command could was not found
|
||||
.RE
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP 17
|
||||
/etc/pam.d/runuser
|
||||
default PAM configuration file
|
||||
.TP
|
||||
/etc/pam.d/runuser-l
|
||||
PAM configuration file if \-\-login is specified
|
||||
.TP
|
||||
/etc/default/runuser
|
||||
runuser specific logindef config file
|
||||
.TP
|
||||
/etc/login.defs
|
||||
global logindef config file
|
||||
.PD 1
|
||||
.SH "SEE ALSO"
|
||||
.BR pam (8),
|
||||
.BR shells (5),
|
||||
.BR login.defs (5),
|
||||
.BR su (1)
|
||||
.SH AUTHOR
|
||||
Derived from coreutils' su which was based on an implemenation from
|
||||
David MacKenzie and Fedora runuser command from Dan Walsh.
|
||||
.SH AVAILABILITY
|
||||
The runuser command is part of the util-linux package and is
|
||||
available from
|
||||
.UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/
|
||||
Linux Kernel Archive
|
||||
.UE .
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "su-common.h"
|
||||
|
||||
int main(int argv, char **argc)
|
||||
{
|
||||
return su_main(argv, argc, RUNUSER_MODE);
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue