From 19c80f8aee73d1ffc00091d7fda206f48e429dd9 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 3 Jul 2016 06:19:43 -0600 Subject: [PATCH] Ignore a missing or insecure #includedir, it is not a fatal error. --- plugins/sudoers/toke.c | 60 +++++++++++++++++++++++------------------- plugins/sudoers/toke.l | 60 +++++++++++++++++++++++------------------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index e90411de5..c23da7c9a 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -2549,8 +2549,8 @@ YY_RULE_SETUP LEXTRACE("INCLUDEDIR\n"); /* - * Push current buffer and switch to include file. - * We simply ignore empty directories. + * Push current buffer and switch to include file, + * ignoring missing or empty directories. */ if (!push_includedir(path)) yyterminate(); @@ -4185,6 +4185,12 @@ init_lexer(void) debug_return; } +/* + * Open an include file (or file from a directory), push the old + * sudoers file buffer and switch to the new one. + * A missing or insecure include dir is simply ignored. + * Returns false on error, else true. + */ static bool push_include_int(char *path, bool isdir) { @@ -4212,40 +4218,35 @@ push_include_int(char *path, bool isdir) SLIST_INIT(&istack[idepth].more); if (isdir) { struct stat sb; - int count; - switch (sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb)) { - case SUDO_PATH_SECURE: - break; - case SUDO_PATH_MISSING: - debug_return_bool(false); - case SUDO_PATH_BAD_TYPE: - errno = ENOTDIR; - if (sudoers_warnings) { + int count, status; + + status = sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb); + if (status != SUDO_PATH_SECURE) { + if (sudoers_warnings) { + switch (status) { + case SUDO_PATH_BAD_TYPE: + errno = ENOTDIR; sudo_warn("%s", path); - } - debug_return_bool(false); - case SUDO_PATH_WRONG_OWNER: - if (sudoers_warnings) { + break; + case SUDO_PATH_WRONG_OWNER: sudo_warnx(U_("%s is owned by uid %u, should be %u"), path, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid); - } - debug_return_bool(false); - case SUDO_PATH_WORLD_WRITABLE: - if (sudoers_warnings) { + break; + case SUDO_PATH_WORLD_WRITABLE: sudo_warnx(U_("%s is world writable"), path); - } - debug_return_bool(false); - case SUDO_PATH_GROUP_WRITABLE: - if (sudoers_warnings) { + break; + case SUDO_PATH_GROUP_WRITABLE: sudo_warnx(U_("%s is owned by gid %u, should be %u"), path, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid); + break; + default: + break; } - debug_return_bool(false); - default: - /* NOTREACHED */ - debug_return_bool(false); + } + /* A missing or insecure include dir is not a fatal error. */ + debug_return_bool(true); } count = switch_dir(&istack[idepth], path); if (count <= 0) { @@ -4285,6 +4286,11 @@ push_include_int(char *path, bool isdir) debug_return_bool(true); } +/* + * Restore the previous sudoers file and buffer, or, in the case + * of an includedir, switch to the next file in the dir. + * Returns false if there is nothing to pop, else true. + */ static bool pop_include(void) { diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index ae4ddf644..a98fef0dc 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -319,8 +319,8 @@ DEFVAR [a-z_]+ LEXTRACE("INCLUDEDIR\n"); /* - * Push current buffer and switch to include file. - * We simply ignore empty directories. + * Push current buffer and switch to include file, + * ignoring missing or empty directories. */ if (!push_includedir(path)) yyterminate(); @@ -902,6 +902,12 @@ init_lexer(void) debug_return; } +/* + * Open an include file (or file from a directory), push the old + * sudoers file buffer and switch to the new one. + * A missing or insecure include dir is simply ignored. + * Returns false on error, else true. + */ static bool push_include_int(char *path, bool isdir) { @@ -929,40 +935,35 @@ push_include_int(char *path, bool isdir) SLIST_INIT(&istack[idepth].more); if (isdir) { struct stat sb; - int count; - switch (sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb)) { - case SUDO_PATH_SECURE: - break; - case SUDO_PATH_MISSING: - debug_return_bool(false); - case SUDO_PATH_BAD_TYPE: - errno = ENOTDIR; - if (sudoers_warnings) { + int count, status; + + status = sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb); + if (status != SUDO_PATH_SECURE) { + if (sudoers_warnings) { + switch (status) { + case SUDO_PATH_BAD_TYPE: + errno = ENOTDIR; sudo_warn("%s", path); - } - debug_return_bool(false); - case SUDO_PATH_WRONG_OWNER: - if (sudoers_warnings) { + break; + case SUDO_PATH_WRONG_OWNER: sudo_warnx(U_("%s is owned by uid %u, should be %u"), path, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid); - } - debug_return_bool(false); - case SUDO_PATH_WORLD_WRITABLE: - if (sudoers_warnings) { + break; + case SUDO_PATH_WORLD_WRITABLE: sudo_warnx(U_("%s is world writable"), path); - } - debug_return_bool(false); - case SUDO_PATH_GROUP_WRITABLE: - if (sudoers_warnings) { + break; + case SUDO_PATH_GROUP_WRITABLE: sudo_warnx(U_("%s is owned by gid %u, should be %u"), path, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid); + break; + default: + break; } - debug_return_bool(false); - default: - /* NOTREACHED */ - debug_return_bool(false); + } + /* A missing or insecure include dir is not a fatal error. */ + debug_return_bool(true); } count = switch_dir(&istack[idepth], path); if (count <= 0) { @@ -1002,6 +1003,11 @@ push_include_int(char *path, bool isdir) debug_return_bool(true); } +/* + * Restore the previous sudoers file and buffer, or, in the case + * of an includedir, switch to the next file in the dir. + * Returns false if there is nothing to pop, else true. + */ static bool pop_include(void) { -- 2.49.0