|
version 1.1, 2012/02/21 16:23:02
|
version 1.1.1.2, 2012/05/29 12:26:49
|
|
Line 70
|
Line 70
|
| # ifndef LOGIN_DEFROOTCLASS |
# ifndef LOGIN_DEFROOTCLASS |
| # define LOGIN_DEFROOTCLASS "daemon" |
# define LOGIN_DEFROOTCLASS "daemon" |
| # endif |
# endif |
| |
# ifndef LOGIN_SETENV |
| |
# define LOGIN_SETENV 0 |
| |
# endif |
| #endif |
#endif |
| #ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
| # include <selinux/selinux.h> |
# include <selinux/selinux.h> |
| #endif |
#endif |
| #include <ctype.h> |
#include <ctype.h> |
| #include <setjmp.h> |
#include <setjmp.h> |
| |
#ifndef HAVE_GETADDRINFO |
| |
# include "compat/getaddrinfo.h" |
| |
#endif |
| |
|
| #include "sudoers.h" |
#include "sudoers.h" |
| #include "interfaces.h" |
#include "interfaces.h" |
| #include "sudoers_version.h" |
#include "sudoers_version.h" |
| #include "auth/sudo_auth.h" |
#include "auth/sudo_auth.h" |
| |
#include "secure_path.h" |
| |
|
| /* |
/* |
| * Prototypes |
* Prototypes |
|
Line 92 static void set_runaspw(const char *);
|
Line 99 static void set_runaspw(const char *);
|
| static void set_runasgr(const char *); |
static void set_runasgr(const char *); |
| static int cb_runas_default(const char *); |
static int cb_runas_default(const char *); |
| static int sudoers_policy_version(int verbose); |
static int sudoers_policy_version(int verbose); |
| static int deserialize_info(char * const settings[], char * const user_info[]); | static int deserialize_info(char * const args[], char * const settings[], |
| | char * const user_info[]); |
| static char *find_editor(int nfiles, char **files, char ***argv_out); |
static char *find_editor(int nfiles, char **files, char ***argv_out); |
| static void create_admin_success_flag(void); |
static void create_admin_success_flag(void); |
| |
|
| /* |
/* |
| * Globals |
* Globals |
| */ |
*/ |
| const char *sudoers_file = _PATH_SUDOERS; |
|
| mode_t sudoers_mode = SUDOERS_MODE; |
|
| uid_t sudoers_uid = SUDOERS_UID; |
|
| gid_t sudoers_gid = SUDOERS_GID; |
|
| struct sudo_user sudo_user; |
struct sudo_user sudo_user; |
| struct passwd *list_pw; |
struct passwd *list_pw; |
| struct interface *interfaces; |
struct interface *interfaces; |
| int long_list; |
int long_list; |
| int debug_level; |
|
| uid_t timestamp_uid; |
uid_t timestamp_uid; |
| extern int errorlineno; |
extern int errorlineno; |
| extern int parse_error; | extern bool parse_error; |
| extern char *errorfile; |
extern char *errorfile; |
| #ifdef HAVE_LOGIN_CAP_H |
|
| login_cap_t *lc; |
|
| #endif /* HAVE_LOGIN_CAP_H */ |
|
| #ifdef HAVE_BSD_AUTH_H |
#ifdef HAVE_BSD_AUTH_H |
| char *login_style; |
char *login_style; |
| #endif /* HAVE_BSD_AUTH_H */ |
#endif /* HAVE_BSD_AUTH_H */ |
|
Line 122 sudo_conv_t sudo_conv;
|
Line 122 sudo_conv_t sudo_conv;
|
| sudo_printf_t sudo_printf; |
sudo_printf_t sudo_printf; |
| int sudo_mode; |
int sudo_mode; |
| |
|
| |
static int sudo_version; |
| static char *prev_user; |
static char *prev_user; |
| static char *runas_user; |
static char *runas_user; |
| static char *runas_group; |
static char *runas_group; |
|
Line 133 static sigaction_t saved_sa_int, saved_sa_quit, saved_
|
Line 134 static sigaction_t saved_sa_int, saved_sa_quit, saved_
|
| int NewArgc; |
int NewArgc; |
| char **NewArgv; |
char **NewArgv; |
| |
|
| /* plugin_error.c */ | /* Declared here instead of plugin_error.c for static sudo builds. */ |
| extern sigjmp_buf error_jmp; | sigjmp_buf error_jmp; |
| |
|
| static int |
static int |
| sudoers_policy_open(unsigned int version, sudo_conv_t conversation, |
sudoers_policy_open(unsigned int version, sudo_conv_t conversation, |
| sudo_printf_t plugin_printf, char * const settings[], |
sudo_printf_t plugin_printf, char * const settings[], |
| char * const user_info[], char * const envp[]) | char * const user_info[], char * const envp[], char * const args[]) |
| { |
{ |
| volatile int sources = 0; |
volatile int sources = 0; |
| sigaction_t sa; |
sigaction_t sa; |
| struct sudo_nss *nss; |
struct sudo_nss *nss; |
| |
debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN) |
| |
|
| |
sudo_version = version; |
| if (!sudo_conv) |
if (!sudo_conv) |
| sudo_conv = conversation; |
sudo_conv = conversation; |
| if (!sudo_printf) |
if (!sudo_printf) |
| sudo_printf = plugin_printf; |
sudo_printf = plugin_printf; |
| |
|
| |
/* Plugin args are only specified for API version 1.2 and higher. */ |
| |
if (sudo_version < SUDO_API_MKVERSION(1, 2)) |
| |
args = NULL; |
| |
|
| if (sigsetjmp(error_jmp, 1)) { |
if (sigsetjmp(error_jmp, 1)) { |
| /* called via error(), errorx() or log_error() */ | /* called via error(), errorx() or log_fatal() */ |
| rewind_perms(); |
rewind_perms(); |
| return -1; | debug_return_bool(-1); |
| } |
} |
| |
|
| bindtextdomain("sudoers", LOCALEDIR); |
bindtextdomain("sudoers", LOCALEDIR); |
|
Line 181 sudoers_policy_open(unsigned int version, sudo_conv_t
|
Line 188 sudoers_policy_open(unsigned int version, sudo_conv_t
|
| /* Setup defaults data structures. */ |
/* Setup defaults data structures. */ |
| init_defaults(); |
init_defaults(); |
| |
|
| /* Parse settings and user_info */ | /* Parse args, settings and user_info */ |
| sudo_mode = deserialize_info(settings, user_info); | sudo_mode = deserialize_info(args, settings, user_info); |
| |
|
| init_vars(envp); /* XXX - move this later? */ |
init_vars(envp); /* XXX - move this later? */ |
| |
|
|
Line 198 sudoers_policy_open(unsigned int version, sudo_conv_t
|
Line 205 sudoers_policy_open(unsigned int version, sudo_conv_t
|
| if (nss->open(nss) == 0 && nss->parse(nss) == 0) { |
if (nss->open(nss) == 0 && nss->parse(nss) == 0) { |
| sources++; |
sources++; |
| if (nss->setdefs(nss) != 0) |
if (nss->setdefs(nss) != 0) |
| log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries")); | log_error(NO_STDERR, _("problem with defaults entries")); |
| } |
} |
| } |
} |
| if (sources == 0) { |
if (sources == 0) { |
| warningx(_("no valid sudoers sources found, quitting")); |
warningx(_("no valid sudoers sources found, quitting")); |
| return -1; | debug_return_bool(-1); |
| } |
} |
| |
|
| /* XXX - collect post-sudoers parse settings into a function */ |
/* XXX - collect post-sudoers parse settings into a function */ |
|
Line 212 sudoers_policy_open(unsigned int version, sudo_conv_t
|
Line 219 sudoers_policy_open(unsigned int version, sudo_conv_t
|
| * Initialize external group plugin, if any. |
* Initialize external group plugin, if any. |
| */ |
*/ |
| if (def_group_plugin) { |
if (def_group_plugin) { |
| if (group_plugin_load(def_group_plugin) != TRUE) | if (group_plugin_load(def_group_plugin) != true) |
| def_group_plugin = NULL; |
def_group_plugin = NULL; |
| } |
} |
| |
|
|
Line 229 sudoers_policy_open(unsigned int version, sudo_conv_t
|
Line 236 sudoers_policy_open(unsigned int version, sudo_conv_t
|
| set_runaspw(runas_user ? runas_user : def_runas_default); |
set_runaspw(runas_user ? runas_user : def_runas_default); |
| |
|
| if (!update_defaults(SETDEF_RUNAS)) |
if (!update_defaults(SETDEF_RUNAS)) |
| log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries")); | log_error(NO_STDERR, _("problem with defaults entries")); |
| |
|
| if (def_fqdn) |
if (def_fqdn) |
| set_fqdn(); /* deferred until after sudoers is parsed */ |
set_fqdn(); /* deferred until after sudoers is parsed */ |
| |
|
| /* Set login class if applicable. */ |
/* Set login class if applicable. */ |
| set_loginclass(sudo_user.pw); | set_loginclass(runas_pw ? runas_pw : sudo_user.pw); |
| |
|
| restore_perms(); |
restore_perms(); |
| |
|
| return TRUE; | debug_return_bool(true); |
| } |
} |
| |
|
| static void |
static void |
| sudoers_policy_close(int exit_status, int error_code) |
sudoers_policy_close(int exit_status, int error_code) |
| { |
{ |
| |
debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN) |
| |
|
| if (sigsetjmp(error_jmp, 1)) { |
if (sigsetjmp(error_jmp, 1)) { |
| /* called via error(), errorx() or log_error() */ | /* called via error(), errorx() or log_fatal() */ |
| return; | debug_return; |
| } |
} |
| |
|
| /* We do not currently log the exit status. */ |
/* We do not currently log the exit status. */ |
|
Line 265 sudoers_policy_close(int exit_status, int error_code)
|
Line 274 sudoers_policy_close(int exit_status, int error_code)
|
| gr_delref(runas_gr); |
gr_delref(runas_gr); |
| if (user_group_list != NULL) |
if (user_group_list != NULL) |
| grlist_delref(user_group_list); |
grlist_delref(user_group_list); |
| |
|
| |
debug_return; |
| } |
} |
| |
|
| /* |
/* |
|
Line 272 sudoers_policy_close(int exit_status, int error_code)
|
Line 283 sudoers_policy_close(int exit_status, int error_code)
|
| * and before uid/gid changes occur. |
* and before uid/gid changes occur. |
| */ |
*/ |
| static int |
static int |
| sudoers_policy_init_session(struct passwd *pwd) | sudoers_policy_init_session(struct passwd *pwd, char **user_env[]) |
| { |
{ |
| |
debug_decl(sudoers_policy_init, SUDO_DEBUG_PLUGIN) |
| |
|
| |
/* user_env is only specified for API version 1.2 and higher. */ |
| |
if (sudo_version < SUDO_API_MKVERSION(1, 2)) |
| |
user_env = NULL; |
| |
|
| if (sigsetjmp(error_jmp, 1)) { |
if (sigsetjmp(error_jmp, 1)) { |
| /* called via error(), errorx() or log_error() */ | /* called via error(), errorx() or log_fatal() */ |
| return -1; |
return -1; |
| } |
} |
| |
|
| return sudo_auth_begin_session(pwd); | debug_return_bool(sudo_auth_begin_session(pwd, user_env)); |
| } |
} |
| |
|
| static int |
static int |
|
Line 291 sudoers_policy_main(int argc, char * const argv[], int
|
Line 308 sudoers_policy_main(int argc, char * const argv[], int
|
| struct sudo_nss *nss; |
struct sudo_nss *nss; |
| int cmnd_status = -1, validated; |
int cmnd_status = -1, validated; |
| volatile int info_len = 0; |
volatile int info_len = 0; |
| volatile int rval = TRUE; | volatile int rval = true; |
| | debug_decl(sudoers_policy_main, SUDO_DEBUG_PLUGIN) |
| |
|
| if (sigsetjmp(error_jmp, 1)) { |
if (sigsetjmp(error_jmp, 1)) { |
| /* error recovery via error(), errorx() or log_error() */ | /* error recovery via error(), errorx() or log_fatal() */ |
| rval = -1; |
rval = -1; |
| goto done; |
goto done; |
| } |
} |
|
Line 335 sudoers_policy_main(int argc, char * const argv[], int
|
Line 353 sudoers_policy_main(int argc, char * const argv[], int
|
| NewArgv = emalloc2(NewArgc + 2, sizeof(char *)); |
NewArgv = emalloc2(NewArgc + 2, sizeof(char *)); |
| memcpy(++NewArgv, argv, argc * sizeof(char *)); |
memcpy(++NewArgv, argv, argc * sizeof(char *)); |
| NewArgv[NewArgc] = NULL; |
NewArgv[NewArgc] = NULL; |
| if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) | if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL) |
| NewArgv[0] = estrdup(runas_pw->pw_shell); |
NewArgv[0] = estrdup(runas_pw->pw_shell); |
| } |
} |
| |
|
| /* If given the -P option, set the "preserve_groups" flag. */ |
/* If given the -P option, set the "preserve_groups" flag. */ |
| if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) |
if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) |
| def_preserve_groups = TRUE; | def_preserve_groups = true; |
| |
|
| /* Find command in path */ |
/* Find command in path */ |
| cmnd_status = set_cmnd(); |
cmnd_status = set_cmnd(); |
|
Line 397 sudoers_policy_main(int argc, char * const argv[], int
|
Line 415 sudoers_policy_main(int argc, char * const argv[], int
|
| pw = sudo_getpwuid(atoi(def_timestampowner + 1)); |
pw = sudo_getpwuid(atoi(def_timestampowner + 1)); |
| else |
else |
| pw = sudo_getpwnam(def_timestampowner); |
pw = sudo_getpwnam(def_timestampowner); |
| if (!pw) | if (pw != NULL) { |
| | timestamp_uid = pw->pw_uid; |
| | pw_delref(pw); |
| | } else { |
| log_error(0, _("timestamp owner (%s): No such user"), |
log_error(0, _("timestamp owner (%s): No such user"), |
| def_timestampowner); |
def_timestampowner); |
| timestamp_uid = pw->pw_uid; | timestamp_uid = ROOT_UID; |
| pw_delref(pw); | } |
| } |
} |
| |
|
| /* If no command line args and "shell_noargs" is not set, error out. */ |
/* If no command line args and "shell_noargs" is not set, error out. */ |
|
Line 427 sudoers_policy_main(int argc, char * const argv[], int
|
Line 448 sudoers_policy_main(int argc, char * const argv[], int
|
| */ |
*/ |
| if (ISSET(sudo_mode, MODE_EDIT) || |
if (ISSET(sudo_mode, MODE_EDIT) || |
| (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)) |
(ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)) |
| def_env_reset = FALSE; | def_env_reset = false; |
| |
|
| /* Build a new environment that avoids any nasty bits. */ |
/* Build a new environment that avoids any nasty bits. */ |
| rebuild_env(); |
rebuild_env(); |
| |
|
| /* Require a password if sudoers says so. */ |
/* Require a password if sudoers says so. */ |
| rval = check_user(validated, sudo_mode); |
rval = check_user(validated, sudo_mode); |
| if (rval != TRUE) | if (rval != true) |
| goto done; |
goto done; |
| |
|
| /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ |
/* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ |
|
Line 582 sudoers_policy_main(int argc, char * const argv[], int
|
Line 603 sudoers_policy_main(int argc, char * const argv[], int
|
| NewArgv[1] = "--login"; |
NewArgv[1] = "--login"; |
| } |
} |
| |
|
| #if defined(__linux__) || defined(_AIX) | #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM)) |
| /* Insert system-wide environment variables. */ |
/* Insert system-wide environment variables. */ |
| read_env_file(_PATH_ENVIRONMENT, TRUE); | read_env_file(_PATH_ENVIRONMENT, true); |
| #endif |
#endif |
| |
#ifdef HAVE_LOGIN_CAP_H |
| |
/* Set environment based on login class. */ |
| |
if (login_class) { |
| |
login_cap_t *lc = login_getclass(login_class); |
| |
if (lc != NULL) { |
| |
setusercontext(lc, runas_pw, runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV); |
| |
login_close(lc); |
| |
} |
| |
} |
| |
#endif /* HAVE_LOGIN_CAP_H */ |
| } |
} |
| |
|
| /* Insert system-wide environment variables. */ |
/* Insert system-wide environment variables. */ |
| if (def_env_file) |
if (def_env_file) |
| read_env_file(def_env_file, FALSE); | read_env_file(def_env_file, false); |
| |
|
| /* Insert user-specified environment variables. */ |
/* Insert user-specified environment variables. */ |
| insert_env_vars(sudo_user.env_vars); |
insert_env_vars(sudo_user.env_vars); |
|
Line 630 sudoers_policy_main(int argc, char * const argv[], int
|
Line 661 sudoers_policy_main(int argc, char * const argv[], int
|
| command_info[info_len++] = "preserve_groups=true"; |
command_info[info_len++] = "preserve_groups=true"; |
| } else { |
} else { |
| int i, len; |
int i, len; |
| |
gid_t egid; |
| size_t glsize; |
size_t glsize; |
| char *cp, *gid_list; |
char *cp, *gid_list; |
| struct group_list *grlist = get_group_list(runas_pw); |
struct group_list *grlist = get_group_list(runas_pw); |
| |
|
| glsize = sizeof("runas_groups=") - 1 + (grlist->ngids * (MAX_UID_T_LEN + 1)); | /* We reserve an extra spot in the list for the effective gid. */ |
| | glsize = sizeof("runas_groups=") - 1 + |
| | ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1)); |
| gid_list = emalloc(glsize); |
gid_list = emalloc(glsize); |
| memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1); |
memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1); |
| cp = gid_list + sizeof("runas_groups=") - 1; |
cp = gid_list + sizeof("runas_groups=") - 1; |
| |
|
| |
/* On BSD systems the effective gid is the first group in the list. */ |
| |
egid = runas_gr ? (unsigned int)runas_gr->gr_gid : |
| |
(unsigned int)runas_pw->pw_gid; |
| |
len = snprintf(cp, glsize - (cp - gid_list), "%u", egid); |
| |
if (len < 0 || len >= glsize - (cp - gid_list)) |
| |
errorx(1, _("internal error, runas_groups overflow")); |
| |
cp += len; |
| for (i = 0; i < grlist->ngids; i++) { |
for (i = 0; i < grlist->ngids; i++) { |
| /* XXX - check rval */ | if (grlist->gids[i] != egid) { |
| len = snprintf(cp, glsize - (cp - gid_list), "%s%u", | len = snprintf(cp, glsize - (cp - gid_list), ",%u", |
| i ? "," : "", (unsigned int) grlist->gids[i]); | (unsigned int) grlist->gids[i]); |
| cp += len; | if (len < 0 || len >= glsize - (cp - gid_list)) |
| | errorx(1, _("internal error, runas_groups overflow")); |
| | cp += len; |
| | } |
| } |
} |
| command_info[info_len++] = gid_list; |
command_info[info_len++] = gid_list; |
| grlist_delref(grlist); |
grlist_delref(grlist); |
|
Line 651 sudoers_policy_main(int argc, char * const argv[], int
|
Line 696 sudoers_policy_main(int argc, char * const argv[], int
|
| easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom); |
easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom); |
| if (def_noexec) |
if (def_noexec) |
| command_info[info_len++] = estrdup("noexec=true"); |
command_info[info_len++] = estrdup("noexec=true"); |
| if (def_noexec_file) |
|
| command_info[info_len++] = fmt_string("noexec_file", def_noexec_file); |
|
| if (def_set_utmp) |
if (def_set_utmp) |
| command_info[info_len++] = estrdup("set_utmp=true"); |
command_info[info_len++] = estrdup("set_utmp=true"); |
| if (def_use_pty) |
if (def_use_pty) |
|
Line 660 sudoers_policy_main(int argc, char * const argv[], int
|
Line 703 sudoers_policy_main(int argc, char * const argv[], int
|
| if (def_utmp_runas) |
if (def_utmp_runas) |
| command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name); |
command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name); |
| #ifdef HAVE_LOGIN_CAP_H |
#ifdef HAVE_LOGIN_CAP_H |
| if (lc != NULL) | if (def_use_loginclass) |
| command_info[info_len++] = fmt_string("login_class", lc->lc_class); | command_info[info_len++] = fmt_string("login_class", login_class); |
| #endif /* HAVE_LOGIN_CAP_H */ |
#endif /* HAVE_LOGIN_CAP_H */ |
| #ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
| if (user_role != NULL) |
if (user_role != NULL) |
|
Line 676 sudoers_policy_main(int argc, char * const argv[], int
|
Line 719 sudoers_policy_main(int argc, char * const argv[], int
|
| *command_infop = command_info; |
*command_infop = command_info; |
| |
|
| *argv_out = edit_argv ? edit_argv : NewArgv; |
*argv_out = edit_argv ? edit_argv : NewArgv; |
| *user_env_out = env_get(); /* our private copy */ |
|
| |
|
| |
/* Get private version of the environment and zero out stashed copy. */ |
| |
*user_env_out = env_get(); |
| |
env_init(NULL); |
| |
|
| goto done; |
goto done; |
| |
|
| bad: |
bad: |
| rval = FALSE; | rval = false; |
| |
|
| done: |
done: |
| rewind_perms(); |
rewind_perms(); |
|
Line 690 done:
|
Line 736 done:
|
| sudo_endpwent(); |
sudo_endpwent(); |
| sudo_endgrent(); |
sudo_endgrent(); |
| |
|
| return rval; | debug_return_bool(rval); |
| } |
} |
| |
|
| static int |
static int |
| sudoers_policy_check(int argc, char * const argv[], char *env_add[], |
sudoers_policy_check(int argc, char * const argv[], char *env_add[], |
| char **command_infop[], char **argv_out[], char **user_env_out[]) |
char **command_infop[], char **argv_out[], char **user_env_out[]) |
| { |
{ |
| |
debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN) |
| |
|
| if (!ISSET(sudo_mode, MODE_EDIT)) |
if (!ISSET(sudo_mode, MODE_EDIT)) |
| SET(sudo_mode, MODE_RUN); |
SET(sudo_mode, MODE_RUN); |
| |
|
| return sudoers_policy_main(argc, argv, 0, env_add, command_infop, | debug_return_bool(sudoers_policy_main(argc, argv, 0, env_add, command_infop, |
| argv_out, user_env_out); | argv_out, user_env_out)); |
| } |
} |
| |
|
| static int |
static int |
| sudoers_policy_validate(void) |
sudoers_policy_validate(void) |
| { |
{ |
| |
debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN) |
| |
|
| user_cmnd = "validate"; |
user_cmnd = "validate"; |
| SET(sudo_mode, MODE_VALIDATE); |
SET(sudo_mode, MODE_VALIDATE); |
| |
|
| return sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL, NULL, NULL); | debug_return_bool(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL, NULL, NULL)); |
| } |
} |
| |
|
| static void |
static void |
| sudoers_policy_invalidate(int remove) |
sudoers_policy_invalidate(int remove) |
| { |
{ |
| |
debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN) |
| |
|
| user_cmnd = "kill"; |
user_cmnd = "kill"; |
| if (sigsetjmp(error_jmp, 1) == 0) { |
if (sigsetjmp(error_jmp, 1) == 0) { |
| remove_timestamp(remove); |
remove_timestamp(remove); |
| plugin_cleanup(0); |
plugin_cleanup(0); |
| } |
} |
| |
|
| |
debug_return; |
| } |
} |
| |
|
| static int |
static int |
|
Line 728 sudoers_policy_list(int argc, char * const argv[], int
|
Line 782 sudoers_policy_list(int argc, char * const argv[], int
|
| const char *list_user) |
const char *list_user) |
| { |
{ |
| int rval; |
int rval; |
| |
debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN) |
| |
|
| user_cmnd = "list"; |
user_cmnd = "list"; |
| if (argc) |
if (argc) |
|
Line 740 sudoers_policy_list(int argc, char * const argv[], int
|
Line 795 sudoers_policy_list(int argc, char * const argv[], int
|
| list_pw = sudo_getpwnam(list_user); |
list_pw = sudo_getpwnam(list_user); |
| if (list_pw == NULL) { |
if (list_pw == NULL) { |
| warningx(_("unknown user: %s"), list_user); |
warningx(_("unknown user: %s"), list_user); |
| return -1; | debug_return_bool(-1); |
| } |
} |
| } |
} |
| rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL); |
rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL); |
|
Line 749 sudoers_policy_list(int argc, char * const argv[], int
|
Line 804 sudoers_policy_list(int argc, char * const argv[], int
|
| list_pw = NULL; |
list_pw = NULL; |
| } |
} |
| |
|
| return rval; | debug_return_bool(rval); |
| } |
} |
| |
|
| /* |
/* |
|
Line 760 static void
|
Line 815 static void
|
| init_vars(char * const envp[]) |
init_vars(char * const envp[]) |
| { |
{ |
| char * const * ep; |
char * const * ep; |
| |
debug_decl(init_vars, SUDO_DEBUG_PLUGIN) |
| |
|
| #ifdef HAVE_TZSET |
#ifdef HAVE_TZSET |
| (void) tzset(); /* set the timezone if applicable */ |
(void) tzset(); /* set the timezone if applicable */ |
|
Line 799 init_vars(char * const envp[])
|
Line 855 init_vars(char * const envp[])
|
| if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) |
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) |
| errorx(1, _("unknown uid: %u"), (unsigned int) user_uid); |
errorx(1, _("unknown uid: %u"), (unsigned int) user_uid); |
| |
|
| /* Need to make a fake struct passwd for the call to log_error(). */ | /* Need to make a fake struct passwd for the call to log_fatal(). */ |
| sudo_user.pw = sudo_fakepwnamid(user_name, user_uid, user_gid); |
sudo_user.pw = sudo_fakepwnamid(user_name, user_uid, user_gid); |
| log_error(0, _("unknown uid: %u"), (unsigned int) user_uid); | log_fatal(0, _("unknown uid: %u"), (unsigned int) user_uid); |
| /* NOTREACHED */ |
/* NOTREACHED */ |
| } |
} |
| |
|
|
Line 814 init_vars(char * const envp[])
|
Line 870 init_vars(char * const envp[])
|
| /* Set runas callback. */ |
/* Set runas callback. */ |
| sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default; |
sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default; |
| |
|
| /* It is now safe to use log_error() and set_perms() */ | /* It is now safe to use log_fatal() and set_perms() */ |
| | debug_return; |
| } |
} |
| |
|
| /* |
/* |
|
Line 826 set_cmnd(void)
|
Line 883 set_cmnd(void)
|
| { |
{ |
| int rval; |
int rval; |
| char *path = user_path; |
char *path = user_path; |
| |
debug_decl(set_cmnd, SUDO_DEBUG_PLUGIN) |
| |
|
| /* Resolve the path and return. */ |
/* Resolve the path and return. */ |
| rval = FOUND; |
rval = FOUND; |
| user_stat = emalloc(sizeof(struct stat)); | user_stat = ecalloc(1, sizeof(struct stat)); |
| |
|
| /* Default value for cmnd, overridden below. */ |
/* Default value for cmnd, overridden below. */ |
| if (user_cmnd == NULL) |
if (user_cmnd == NULL) |
|
Line 897 set_cmnd(void)
|
Line 955 set_cmnd(void)
|
| user_base = user_cmnd; |
user_base = user_cmnd; |
| |
|
| if (!update_defaults(SETDEF_CMND)) |
if (!update_defaults(SETDEF_CMND)) |
| log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries")); | log_error(NO_STDERR, _("problem with defaults entries")); |
| |
|
| return rval; | debug_return_int(rval); |
| } |
} |
| |
|
| /* |
/* |
|
Line 907 set_cmnd(void)
|
Line 965 set_cmnd(void)
|
| * Returns a handle to the sudoers file or NULL on error. |
* Returns a handle to the sudoers file or NULL on error. |
| */ |
*/ |
| FILE * |
FILE * |
| open_sudoers(const char *sudoers, int doedit, int *keepopen) | open_sudoers(const char *sudoers, bool doedit, bool *keepopen) |
| { |
{ |
| struct stat statbuf; | struct stat sb; |
| FILE *fp = NULL; |
FILE *fp = NULL; |
| int rootstat; | debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN) |
| |
|
| /* | set_perms(PERM_SUDOERS); |
| * Fix the mode and group on sudoers file from old default. | |
| * Only works if file system is readable/writable by root. | |
| */ | |
| if ((rootstat = stat_sudoers(sudoers, &statbuf)) == 0 && | |
| sudoers_uid == statbuf.st_uid && sudoers_mode != 0400 && | |
| (statbuf.st_mode & 0007777) == 0400) { | |
| |
|
| if (chmod(sudoers, sudoers_mode) == 0) { | switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) { |
| warningx(_("fixed mode on %s"), sudoers); | case SUDO_PATH_SECURE: |
| SET(statbuf.st_mode, sudoers_mode); | if ((fp = fopen(sudoers, "r")) == NULL) { |
| if (statbuf.st_gid != sudoers_gid) { | log_error(USE_ERRNO, _("unable to open %s"), sudoers); |
| if (chown(sudoers, (uid_t) -1, sudoers_gid) == 0) { | } else { |
| warningx(_("set group on %s"), sudoers); | /* |
| statbuf.st_gid = sudoers_gid; | * Make sure we can actually read sudoers so we can present the |
| } else | * user with a reasonable error message (unlike the lexer). |
| warning(_("unable to set group on %s"), sudoers); | */ |
| | if (sb.st_size != 0 && fgetc(fp) == EOF) { |
| | log_error(USE_ERRNO, _("unable to read %s"), |
| | sudoers); |
| | fclose(fp); |
| | fp = NULL; |
| | } else { |
| | /* Rewind fp and set close on exec flag. */ |
| | rewind(fp); |
| | (void) fcntl(fileno(fp), F_SETFD, 1); |
| | } |
| } |
} |
| } else | break; |
| warning(_("unable to fix mode on %s"), sudoers); | case SUDO_PATH_MISSING: |
| | log_error(USE_ERRNO, _("unable to stat %s"), sudoers); |
| | break; |
| | case SUDO_PATH_BAD_TYPE: |
| | log_error(0, _("%s is not a regular file"), sudoers); |
| | break; |
| | case SUDO_PATH_WRONG_OWNER: |
| | log_error(0, _("%s is owned by uid %u, should be %u"), |
| | sudoers, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid); |
| | break; |
| | case SUDO_PATH_WORLD_WRITABLE: |
| | log_error(0, _("%s is world writable"), sudoers); |
| | break; |
| | case SUDO_PATH_GROUP_WRITABLE: |
| | log_error(0, _("%s is owned by gid %u, should be %u"), |
| | sudoers, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid); |
| | break; |
| | default: |
| | /* NOTREACHED */ |
| | break; |
| } |
} |
| |
|
| /* |
|
| * Sanity checks on sudoers file. Must be done as sudoers |
|
| * file owner. We already did a stat as root, so use that |
|
| * data if we can't stat as sudoers file owner. |
|
| */ |
|
| set_perms(PERM_SUDOERS); |
|
| |
|
| if (rootstat != 0 && stat_sudoers(sudoers, &statbuf) != 0) |
|
| log_error(USE_ERRNO|NO_EXIT, _("unable to stat %s"), sudoers); |
|
| else if (!S_ISREG(statbuf.st_mode)) |
|
| log_error(NO_EXIT, _("%s is not a regular file"), sudoers); |
|
| else if ((statbuf.st_mode & 07577) != sudoers_mode) |
|
| log_error(NO_EXIT, _("%s is mode 0%o, should be 0%o"), sudoers, |
|
| (unsigned int) (statbuf.st_mode & 07777), |
|
| (unsigned int) sudoers_mode); |
|
| else if (statbuf.st_uid != sudoers_uid) |
|
| log_error(NO_EXIT, _("%s is owned by uid %u, should be %u"), sudoers, |
|
| (unsigned int) statbuf.st_uid, (unsigned int) sudoers_uid); |
|
| else if (statbuf.st_gid != sudoers_gid && ISSET(statbuf.st_mode, S_IRGRP|S_IWGRP)) |
|
| log_error(NO_EXIT, _("%s is owned by gid %u, should be %u"), sudoers, |
|
| (unsigned int) statbuf.st_gid, (unsigned int) sudoers_gid); |
|
| else if ((fp = fopen(sudoers, "r")) == NULL) |
|
| log_error(USE_ERRNO|NO_EXIT, _("unable to open %s"), sudoers); |
|
| else { |
|
| /* |
|
| * Make sure we can actually read sudoers so we can present the |
|
| * user with a reasonable error message (unlike the lexer). |
|
| */ |
|
| if (statbuf.st_size != 0 && fgetc(fp) == EOF) { |
|
| log_error(USE_ERRNO|NO_EXIT, _("unable to read %s"), sudoers); |
|
| fclose(fp); |
|
| fp = NULL; |
|
| } |
|
| } |
|
| |
|
| if (fp != NULL) { |
|
| rewind(fp); |
|
| (void) fcntl(fileno(fp), F_SETFD, 1); |
|
| } |
|
| |
|
| restore_perms(); /* change back to root */ |
restore_perms(); /* change back to root */ |
| return fp; | |
| | debug_return_ptr(fp); |
| } |
} |
| |
|
| #ifdef HAVE_LOGIN_CAP_H |
#ifdef HAVE_LOGIN_CAP_H |
| static void |
static void |
| set_loginclass(struct passwd *pw) |
set_loginclass(struct passwd *pw) |
| { |
{ |
| int errflags; | const int errflags = NO_MAIL|MSG_ONLY; |
| | login_cap_t *lc; |
| | debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN) |
| |
|
| /* | if (!def_use_loginclass) |
| * Don't make it a fatal error if the user didn't specify the login | debug_return; |
| * class themselves. We do this because if login.conf gets | |
| * corrupted we want the admin to be able to use sudo to fix it. | |
| */ | |
| if (login_class) | |
| errflags = NO_MAIL|MSG_ONLY; | |
| else | |
| errflags = NO_MAIL|MSG_ONLY|NO_EXIT; | |
| |
|
| if (login_class && strcmp(login_class, "-") != 0) { |
if (login_class && strcmp(login_class, "-") != 0) { |
| if (user_uid != 0 && |
if (user_uid != 0 && |
|
Line 1006 set_loginclass(struct passwd *pw)
|
Line 1043 set_loginclass(struct passwd *pw)
|
| (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; |
(pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; |
| } |
} |
| |
|
| |
/* Make sure specified login class is valid. */ |
| lc = login_getclass(login_class); |
lc = login_getclass(login_class); |
| if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { |
if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { |
| log_error(errflags, _("unknown login class: %s"), login_class); | /* |
| if (!lc) | * Don't make it a fatal error if the user didn't specify the login |
| lc = login_getclass(NULL); /* needed for login_getstyle() later */ | * class themselves. We do this because if login.conf gets |
| | * corrupted we want the admin to be able to use sudo to fix it. |
| | */ |
| | if (login_class) |
| | log_fatal(errflags, _("unknown login class: %s"), login_class); |
| | else |
| | log_error(errflags, _("unknown login class: %s"), login_class); |
| | def_use_loginclass = false; |
| } |
} |
| |
login_close(lc); |
| |
debug_return; |
| } |
} |
| #else |
#else |
| static void |
static void |
|
Line 1026 set_loginclass(struct passwd *pw)
|
Line 1073 set_loginclass(struct passwd *pw)
|
| void |
void |
| set_fqdn(void) |
set_fqdn(void) |
| { |
{ |
| #ifdef HAVE_GETADDRINFO |
|
| struct addrinfo *res0, hint; |
struct addrinfo *res0, hint; |
| #else |
|
| struct hostent *hp; |
|
| #endif |
|
| char *p; |
char *p; |
| |
debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN) |
| |
|
| #ifdef HAVE_GETADDRINFO |
|
| zero_bytes(&hint, sizeof(hint)); |
zero_bytes(&hint, sizeof(hint)); |
| hint.ai_family = PF_UNSPEC; |
hint.ai_family = PF_UNSPEC; |
| hint.ai_flags = AI_CANONNAME; |
hint.ai_flags = AI_CANONNAME; |
| if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) { |
if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) { |
| #else | log_error(MSG_ONLY, _("unable to resolve host %s"), user_host); |
| if (!(hp = gethostbyname(user_host))) { | |
| #endif | |
| log_error(MSG_ONLY|NO_EXIT, | |
| _("unable to resolve host %s"), user_host); | |
| } else { |
} else { |
| if (user_shost != user_host) |
if (user_shost != user_host) |
| efree(user_shost); |
efree(user_shost); |
| efree(user_host); |
efree(user_host); |
| #ifdef HAVE_GETADDRINFO |
|
| user_host = estrdup(res0->ai_canonname); |
user_host = estrdup(res0->ai_canonname); |
| freeaddrinfo(res0); |
freeaddrinfo(res0); |
| #else |
|
| user_host = estrdup(hp->h_name); |
|
| #endif |
|
| } |
} |
| if ((p = strchr(user_host, '.')) != NULL) |
if ((p = strchr(user_host, '.')) != NULL) |
| user_shost = estrndup(user_host, (size_t)(p - user_host)); |
user_shost = estrndup(user_host, (size_t)(p - user_host)); |
| else |
else |
| user_shost = user_host; |
user_shost = user_host; |
| |
debug_return; |
| } |
} |
| |
|
| /* |
/* |
| * Get passwd entry for the user we are going to run commands as |
* Get passwd entry for the user we are going to run commands as |
| * and store it in runas_pw. By default, commands run as "root". |
* and store it in runas_pw. By default, commands run as "root". |
| */ |
*/ |
| void | static void |
| set_runaspw(const char *user) |
set_runaspw(const char *user) |
| { |
{ |
| |
debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN) |
| |
|
| if (runas_pw != NULL) |
if (runas_pw != NULL) |
| pw_delref(runas_pw); |
pw_delref(runas_pw); |
| if (*user == '#') { |
if (*user == '#') { |
|
Line 1074 set_runaspw(const char *user)
|
Line 1112 set_runaspw(const char *user)
|
| runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); |
runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); |
| } else { |
} else { |
| if ((runas_pw = sudo_getpwnam(user)) == NULL) |
if ((runas_pw = sudo_getpwnam(user)) == NULL) |
| log_error(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user); | log_fatal(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user); |
| } |
} |
| |
debug_return; |
| } |
} |
| |
|
| /* |
/* |
|
Line 1085 set_runaspw(const char *user)
|
Line 1124 set_runaspw(const char *user)
|
| static void |
static void |
| set_runasgr(const char *group) |
set_runasgr(const char *group) |
| { |
{ |
| |
debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN) |
| |
|
| if (runas_gr != NULL) |
if (runas_gr != NULL) |
| gr_delref(runas_gr); |
gr_delref(runas_gr); |
| if (*group == '#') { |
if (*group == '#') { |
|
Line 1092 set_runasgr(const char *group)
|
Line 1133 set_runasgr(const char *group)
|
| runas_gr = sudo_fakegrnam(group); |
runas_gr = sudo_fakegrnam(group); |
| } else { |
} else { |
| if ((runas_gr = sudo_getgrnam(group)) == NULL) |
if ((runas_gr = sudo_getgrnam(group)) == NULL) |
| log_error(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group); | log_fatal(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group); |
| } |
} |
| |
debug_return; |
| } |
} |
| |
|
| /* |
/* |
|
Line 1105 cb_runas_default(const char *user)
|
Line 1147 cb_runas_default(const char *user)
|
| /* Only reset runaspw if user didn't specify one. */ |
/* Only reset runaspw if user didn't specify one. */ |
| if (!runas_user && !runas_group) |
if (!runas_user && !runas_group) |
| set_runaspw(user); |
set_runaspw(user); |
| return TRUE; | return true; |
| } |
} |
| |
|
| /* |
/* |
|
Line 1117 plugin_cleanup(int gotsignal)
|
Line 1159 plugin_cleanup(int gotsignal)
|
| struct sudo_nss *nss; |
struct sudo_nss *nss; |
| |
|
| if (!gotsignal) { |
if (!gotsignal) { |
| |
debug_decl(plugin_cleanup, SUDO_DEBUG_PLUGIN) |
| if (snl != NULL) { |
if (snl != NULL) { |
| tq_foreach_fwd(snl, nss) |
tq_foreach_fwd(snl, nss) |
| nss->close(nss); |
nss->close(nss); |
|
Line 1125 plugin_cleanup(int gotsignal)
|
Line 1168 plugin_cleanup(int gotsignal)
|
| group_plugin_unload(); |
group_plugin_unload(); |
| sudo_endpwent(); |
sudo_endpwent(); |
| sudo_endgrent(); |
sudo_endgrent(); |
| |
debug_return; |
| } |
} |
| } |
} |
| |
|
| static int |
static int |
| sudoers_policy_version(int verbose) |
sudoers_policy_version(int verbose) |
| { |
{ |
| |
debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN) |
| |
|
| if (sigsetjmp(error_jmp, 1)) { |
if (sigsetjmp(error_jmp, 1)) { |
| /* error recovery via error(), errorx() or log_error() */ | /* error recovery via error(), errorx() or log_fatal() */ |
| return -1; | debug_return_bool(-1); |
| } |
} |
| |
|
| sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"), |
sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"), |
|
Line 1153 sudoers_policy_version(int verbose)
|
Line 1199 sudoers_policy_version(int verbose)
|
| dump_auth_methods(); |
dump_auth_methods(); |
| dump_defaults(); |
dump_defaults(); |
| sudo_printf(SUDO_CONV_INFO_MSG, "\n"); |
sudo_printf(SUDO_CONV_INFO_MSG, "\n"); |
| dump_interfaces(interfaces_string); | if (interfaces_string != NULL) { |
| sudo_printf(SUDO_CONV_INFO_MSG, "\n"); | dump_interfaces(interfaces_string); |
| | sudo_printf(SUDO_CONV_INFO_MSG, "\n"); |
| | } |
| } |
} |
| return TRUE; | debug_return_bool(true); |
| } |
} |
| |
|
| static int |
static int |
| deserialize_info(char * const settings[], char * const user_info[]) | deserialize_info(char * const args[], char * const settings[], char * const user_info[]) |
| { |
{ |
| char * const *cur; |
char * const *cur; |
| const char *p, *groups = NULL; |
const char *p, *groups = NULL; |
| |
const char *debug_flags = NULL; |
| int flags = 0; |
int flags = 0; |
| |
debug_decl(deserialize_info, SUDO_DEBUG_PLUGIN) |
| |
|
| #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0) |
#define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0) |
| |
|
| |
/* Parse sudo.conf plugin args. */ |
| |
if (args != NULL) { |
| |
for (cur = args; *cur != NULL; cur++) { |
| |
if (MATCHES(*cur, "sudoers_file=")) { |
| |
sudoers_file = *cur + sizeof("sudoers_file=") - 1; |
| |
continue; |
| |
} |
| |
if (MATCHES(*cur, "sudoers_uid=")) { |
| |
sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1); |
| |
continue; |
| |
} |
| |
if (MATCHES(*cur, "sudoers_gid=")) { |
| |
sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1); |
| |
continue; |
| |
} |
| |
if (MATCHES(*cur, "sudoers_mode=")) { |
| |
sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1, |
| |
NULL, 8); |
| |
continue; |
| |
} |
| |
} |
| |
} |
| |
|
| /* Parse command line settings. */ |
/* Parse command line settings. */ |
| user_closefrom = -1; |
user_closefrom = -1; |
| for (cur = settings; *cur != NULL; cur++) { |
for (cur = settings; *cur != NULL; cur++) { |
|
Line 1175 deserialize_info(char * const settings[], char * const
|
Line 1248 deserialize_info(char * const settings[], char * const
|
| user_closefrom = atoi(*cur + sizeof("closefrom=") - 1); |
user_closefrom = atoi(*cur + sizeof("closefrom=") - 1); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "debug_level=")) { | if (MATCHES(*cur, "debug_flags=")) { |
| debug_level = atoi(*cur + sizeof("debug_level=") - 1); | debug_flags = *cur + sizeof("debug_flags=") - 1; |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "runas_user=")) { |
if (MATCHES(*cur, "runas_user=")) { |
|
Line 1189 deserialize_info(char * const settings[], char * const
|
Line 1262 deserialize_info(char * const settings[], char * const
|
| } |
} |
| if (MATCHES(*cur, "prompt=")) { |
if (MATCHES(*cur, "prompt=")) { |
| user_prompt = *cur + sizeof("prompt=") - 1; |
user_prompt = *cur + sizeof("prompt=") - 1; |
| def_passprompt_override = TRUE; | def_passprompt_override = true; |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "set_home=")) { |
if (MATCHES(*cur, "set_home=")) { |
| if (atobool(*cur + sizeof("set_home=") - 1) == TRUE) | if (atobool(*cur + sizeof("set_home=") - 1) == true) |
| SET(flags, MODE_RESET_HOME); |
SET(flags, MODE_RESET_HOME); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "preserve_environment=")) { |
if (MATCHES(*cur, "preserve_environment=")) { |
| if (atobool(*cur + sizeof("preserve_environment=") - 1) == TRUE) | if (atobool(*cur + sizeof("preserve_environment=") - 1) == true) |
| SET(flags, MODE_PRESERVE_ENV); |
SET(flags, MODE_PRESERVE_ENV); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "run_shell=")) { |
if (MATCHES(*cur, "run_shell=")) { |
| if (atobool(*cur + sizeof("run_shell=") - 1) == TRUE) | if (atobool(*cur + sizeof("run_shell=") - 1) == true) |
| SET(flags, MODE_SHELL); |
SET(flags, MODE_SHELL); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "login_shell=")) { |
if (MATCHES(*cur, "login_shell=")) { |
| if (atobool(*cur + sizeof("login_shell=") - 1) == TRUE) { | if (atobool(*cur + sizeof("login_shell=") - 1) == true) { |
| SET(flags, MODE_LOGIN_SHELL); |
SET(flags, MODE_LOGIN_SHELL); |
| def_env_reset = TRUE; | def_env_reset = true; |
| } |
} |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "implied_shell=")) { |
if (MATCHES(*cur, "implied_shell=")) { |
| if (atobool(*cur + sizeof("implied_shell=") - 1) == TRUE) | if (atobool(*cur + sizeof("implied_shell=") - 1) == true) |
| SET(flags, MODE_IMPLIED_SHELL); |
SET(flags, MODE_IMPLIED_SHELL); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "preserve_groups=")) { |
if (MATCHES(*cur, "preserve_groups=")) { |
| if (atobool(*cur + sizeof("preserve_groups=") - 1) == TRUE) | if (atobool(*cur + sizeof("preserve_groups=") - 1) == true) |
| SET(flags, MODE_PRESERVE_GROUPS); |
SET(flags, MODE_PRESERVE_GROUPS); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "ignore_ticket=")) { |
if (MATCHES(*cur, "ignore_ticket=")) { |
| if (atobool(*cur + sizeof("ignore_ticket=") - 1) == TRUE) | if (atobool(*cur + sizeof("ignore_ticket=") - 1) == true) |
| SET(flags, MODE_IGNORE_TICKET); |
SET(flags, MODE_IGNORE_TICKET); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "noninteractive=")) { |
if (MATCHES(*cur, "noninteractive=")) { |
| if (atobool(*cur + sizeof("noninteractive=") - 1) == TRUE) | if (atobool(*cur + sizeof("noninteractive=") - 1) == true) |
| SET(flags, MODE_NONINTERACTIVE); |
SET(flags, MODE_NONINTERACTIVE); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "sudoedit=")) { |
if (MATCHES(*cur, "sudoedit=")) { |
| if (atobool(*cur + sizeof("sudoedit=") - 1) == TRUE) | if (atobool(*cur + sizeof("sudoedit=") - 1) == true) |
| SET(flags, MODE_EDIT); |
SET(flags, MODE_EDIT); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "login_class=")) { |
if (MATCHES(*cur, "login_class=")) { |
| login_class = *cur + sizeof("login_class=") - 1; |
login_class = *cur + sizeof("login_class=") - 1; |
| def_use_loginclass = TRUE; | def_use_loginclass = true; |
| continue; |
continue; |
| } |
} |
| #ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
|
Line 1271 deserialize_info(char * const settings[], char * const
|
Line 1344 deserialize_info(char * const settings[], char * const
|
| set_interfaces(interfaces_string); |
set_interfaces(interfaces_string); |
| continue; |
continue; |
| } |
} |
| if (MATCHES(*cur, "sudoers_file=")) { |
|
| sudoers_file = *cur + sizeof("sudoers_file=") - 1; |
|
| continue; |
|
| } |
|
| if (MATCHES(*cur, "sudoers_uid=")) { |
|
| sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1); |
|
| continue; |
|
| } |
|
| if (MATCHES(*cur, "sudoers_gid=")) { |
|
| sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1); |
|
| continue; |
|
| } |
|
| if (MATCHES(*cur, "sudoers_mode=")) { |
|
| sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1, |
|
| NULL, 8); |
|
| continue; |
|
| } |
|
| } |
} |
| |
|
| for (cur = user_info; *cur != NULL; cur++) { |
for (cur = user_info; *cur != NULL; cur++) { |
|
Line 1368 deserialize_info(char * const settings[], char * const
|
Line 1424 deserialize_info(char * const settings[], char * const
|
| efree(gids); |
efree(gids); |
| } |
} |
| |
|
| |
/* Setup debugging if indicated. */ |
| |
if (debug_flags != NULL) { |
| |
sudo_debug_init(NULL, debug_flags); |
| |
for (cur = settings; *cur != NULL; cur++) |
| |
sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur); |
| |
for (cur = user_info; *cur != NULL; cur++) |
| |
sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur); |
| |
} |
| |
|
| #undef MATCHES |
#undef MATCHES |
| return flags; | debug_return_int(flags); |
| } |
} |
| |
|
| static char * |
static char * |
| resolve_editor(char *editor, int nfiles, char **files, char ***argv_out) |
resolve_editor(char *editor, int nfiles, char **files, char ***argv_out) |
| { |
{ |
| char *cp, **nargv, *editor_path = NULL; |
char *cp, **nargv, *editor_path = NULL; |
| int ac, i, nargc, wasblank; | int ac, i, nargc; |
| | bool wasblank; |
| | debug_decl(resolve_editor, SUDO_DEBUG_PLUGIN) |
| |
|
| editor = estrdup(editor); /* becomes part of argv_out */ |
editor = estrdup(editor); /* becomes part of argv_out */ |
| |
|
|
Line 1386 resolve_editor(char *editor, int nfiles, char **files,
|
Line 1453 resolve_editor(char *editor, int nfiles, char **files,
|
| * line args so look for those and alloc space for them too. |
* line args so look for those and alloc space for them too. |
| */ |
*/ |
| nargc = 1; |
nargc = 1; |
| for (wasblank = FALSE, cp = editor; *cp != '\0'; cp++) { | for (wasblank = false, cp = editor; *cp != '\0'; cp++) { |
| if (isblank((unsigned char) *cp)) |
if (isblank((unsigned char) *cp)) |
| wasblank = TRUE; | wasblank = true; |
| else if (wasblank) { |
else if (wasblank) { |
| wasblank = FALSE; | wasblank = false; |
| nargc++; |
nargc++; |
| } |
} |
| } |
} |
|
Line 1399 resolve_editor(char *editor, int nfiles, char **files,
|
Line 1466 resolve_editor(char *editor, int nfiles, char **files,
|
| if (cp == NULL || |
if (cp == NULL || |
| find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) { |
find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) { |
| efree(editor); |
efree(editor); |
| return NULL; | debug_return_str(NULL); |
| } |
} |
| nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *)); |
nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *)); |
| for (ac = 0; cp != NULL && ac < nargc; ac++) { |
for (ac = 0; cp != NULL && ac < nargc; ac++) { |
|
Line 1412 resolve_editor(char *editor, int nfiles, char **files,
|
Line 1479 resolve_editor(char *editor, int nfiles, char **files,
|
| nargv[ac] = NULL; |
nargv[ac] = NULL; |
| |
|
| *argv_out = nargv; |
*argv_out = nargv; |
| return editor_path; | debug_return_str(editor_path); |
| } |
} |
| |
|
| /* |
/* |
|
Line 1424 static char *
|
Line 1491 static char *
|
| find_editor(int nfiles, char **files, char ***argv_out) |
find_editor(int nfiles, char **files, char ***argv_out) |
| { |
{ |
| char *cp, *editor, *editor_path = NULL, **ev, *ev0[4]; |
char *cp, *editor, *editor_path = NULL, **ev, *ev0[4]; |
| |
debug_decl(find_editor, SUDO_DEBUG_PLUGIN) |
| |
|
| /* |
/* |
| * If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one. |
* If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one. |
|
Line 1454 find_editor(int nfiles, char **files, char ***argv_out
|
Line 1522 find_editor(int nfiles, char **files, char ***argv_out
|
| audit_failure(NewArgv, _("%s: command not found"), editor); |
audit_failure(NewArgv, _("%s: command not found"), editor); |
| warningx(_("%s: command not found"), editor); |
warningx(_("%s: command not found"), editor); |
| } |
} |
| return editor_path; | debug_return_str(editor_path); |
| } |
} |
| |
|
| #ifdef USE_ADMIN_FLAG |
#ifdef USE_ADMIN_FLAG |
|
Line 1464 create_admin_success_flag(void)
|
Line 1532 create_admin_success_flag(void)
|
| struct stat statbuf; |
struct stat statbuf; |
| char flagfile[PATH_MAX]; |
char flagfile[PATH_MAX]; |
| int fd, n; |
int fd, n; |
| |
debug_decl(create_admin_success_flag, SUDO_DEBUG_PLUGIN) |
| |
|
| /* Check whether the user is in the admin group. */ |
/* Check whether the user is in the admin group. */ |
| if (!user_in_group(sudo_user.pw, "admin")) |
if (!user_in_group(sudo_user.pw, "admin")) |
| return; | debug_return; |
| |
|
| /* Build path to flag file. */ |
/* Build path to flag file. */ |
| n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful", |
n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful", |
| user_dir); |
user_dir); |
| if (n <= 0 || n >= sizeof(flagfile)) |
if (n <= 0 || n >= sizeof(flagfile)) |
| return; | debug_return; |
| |
|
| /* Create admin flag file if it doesn't already exist. */ |
/* Create admin flag file if it doesn't already exist. */ |
| set_perms(PERM_USER); |
set_perms(PERM_USER); |
|
Line 1482 create_admin_success_flag(void)
|
Line 1551 create_admin_success_flag(void)
|
| close(fd); |
close(fd); |
| } |
} |
| restore_perms(); |
restore_perms(); |
| |
debug_return; |
| } |
} |
| #else /* !USE_ADMIN_FLAG */ |
#else /* !USE_ADMIN_FLAG */ |
| static void |
static void |
|
Line 1491 create_admin_success_flag(void)
|
Line 1561 create_admin_success_flag(void)
|
| } |
} |
| #endif /* USE_ADMIN_FLAG */ |
#endif /* USE_ADMIN_FLAG */ |
| |
|
| |
static void |
| |
sudoers_policy_register_hooks(int version, int (*register_hook)(struct sudo_hook *hook)) |
| |
{ |
| |
struct sudo_hook hook; |
| |
|
| |
memset(&hook, 0, sizeof(hook)); |
| |
hook.hook_version = SUDO_HOOK_VERSION; |
| |
|
| |
hook.hook_type = SUDO_HOOK_SETENV; |
| |
hook.hook_fn = sudoers_hook_setenv; |
| |
register_hook(&hook); |
| |
|
| |
hook.hook_type = SUDO_HOOK_UNSETENV; |
| |
hook.hook_fn = sudoers_hook_unsetenv; |
| |
register_hook(&hook); |
| |
|
| |
hook.hook_type = SUDO_HOOK_GETENV; |
| |
hook.hook_fn = sudoers_hook_getenv; |
| |
register_hook(&hook); |
| |
|
| |
hook.hook_type = SUDO_HOOK_PUTENV; |
| |
hook.hook_fn = sudoers_hook_putenv; |
| |
register_hook(&hook); |
| |
} |
| |
|
| struct policy_plugin sudoers_policy = { |
struct policy_plugin sudoers_policy = { |
| SUDO_POLICY_PLUGIN, |
SUDO_POLICY_PLUGIN, |
| SUDO_API_VERSION, |
SUDO_API_VERSION, |
|
Line 1501 struct policy_plugin sudoers_policy = {
|
Line 1596 struct policy_plugin sudoers_policy = {
|
| sudoers_policy_list, |
sudoers_policy_list, |
| sudoers_policy_validate, |
sudoers_policy_validate, |
| sudoers_policy_invalidate, |
sudoers_policy_invalidate, |
| sudoers_policy_init_session | sudoers_policy_init_session, |
| | sudoers_policy_register_hooks |
| }; |
}; |