Add "list" pseudo-command to allow a user to list another user's

privs.  Previously, only root or a user with the ability to run any
command as either root or the target user on the current host could
use the -U option.  For "sudo -l [-U otheruser] command", NewArgv[0]
is now set to "list" (just like "sudo -l") and the actual command
to be checked starts with NewArgv[1].
This commit is contained in:
Todd C. Miller
2022-12-11 13:46:00 -07:00
parent 8c16c8faf6
commit a514a6eed5
9 changed files with 2577 additions and 2418 deletions

View File

@@ -442,14 +442,21 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
sudoers_gc_remove(GC_PTR, NewArgv);
free(NewArgv);
}
NewArgc = argc;
NewArgv = reallocarray(NULL, NewArgc + 2, sizeof(char *));
NewArgv = reallocarray(NULL, argc + 2, sizeof(char *));
if (NewArgv == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
sudoers_gc_add(GC_PTR, NewArgv);
memcpy(NewArgv, argv, argc * sizeof(char *));
if (ISSET(sudo_mode, MODE_CHECK)) {
/* For "sudo -l [-U otheruser] command" */
NewArgv[0] = (char *)"list";
memcpy(NewArgv + 1, argv, argc * sizeof(char *));
NewArgc = argc + 1;
} else {
memcpy(NewArgv, argv, argc * sizeof(char *));
NewArgc = argc;
}
NewArgv[NewArgc] = NULL;
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL) {
NewArgv[0] = strdup(runas_pw->pw_shell);
@@ -646,8 +653,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
} else if (cmnd_status == NOT_FOUND) {
if (ISSET(sudo_mode, MODE_CHECK)) {
audit_failure(NewArgv, N_("%s: command not found"),
NewArgv[0]);
sudo_warnx(U_("%s: command not found"), NewArgv[0]);
NewArgv[1]);
sudo_warnx(U_("%s: command not found"), NewArgv[1]);
} else {
audit_failure(NewArgv, N_("%s: command not found"),
user_cmnd);
@@ -970,17 +977,21 @@ init_vars(char * const envp[])
int
set_cmnd_path(const char *runchroot)
{
const char *cmnd_in;
char *cmnd_out = NULL;
char *path = user_path;
int ret;
debug_decl(set_cmnd_path, SUDOERS_DEBUG_PLUGIN);
cmnd_in = ISSET(sudo_mode, MODE_CHECK) ? NewArgv[1] : NewArgv[0];
free(user_cmnd);
user_cmnd = NULL;
if (def_secure_path && !user_is_exempt())
path = def_secure_path;
if (!set_perms(PERM_RUNAS))
debug_return_int(NOT_FOUND_ERROR);
ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
ret = find_path(cmnd_in, &cmnd_out, user_stat, path,
runchroot, def_ignore_dot, NULL);
if (!restore_perms())
debug_return_int(NOT_FOUND_ERROR);
@@ -988,12 +999,17 @@ set_cmnd_path(const char *runchroot)
/* Failed as root, try as invoking user. */
if (!set_perms(PERM_USER))
debug_return_int(false);
ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
ret = find_path(cmnd_in, &cmnd_out, user_stat, path,
runchroot, def_ignore_dot, NULL);
if (!restore_perms())
debug_return_int(NOT_FOUND_ERROR);
}
if (ISSET(sudo_mode, MODE_CHECK))
list_cmnd = cmnd_out;
else
user_cmnd = cmnd_out;
debug_return_int(ret);
}
@@ -1858,6 +1874,7 @@ sudo_user_free(void)
free(user_runhost);
free(user_cmnd);
free(user_args);
free(list_cmnd);
free(safe_cmnd);
free(saved_cmnd);
free(user_stat);