diff options
Diffstat (limited to 'plugins/sudoers/visudo.c')
-rw-r--r-- | plugins/sudoers/visudo.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index 679d39da8..734118bac 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 1996, 1998-2005, 2007-2018 + * Copyright (c) 1996, 1998-2005, 2007-2022 * Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any @@ -90,14 +90,14 @@ static char *get_editor(int *editor_argc, char ***editor_argv); static bool check_syntax(const char *, bool, bool, bool, bool); static bool edit_sudoers(struct sudoersfile *, char *, int, char **, int); static bool install_sudoers(struct sudoersfile *, bool, bool); -static bool visudo_track_error(const char *file, int line, int column, const char *fmt, va_list args); +static bool visudo_track_error(const char *file, int line, int column, const char *fmt, va_list args) sudo_printf0like(4, 0); static int print_unused(struct sudoers_parse_tree *, struct alias *, void *); static bool reparse_sudoers(char *, int, char **, bool, bool); -static int run_command(char *, char **); +static int run_command(const char *, char *const *); static void parse_sudoers_options(void); static void setup_signals(void); -static void help(void) __attribute__((__noreturn__)); -static void usage(int); +static sudo_noreturn void help(void); +static sudo_noreturn void usage(void); static void visudo_cleanup(void); extern void get_hostname(void); @@ -109,13 +109,15 @@ struct sudo_user sudo_user; struct passwd *list_pw; static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist); static bool checkonly; +static bool edit_includes = true; static unsigned int errors; -static const char short_opts[] = "cf:hOPqsVx:"; +static const char short_opts[] = "cf:hIOPqsVx:"; static struct option long_opts[] = { { "check", no_argument, NULL, 'c' }, { "export", required_argument, NULL, 'x' }, { "file", required_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, + { "no-includes", no_argument, NULL, 'I' }, { "owner", no_argument, NULL, 'O' }, { "perms", no_argument, NULL, 'P' }, { "quiet", no_argument, NULL, 'q' }, @@ -151,7 +153,7 @@ main(int argc, char *argv[]) textdomain("sudoers"); if (argc < 1) - usage(1); + usage(); /* Register fatal/fatalx callback. */ sudo_fatal_callback_register(visudo_cleanup); @@ -192,6 +194,9 @@ main(int argc, char *argv[]) case 'h': help(); break; + case 'I': + edit_includes = false; + break; case 'O': use_owner = true; /* check/set owner */ break; @@ -208,7 +213,7 @@ main(int argc, char *argv[]) export_path = optarg; break; default: - usage(1); + usage(); } } argc -= optind; @@ -226,7 +231,7 @@ main(int argc, char *argv[]) } break; default: - usage(1); + usage(); } if (fflag) { @@ -255,7 +260,7 @@ main(int argc, char *argv[]) } /* Mock up a fake sudo_user struct. */ - user_cmnd = user_base = ""; + user_cmnd = user_base = (char *)""; if (geteuid() == 0) { const char *user = getenv("SUDO_USER"); if (user != NULL && *user != '\0') @@ -361,7 +366,7 @@ get_editor(int *editor_argc, char ***editor_argv) { char *editor_path = NULL, **allowlist = NULL; const char *env_editor; - static char *files[] = { "+1", "sudoers" }; + static const char *files[] = { "+1", "sudoers" }; unsigned int allowlist_len = 0; debug_decl(get_editor, SUDOERS_DEBUG_UTIL); @@ -389,8 +394,8 @@ get_editor(int *editor_argc, char ***editor_argv) allowlist[allowlist_len] = NULL; } - editor_path = find_editor(2, files, editor_argc, editor_argv, allowlist, - &env_editor); + editor_path = find_editor(2, (char **)files, editor_argc, editor_argv, + allowlist, &env_editor); if (editor_path == NULL) { if (def_env_editor && env_editor != NULL) { /* We are honoring $EDITOR so this is a fatal error. */ @@ -413,12 +418,13 @@ get_editor(int *editor_argc, char ***editor_argv) * If an entry starts with '*' the tail end of the string is matched. * No other wild cards are supported. */ -static char *lineno_editors[] = { +static const char *lineno_editors[] = { "ex", "nex", "vi", "nvi", "vim", + "nvim", "elvis", "*macs", "mg", @@ -440,7 +446,7 @@ static bool editor_supports_plus(const char *editor) { const char *cp, *editor_base; - char **av; + const char **av; debug_decl(editor_supports_plus, SUDOERS_DEBUG_UTIL); editor_base = sudo_basename(editor); @@ -532,7 +538,7 @@ edit_sudoers(struct sudoersfile *sp, char *editor, int editor_argc, (void)snprintf(linestr, sizeof(linestr), "+%d", lineno); editor_argv[ac++] = linestr; // -V507 } - editor_argv[ac++] = "--"; + editor_argv[ac++] = (char *)"--"; editor_argv[ac++] = sp->tpath; editor_argv[ac++] = NULL; @@ -655,7 +661,7 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv, } fclose(sudoersin); if (!parse_error) { - (void) update_defaults(&parsed_policy, NULL, + parse_error = !update_defaults(&parsed_policy, NULL, SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true); check_defaults_and_aliases(strict, quiet); } @@ -885,7 +891,7 @@ setup_signals(void) } static int -run_command(char *path, char **argv) +run_command(const char *path, char *const *argv) { int status; pid_t pid, rv; @@ -975,7 +981,7 @@ check_syntax(const char *file, bool quiet, bool strict, bool check_owner, parse_error = true; } if (!parse_error) { - (void) update_defaults(&parsed_policy, NULL, + parse_error = !update_defaults(&parsed_policy, NULL, SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true); check_defaults_and_aliases(strict, quiet); } @@ -1086,6 +1092,11 @@ open_sudoers(const char *path, bool doedit, bool *keepopen) break; } if (entry == NULL) { + if (doedit && !edit_includes) { + /* Only edit the main sudoers file. */ + if (strcmp(path, sudoers_file) != 0) + doedit = false; + } if ((entry = new_sudoers(path, doedit)) == NULL) debug_return_ptr(NULL); if ((fp = fdopen(entry->fd, "r")) == NULL) @@ -1204,34 +1215,35 @@ quit(int signo) #define emsg " exiting due to signal: " iov[0].iov_base = (char *)getprogname(); iov[0].iov_len = strlen(iov[0].iov_base); - iov[1].iov_base = emsg; + iov[1].iov_base = (char *)emsg; iov[1].iov_len = sizeof(emsg) - 1; iov[2].iov_base = strsignal(signo); iov[2].iov_len = strlen(iov[2].iov_base); - iov[3].iov_base = "\n"; + iov[3].iov_base = (char *)"\n"; iov[3].iov_len = 1; ignore_result(writev(STDERR_FILENO, iov, 4)); _exit(signo); } +#define VISUDO_USAGE "usage: %s [-chqsV] [[-f] sudoers ]\n" + static void -usage(int fatal) +usage(void) { - (void) fprintf(fatal ? stderr : stdout, - "usage: %s [-chqsV] [[-f] sudoers ]\n", getprogname()); - if (fatal) - exit(EXIT_FAILURE); + (void) fprintf(stderr, VISUDO_USAGE, getprogname()); + exit(EXIT_FAILURE); } static void help(void) { (void) printf(_("%s - safely edit the sudoers file\n\n"), getprogname()); - usage(0); + (void) printf(VISUDO_USAGE, getprogname()); (void) puts(_("\nOptions:\n" " -c, --check check-only mode\n" " -f, --file=sudoers specify sudoers file location\n" " -h, --help display help message and exit\n" + " -I, --no-includes do not edit include files\n" " -q, --quiet less verbose (quiet) syntax error messages\n" " -s, --strict strict syntax checking\n" " -V, --version display version information and exit\n")); |