-1.8.0a1 March 19, 2010 1
+1.8.0a1 March 21, 2010 1
-1.8.0a1 March 19, 2010 2
+1.8.0a1 March 21, 2010 2
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,
+ s\bsu\bud\bdo\bo will pass the plugin the path to the user's shell and
+ set _\bi_\bm_\bp_\bl_\bi_\be_\bd_\b__\bs_\bh_\be_\bl_\bl to true. This allows s\bsu\bud\bdo\bo with no
+ arguments to be used similarly to _\bs_\bu(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 s\bsu\bud\bdo\bo 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
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 21, 2010 3
-1.8.0a1 March 19, 2010 3
+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
terminal device associated with the session, the value will
be empty, as in tty=.
- host=string
- The local machine's hostname as returned by the
- gethostname() system call.
- lines=int
- The number of lines the user's terminal supports. If there
- is no terminal device available, a default value of 24 is
- used.
-
-1.8.0a1 March 19, 2010 4
+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.
+
+ lines=int
+ The number of lines the user's terminal supports. If there
+ is no terminal device available, a default value of 24 is
+ used.
+
cols=int
The number of columns the user's terminal supports. If
there is no terminal device available, a default value of
will be set.
check_policy
- int (*check_policy)(int argc, char * const argv[]
- char *env_add[], char **command_info[],
- char **argv_out[], char **user_env_out[]);
- The _\bc_\bh_\be_\bc_\bk_\b__\bp_\bo_\bl_\bi_\bc_\by function is called by s\bsu\bud\bdo\bo to determine whether
- the user is allowed to run the specified commands. Returns 1 if
- the command is allowed, 0 if not and -1 on error. On error, the
- plugin may optionally call the conversation function with
- SUDO_CONF_ERROR_MSG to present additional error information to the
- user.
-1.8.0a1 March 19, 2010 5
+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[]);
+
+ The _\bc_\bh_\be_\bc_\bk_\b__\bp_\bo_\bl_\bi_\bc_\by function is called by s\bsu\bud\bdo\bo to determine whether
+ the user is allowed to run the specified commands. Returns 1 if
+ the command is allowed, 0 if not and -1 on error. On error, the
+ plugin may optionally call the conversation function with
+ SUDO_CONF_ERROR_MSG to present additional error information to the
+ user.
+
The function arguments are as follows:
argc
runas_gid=gid
Group ID to run the command as.
- runas_egid=gid
- Effective group ID to run the command as. If not
- specified, the value of _\br_\bu_\bn_\ba_\bs_\b__\bg_\bi_\bd is used.
- runas_groups=list
- The supplementary group vector to use for the command in
- the form of a comma-separated list of group IDs. If
- _\bp_\br_\be_\bs_\be_\br_\bv_\be_\b__\bg_\br_\bo_\bu_\bp_\bs is set, this option is ignored.
- login_class=login_class
- BSD login class to use when setting resource limits and
+1.8.0a1 March 21, 2010 6
-1.8.0a1 March 19, 2010 6
+SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
-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 _\br_\bu_\bn_\ba_\bs_\b__\bg_\bi_\bd is used.
+ runas_groups=list
+ The supplementary group vector to use for the command in
+ the form of a comma-separated list of group IDs. If
+ _\bp_\br_\be_\bs_\be_\br_\bv_\be_\b__\bg_\br_\bo_\bu_\bp_\bs is set, this option is ignored.
+ login_class=login_class
+ BSD login class to use when setting resource limits and
nice value (optional). This option is only set on systems
that support login classes.
system call when executing the command. The plugin is
responsible for allocating and populating the vector.
- user_env_out
- The NULL-terminated environment vector to use when executing
- the command. The plugin is responsible for allocating and
- populating the vector.
-
- list
- int (*list)(int verbose, const char *list_user,
- int argc, char * const argv[]);
- 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
+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
+ populating the vector.
+
+ list
+ int (*list)(int verbose, const char *list_user,
+ int argc, char * const argv[]);
+
+ 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
to present additional error information to the user.
Privileges should be output via the conversation function using
invalidate
void (*invalidate)(int remove);
- The invalidate function is called when s\bsu\bud\bdo\bo is called with the -k
- or -K flag. For policy plugins such as _\bs_\bu_\bd_\bo_\be_\br_\bs that cache
- authentication credentials, this function will invalidate the
- credentials. If the _\br_\be_\bm_\bo_\bv_\be flag is set, the plugin may remove the
- credentials instead of simply invalidating them.
- The invalidate function should be NULL if the plugin does not
- support credential caching.
-
- _\bC_\bo_\bn_\bv_\be_\br_\bs_\ba_\bt_\bi_\bo_\bn _\bA_\bP_\bI
+1.8.0a1 March 21, 2010 8
-1.8.0a1 March 19, 2010 8
+SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
+ The invalidate function is called when s\bsu\bud\bdo\bo is called with the -k
+ or -K flag. For policy plugins such as _\bs_\bu_\bd_\bo_\be_\br_\bs that cache
+ authentication credentials, this function will invalidate the
+ credentials. If the _\br_\be_\bm_\bo_\bv_\be flag is set, the plugin may remove the
+ credentials instead of simply invalidating them.
-SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
+ The invalidate function should be NULL if the plugin does not
+ support credential caching.
+ _\bC_\bo_\bn_\bv_\be_\br_\bs_\ba_\bt_\bi_\bo_\bn _\bA_\bP_\bI
If the plugin needs to interact with the user or display informational
or error messages, it may do so via the conversation function. A
usage.
I\bI/\b/O\bO P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
+
+
+
+
+
+
+
+
+
+
+
+
+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 */
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:
A pointer to the conversation function that may be used by the
_\bs_\bh_\bo_\bw_\b__\bv_\be_\br_\bs_\bi_\bo_\bn 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
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 _\bu_\bs_\be_\br_\b__\bi_\bn_\bf_\bo, the plugin should split on the f\bfi\bir\brs\bst\bt
equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
itself but the _\bv_\ba_\bl_\bu_\be might.
of errno set by the _\be_\bx_\be_\bc_\bv_\be(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);
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 _\bb_\bu_\bf in bytes.
S\bSu\bud\bdo\bo i\bim\bmp\bpl\ble\bem\bme\ben\bnt\bta\bat\bti\bio\bon\bn d\bde\bet\bta\bai\bil\bls\bs
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 { \
-1.8.0a1 March 19, 2010 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.8.0a1 March 21, 2010 13
/* 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 */
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);
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;
}
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;
}
(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) {
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;
#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() */
/* 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
}
/*
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);
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 {
- for (size = 0, from = NewArgv + 1; *from; from++)
- size += strlen(*from) + 1;
- }
-
/* Alloc and build up user_args. */
+ for (size = 0, from = NewArgv + 1; *from; from++)
+ size += strlen(*from) + 1;
user_args = emalloc(size);
for (to = user_args, from = NewArgv + 1; *from; from++) {
n = strlcpy(to, *from, size - (to - user_args));
}
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;
/*
* Local functions.
*/
-static void usage(int) __attribute__((__noreturn__));
static void usage_excl(int) __attribute__((__noreturn__));
/*
{ "runas_user" },
#define ARG_PROGNAME 12
{ "progname" },
-#define NUM_SETTINGS 13
+#define ARG_IMPLIED_SHELL 13
+ { "implied_shell" },
+#define NUM_SETTINGS 14
{ NULL }
};
}
}
- *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;
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)) {
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.
*/
*settingsp = settings;
*env_addp = env_add;
+ *nargc = argc;
+ *nargv = argv;
return(mode | flags);
}
* 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;