Fix the -s and -i flags and add support for the "implied_shell"

option.  If the user does not specify a command, sudo will now pass
in the path to the user's shell and set impied_shell=true.  The
plugin can them either check the command normally or return -2 to
cause sudo to print a usage message and exit.
This commit is contained in:
Todd C. Miller
2010-03-21 08:54:06 -04:00
parent 2e27226a0d
commit 6b180d24da
8 changed files with 284 additions and 190 deletions

View File

@@ -61,7 +61,7 @@ SSuuddoo PPlluuggiinn AAPPII
1.8.0a1 March 19, 2010 1
1.8.0a1 March 21, 2010 1
@@ -127,7 +127,7 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
1.8.0a1 March 19, 2010 2
1.8.0a1 March 21, 2010 2
@@ -172,6 +172,15 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
Set to true if the user specified the -i flag, indicating
that the user wishes to run a login shell.
implied_shell=bool
If the user does not specify a program on the command line,
ssuuddoo will pass the plugin the path to the user's shell and
set _i_m_p_l_i_e_d___s_h_e_l_l to true. This allows ssuuddoo with no
arguments to be used similarly to _s_u(1). If the plugin
does not to support this usage, it may return a value of -2
from the check_policy function, which will cause ssuuddoo to
print a usage message and exit.
preserve_groups=bool
Set to true if the user specified the -P flag, indicating
that the user wishes to preserve the group vector instead
@@ -182,18 +191,9 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
command, indicating that the user wishes to ignore any
cached authentication credentials.
login_class=string
BSD login class to use when setting resource limits and
nice value, if specified by the -c flag.
selinux_role=string
SELinux role to use when executing the command, if
specified by the -r flag.
1.8.0a1 March 19, 2010 3
1.8.0a1 March 21, 2010 3
@@ -202,6 +202,14 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
login_class=string
BSD login class to use when setting resource limits and
nice value, if specified by the -c flag.
selinux_role=string
SELinux role to use when executing the command, if
specified by the -r flag.
selinux_type=string
SELinux type to use when executing the command, if
specified by the -t flag.
@@ -247,6 +255,19 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
terminal device associated with the session, the value will
be empty, as in tty=.
1.8.0a1 March 21, 2010 4
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
host=string
The local machine's hostname as returned by the
gethostname() system call.
@@ -256,18 +277,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
is no terminal device available, a default value of 24 is
used.
1.8.0a1 March 19, 2010 4
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
cols=int
The number of columns the user's terminal supports. If
there is no terminal device available, a default value of
@@ -311,6 +320,20 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
will be set.
check_policy
1.8.0a1 March 21, 2010 5
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
int (*check_policy)(int argc, char * const argv[]
char *env_add[], char **command_info[],
char **argv_out[], char **user_env_out[]);
@@ -322,18 +345,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
SUDO_CONF_ERROR_MSG to present additional error information to the
user.
1.8.0a1 March 19, 2010 5
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
The function arguments are as follows:
argc
@@ -377,6 +388,18 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
runas_gid=gid
Group ID to run the command as.
1.8.0a1 March 21, 2010 6
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
runas_egid=gid
Effective group ID to run the command as. If not
specified, the value of _r_u_n_a_s___g_i_d is used.
@@ -388,18 +411,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
login_class=login_class
BSD login class to use when setting resource limits and
1.8.0a1 March 19, 2010 6
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
nice value (optional). This option is only set on systems
that support login classes.
@@ -442,6 +453,19 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
system call when executing the command. The plugin is
responsible for allocating and populating the vector.
1.8.0a1 March 21, 2010 7
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
user_env_out
The NULL-terminated environment vector to use when executing
the command. The plugin is responsible for allocating and
@@ -454,18 +478,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
List available privileges for the invoking user. Returns 1 on
success, 0 on failure and -1 on error. On error, the plugin may
optionally call the conversation function with SUDO_CONF_ERROR_MSG
1.8.0a1 March 19, 2010 7
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
to present additional error information to the user.
Privileges should be output via the conversation function using
@@ -509,6 +521,17 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
invalidate
void (*invalidate)(int remove);
1.8.0a1 March 21, 2010 8
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
The invalidate function is called when ssuuddoo is called with the -k
or -K flag. For policy plugins such as _s_u_d_o_e_r_s that cache
authentication credentials, this function will invalidate the
@@ -520,18 +543,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
_C_o_n_v_e_r_s_a_t_i_o_n _A_P_I
1.8.0a1 March 19, 2010 8
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
If the plugin needs to interact with the user or display informational
or error messages, it may do so via the conversation function. A
plugin should not attempt to read directly from the standard input or
@@ -566,6 +577,27 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
usage.
II//OO PPlluuggiinn AAPPII
1.8.0a1 March 21, 2010 9
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
struct io_plugin {
#define SUDO_IO_PLUGIN 2
unsigned int type; /* always SUDO_IO_PLUGIN */
@@ -586,18 +618,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
disabled, such as passwords). The log_output function receives output
from the pseudo-tty that is suitable for replaying the user's session
at a later time. Either log_input or log_output may be NULL. If the
1.8.0a1 March 19, 2010 9
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
open function returns 0, no I/O will be sent to the plugin.
The io_plugin struct has the following fields:
@@ -632,6 +652,18 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
A pointer to the conversation function that may be used by the
_s_h_o_w___v_e_r_s_i_o_n function to display version information (see
show_version below). The conversation function may also be
1.8.0a1 March 21, 2010 10
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
used to display additional error message to the user.
settings
@@ -653,17 +685,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
the form of "name=value" strings. The vector is terminated by
a NULL pointer.
1.8.0a1 March 19, 2010 10
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
equal sign ('=') since the _n_a_m_e field will never include one
itself but the _v_a_l_u_e might.
@@ -697,6 +718,18 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
of errno set by the _e_x_e_c_v_e(2) system call. If the command was
successfully executed, the value of error is 0.
1.8.0a1 March 21, 2010 11
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
show_version
int (*show_version)(int verbose);
@@ -718,18 +751,6 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
The function arguments are as follows:
1.8.0a1 March 19, 2010 11
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
buf The buffer containing user input.
len The length of _b_u_f in bytes.
@@ -757,6 +778,24 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
SSuuddoo iimmpplleemmeennttaattiioonn ddeettaaiillss
Version macros:
1.8.0a1 March 21, 2010 12
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
@@ -787,6 +826,33 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
1.8.0a1 March 19, 2010 12
1.8.0a1 March 21, 2010 13

View File

@@ -139,7 +139,7 @@
.\" ========================================================================
.\"
.IX Title "SUDO_PLUGIN @mansectsu@"
.TH SUDO_PLUGIN @mansectsu@ "March 19, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
.TH SUDO_PLUGIN @mansectsu@ "March 21, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -295,6 +295,15 @@ the user wishes to preserve the environment.
.IX Item "login_shell=bool"
Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that
the user wishes to run a login shell.
.IP "implied_shell=bool" 4
.IX Item "implied_shell=bool"
If the user does not specify a program on the command line, \fBsudo\fR
will pass the plugin the path to the user's shell and set
\&\fIimplied_shell\fR to true. This allows \fBsudo\fR with no arguments
to be used similarly to \fIsu\fR\|(1). If the plugin does not to support
this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR
function, which will cause \fBsudo\fR to print a usage message and
exit.
.IP "preserve_groups=bool" 4
.IX Item "preserve_groups=bool"
Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that

View File

@@ -180,6 +180,16 @@ the user wishes to preserve the environment.
Set to true if the user specified the C<-i> flag, indicating that
the user wishes to run a login shell.
=item implied_shell=bool
If the user does not specify a program on the command line, B<sudo>
will pass the plugin the path to the user's shell and set
I<implied_shell> to true. This allows B<sudo> with no arguments
to be used similarly to L<su(1)>. If the plugin does not to support
this usage, it may return a value of -2 from the C<check_policy>
function, which will cause B<sudo> to print a usage message and
exit.
=item preserve_groups=bool
Set to true if the user specified the C<-P> flag, indicating that

View File

@@ -262,12 +262,6 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
/* Set login class if applicable. */
set_loginclass(sudo_user.pw);
#if 0 /* XXX - later */
/* Update initial shell now that runas is set. */
if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
NewArgv[0] = runas_pw->pw_shell;
#endif
/* XXX */
user_env = envp; /* stash for later */
@@ -305,11 +299,17 @@ sudoers_policy_main(int argc, char * const argv[], char *env_add[],
return -1;
}
/* Local copy of argv */
/*
* Make a local copy of argc/argv, with special handling
* for the '-e', '-i' or '-s' options.
* XXX - handle sudoedit
*/
NewArgv = emalloc2(argc + 1, sizeof(char *));
memcpy(NewArgv, argv, argc * sizeof(char *));
NewArgv[argc] = NULL;
NewArgc = argc;
if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
NewArgv[0] = runas_pw->pw_shell;
/* Set environ to contents of user_env. */
env_init(user_env);
@@ -387,9 +387,9 @@ sudoers_policy_main(int argc, char * const argv[], char *env_add[],
if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
def_preserve_groups = TRUE;
/* If no command line args and "set_home" is not set, error out. */
/* If no command line args and "shell_noargs" is not set, error out. */
if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
/* XXX - error message */
rval = -2; /* usage error */
goto done;
}
@@ -447,7 +447,7 @@ sudoers_policy_main(int argc, char * const argv[], char *env_add[],
goto done;
} else if (cmnd_status == NOT_FOUND) {
//audit_failure(NewArgv, "%s: command not found", user_cmnd);
warningx("command not found", user_cmnd);
warningx("%s: command not found", user_cmnd);
goto done;
}
@@ -622,12 +622,6 @@ init_vars(char * const envp[])
(void) tzset(); /* set the timezone if applicable */
#endif /* HAVE_TZSET */
#if 0
/* Default value for cmnd and cwd, overridden later. */
if (user_cmnd == NULL)
user_cmnd = NewArgv[0];
#endif
for (ep = envp; *ep; ep++) {
/* XXX - don't fill in if empty string */
switch (**ep) {
@@ -644,9 +638,7 @@ init_vars(char * const envp[])
user_path = *ep + 5;
break;
case 'S':
if (strncmp("SHELL=", *ep, 6) == 0)
user_shell = *ep + 6;
else if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0)
if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0)
user_prompt = *ep + 12;
else if (strncmp("SUDO_USER=", *ep, 10) == 0)
prev_user = *ep + 10;
@@ -683,8 +675,6 @@ init_vars(char * const envp[])
#ifdef HAVE_MBR_CHECK_MEMBERSHIP
mbr_uid_to_uuid(user_uid, user_uuid);
#endif
if (user_shell == NULL || *user_shell == '\0')
user_shell = estrdup(sudo_user.pw->pw_shell);
/* It is now safe to use log_error() and set_perms() */
@@ -692,43 +682,6 @@ init_vars(char * const envp[])
/* may call log_error() */
set_fqdn();
}
#if 0 /* XXX need to adapt this in sudo.c */
/*
* If we were given the '-e', '-i' or '-s' options we need to redo
* NewArgv and NewArgc.
*/
if (ISSET(sudo_mode, MODE_EDIT)) {
NewArgv--;
NewArgc++;
NewArgv[0] = "sudoedit";
} else if (ISSET(sudo_mode, MODE_SHELL)) {
char **av;
/* Allocate an extra slot for execve() failure (ENOEXEC). */
av = (char **) emalloc2(5, sizeof(char *));
av++;
av[0] = user_shell; /* may be updated later */
if (NewArgc > 0) {
size_t size;
char *cmnd, *src, *dst, *end;
size = (size_t) (NewArgv[NewArgc - 1] - NewArgv[0]) +
strlen(NewArgv[NewArgc - 1]) + 1;
cmnd = emalloc(size);
src = NewArgv[0];
dst = cmnd;
for (end = src + size - 1; src < end; src++, dst++)
*dst = *src == 0 ? ' ' : *src;
*dst = '\0';
av[1] = "-c";
av[2] = cmnd;
NewArgc = 2;
}
av[++NewArgc] = NULL;
NewArgv = av;
}
#endif
}
/*
@@ -748,6 +701,10 @@ set_cmnd(sudo_mode)
rval = FOUND;
user_stat = emalloc(sizeof(struct stat));
/* Default value for cmnd, overridden below. */
if (user_cmnd == NULL)
user_cmnd = NewArgv[0];
if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
set_perms(PERM_RUNAS);
@@ -766,16 +723,9 @@ set_cmnd(sudo_mode)
char *to, **from;
size_t size, n;
/* If we didn't realloc NewArgv it is contiguous so just count. */
if (!ISSET(sudo_mode, MODE_SHELL)) {
size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) +
strlen(NewArgv[NewArgc-1]) + 1;
} else {
/* Alloc and build up user_args. */
for (size = 0, from = NewArgv + 1; *from; from++)
size += strlen(*from) + 1;
}
/* Alloc and build up user_args. */
user_args = emalloc(size);
for (to = user_args, from = NewArgv + 1; *from; from++) {
n = strlcpy(to, *from, size - (to - user_args));
@@ -1197,6 +1147,11 @@ deserialize_info(char * const settings[], char * const user_info[])
}
continue;
}
if (MATCHES(*cur, "implied_shell=")) {
if (atobool(*cur + sizeof("implied_shell=") - 1) == TRUE)
SET(flags, MODE_IMPLIED_SHELL);
continue;
}
if (MATCHES(*cur, "preserve_groups=")) {
SET(flags, MODE_PRESERVE_GROUPS);
continue;

View File

@@ -48,7 +48,6 @@ struct sudo_user {
struct stat *cmnd_stat;
char *name;
char *path;
char *shell;
char *tty;
char *ttypath;
char *host;
@@ -156,7 +155,6 @@ struct sudo_user {
#define user_passwd (sudo_user.pw->pw_passwd)
#define user_uuid (sudo_user.uuid)
#define user_dir (sudo_user.pw->pw_dir)
#define user_shell (sudo_user.shell)
#define user_ngroups (sudo_user.ngroups)
#define user_groups (sudo_user.groups)
#define user_tty (sudo_user.tty)

View File

@@ -66,7 +66,6 @@ const char *list_user, *runas_user, *runas_group;
/*
* Local functions.
*/
static void usage(int) __attribute__((__noreturn__));
static void usage_excl(int) __attribute__((__noreturn__));
/*
@@ -102,7 +101,9 @@ static struct sudo_settings {
{ "runas_user" },
#define ARG_PROGNAME 12
{ "progname" },
#define NUM_SETTINGS 13
#define ARG_IMPLIED_SHELL 13
{ "implied_shell" },
#define NUM_SETTINGS 14
{ NULL }
};
@@ -295,13 +296,13 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
}
}
*nargc = argc - optind;
*nargv = argv + optind;
argc -= optind;
argv += optind;
if (!mode) {
/* Defer -k mode setting until we know whether it is a flag or not */
if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) {
if (*nargc == 0) {
if (argc == 0) {
mode = MODE_INVALIDATE; /* -k by itself */
sudo_settings[ARG_IGNORE_TICKET].value = NULL;
valid_flags = 0;
@@ -311,7 +312,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
mode = MODE_RUN; /* running a command */
}
if (*nargc > 0 && mode == MODE_LIST)
if (argc > 0 && mode == MODE_LIST)
mode = MODE_CHECK;
if (ISSET(flags, MODE_LOGIN_SHELL)) {
@@ -347,15 +348,55 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
warningx("the `-A' and `-S' options may not be used together");
usage(1);
}
if ((*nargc == 0 && mode == MODE_EDIT) ||
(*nargc > 0 && !ISSET(mode, MODE_RUN | MODE_EDIT | MODE_CHECK)))
if ((argc == 0 && mode == MODE_EDIT) ||
(argc > 0 && !ISSET(mode, MODE_RUN | MODE_EDIT | MODE_CHECK)))
usage(1);
if (*nargc == 0 && mode == MODE_RUN && !ISSET(flags, MODE_SHELL))
if (argc == 0 && mode == MODE_RUN && !ISSET(flags, MODE_SHELL)) {
SET(flags, (MODE_IMPLIED_SHELL | MODE_SHELL));
sudo_settings[ARG_IMPLIED_SHELL].value = "true";
}
if (mode == MODE_HELP)
usage(0);
/*
* For shell mode we need to rewrite argv
*/
if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
char **av;
int ac;
if (argc == 0) {
/* just the shell */
ac = argc + 1;
av = emalloc2(ac + 1, sizeof(char *));
memcpy(av + 1, argv, argc * sizeof(char *));
} else {
/* shell -c "command" */
size_t size;
char *src, *dst, *end;
/* length of the command + NUL terminator */
size = (size_t)(argv[argc - 1] - argv[0]) +
strlen(argv[argc - 1]) + 1;
ac = 3;
av = emalloc2(ac + 1, sizeof(char *));
av[1] = "-c";
av[2] = dst = emalloc(size);
src = argv[0];
for (end = src + size - 1; src < end; src++, dst++)
*dst = *src == 0 ? ' ' : *src;
*dst = '\0';
}
av[0] = (char *)user_details.shell; /* plugin may override shell */
av[ac] = NULL;
argv = av;
argc = ac;
}
/*
* Format setting_pairs into settings array.
*/
@@ -375,6 +416,8 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
*settingsp = settings;
*env_addp = env_add;
*nargc = argc;
*nargv = argv;
return(mode | flags);
}
@@ -388,7 +431,7 @@ usage_out(const char *buf)
* Give usage message and exit.
* The actual usage strings are in sudo_usage.h for configure substitution.
*/
static void
void
usage(int exit_val)
{
struct lbuf lbuf;

View File

@@ -224,8 +224,11 @@ main(int argc, char *argv[], char *envp[])
ok = policy_plugin.u.policy->check_policy(nargc, nargv, env_add,
&command_info, &argv_out, &user_env_out);
sudo_debug(8, "policy plugin returns %d", ok);
if (ok != TRUE)
exit(ok); /* plugin printed error message */
if (ok != TRUE) {
if (ok == -2)
usage(1);
exit(1); /* plugin printed error message */
}
command_info_to_details(command_info, &command_details);
/* Restore coredumpsize resource limit before running. */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
@@ -330,6 +333,12 @@ get_user_info(struct user_details *ud)
errorx(1, "unable to allocate memory");
ud->username = user_info[i] + sizeof("user=") - 1;
/* Stash user's shell for use with the -s flag; don't pass to plugin. */
if ((ud->shell = getenv("SHELL")) == NULL || ud->shell[0] == '\0') {
ud->shell = pw->pw_shell[0] ? pw->pw_shell : _PATH_BSHELL;
}
ud->shell = estrdup(ud->shell);
easprintf(&user_info[++i], "uid=%lu", (unsigned long)ud->uid);
easprintf(&user_info[++i], "euid=%lu", (unsigned long)ud->euid);
easprintf(&user_info[++i], "gid=%lu", (unsigned long)ud->gid);

View File

@@ -117,6 +117,7 @@ struct user_details {
const char *cwd;
const char *tty;
const char *host;
const char *shell;
GETGROUPS_T *groups;
int ngroups;
int ts_cols;
@@ -210,6 +211,9 @@ int exec_setup(struct command_details *details);
extern int debug_level;
extern struct plugin_container_list io_plugins;
/* parse_args.c */
void usage(int) __attribute__((__noreturn__));
#ifndef errno
extern int errno;
#endif