]> granicus.if.org Git - sudo/commitdiff
Remove the NO_EXIT flag to log_error() and add a log_fatal() function
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 26 Mar 2012 14:59:14 +0000 (10:59 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 26 Mar 2012 14:59:14 +0000 (10:59 -0400)
that exits and is marked no_return.  Fixes false positives from
static analyzers and is easier for humans to read too.

14 files changed:
plugins/sudoers/auth/bsdauth.c
plugins/sudoers/auth/kerb5.c
plugins/sudoers/auth/pam.c
plugins/sudoers/auth/sia.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/bsm_audit.c
plugins/sudoers/check.c
plugins/sudoers/env.c
plugins/sudoers/iolog.c
plugins/sudoers/logging.c
plugins/sudoers/logging.h
plugins/sudoers/parse.c
plugins/sudoers/set_perms.c
plugins/sudoers/sudoers.c

index 5e90898aa8a4836d22435753ca0b6e32e06b0475..3597e56eeecb286cd0b2e0975adbcebcfca8da65 100644 (file)
@@ -74,13 +74,13 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
     else
        state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
     if (state.lc == NULL) {
-       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+       log_error(USE_ERRNO|NO_MAIL,
            _("unable to get login class for user %s"), pw->pw_name);
        debug_return_int(AUTH_FATAL);
     }
 
     if ((state.as = auth_open()) == NULL) {
-       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+       log_error(USE_ERRNO|NO_MAIL,
            _("unable to begin bsd authentication"));
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
@@ -89,7 +89,7 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
     /* XXX - maybe sanity check the auth style earlier? */
     login_style = login_getstyle(state.lc, login_style, "auth-sudo");
     if (login_style == NULL) {
-       log_error(NO_EXIT|NO_MAIL, _("invalid authentication type"));
+       log_error(NO_MAIL, _("invalid authentication type"));
        auth_close(state.as);
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
@@ -98,7 +98,7 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
      if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
        auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
        auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
-       log_error(NO_EXIT|NO_MAIL, _("unable to setup authentication"));
+       log_error(NO_MAIL, _("unable to setup authentication"));
        auth_close(state.as);
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
@@ -170,7 +170,7 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
        debug_return_int(AUTH_INTR);
 
     if ((s = auth_getvalue(as, "errormsg")) != NULL)
-       log_error(NO_EXIT|NO_MAIL, "%s", s);
+       log_error(NO_MAIL, "%s", s);
     debug_return_int(AUTH_FAILURE);
 }
 
index 3ba7b8c5b81e4f20d4547bf1e2348b14d0c67207..ab47c190c83304105177e10b5b34bab46efe3e51 100644 (file)
@@ -113,7 +113,7 @@ sudo_krb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
         * API does not currently provide this unless the auth is standalone.
         */
        if ((error = krb5_unparse_name(sudo_context, princ, &pname))) {
-           log_error(NO_EXIT|NO_MAIL,
+           log_error(NO_MAIL,
                      _("%s: unable to unparse princ ('%s'): %s"), auth->name,
                      pw->pw_name, error_message(error));
            debug_return_int(AUTH_FAILURE);
@@ -156,7 +156,7 @@ sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
 
     error = krb5_parse_name(sudo_context, pname, &(sudo_krb5_data.princ));
     if (error) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to parse '%s': %s"), auth->name, pname,
                  error_message(error));
        goto done;
@@ -166,7 +166,7 @@ sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
                    (long) getpid());
     if ((error = krb5_cc_resolve(sudo_context, cache_name,
        &(sudo_krb5_data.ccache)))) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to resolve ccache: %s"), auth->name,
                  error_message(error));
        goto done;
@@ -214,7 +214,7 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     /* Set default flags based on the local config file. */
     error = krb5_get_init_creds_opt_alloc(sudo_context, &opts);
     if (error) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to allocate options: %s"), auth->name,
                  error_message(error));
        goto done;
@@ -230,7 +230,7 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
                                             NULL, 0, NULL, opts))) {
        /* Don't print error if just a bad password */
        if (error != KRB5KRB_AP_ERR_BAD_INTEGRITY)
-           log_error(NO_EXIT|NO_MAIL,
+           log_error(NO_MAIL,
                      _("%s: unable to get credentials: %s"), auth->name,
                      error_message(error));
        goto done;
@@ -243,11 +243,11 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 
     /* Store cred in cred cache. */
     if ((error = krb5_cc_initialize(sudo_context, ccache, princ))) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to initialize ccache: %s"), auth->name,
                  error_message(error));
     } else if ((error = krb5_cc_store_cred(sudo_context, ccache, creds))) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to store cred in ccache: %s"), auth->name,
                  error_message(error));
     }
@@ -312,7 +312,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
      */
     if ((error = krb5_sname_to_principal(sudo_context, NULL, NULL,
                                        KRB5_NT_SRV_HST, &server))) {
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: unable to get host principal: %s"), auth_name,
                  error_message(error));
        debug_return_int(-1);
@@ -327,7 +327,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
                                   NULL, &vopt);
     krb5_free_principal(sudo_context, server);
     if (error)
-       log_error(NO_EXIT|NO_MAIL,
+       log_error(NO_MAIL,
                  _("%s: Cannot verify TGT! Possible attack!: %s"),
                  auth_name, error_message(error));
     debug_return_int(error);
index 5006e4badc3fcdb8e8bb5818a9eb52c5881b3315..64ac30a80a363d615ffbd34e3bddd3f0064351ff 100644 (file)
@@ -97,7 +97,7 @@ sudo_pam_init(struct passwd *pw, sudo_auth *auth)
 #endif
        pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
     if (pam_status != PAM_SUCCESS) {
-       log_error(USE_ERRNO|NO_EXIT|NO_MAIL, _("unable to initialize PAM"));
+       log_error(USE_ERRNO|NO_MAIL, _("unable to initialize PAM"));
        debug_return_int(AUTH_FATAL);
     }
 
@@ -141,25 +141,25 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
                case PAM_SUCCESS:
                    debug_return_int(AUTH_SUCCESS);
                case PAM_AUTH_ERR:
-                   log_error(NO_EXIT|NO_MAIL, _("account validation failure, "
+                   log_error(NO_MAIL, _("account validation failure, "
                        "is your account locked?"));
                    debug_return_int(AUTH_FATAL);
                case PAM_NEW_AUTHTOK_REQD:
-                   log_error(NO_EXIT|NO_MAIL, _("Account or password is "
+                   log_error(NO_MAIL, _("Account or password is "
                        "expired, reset your password and try again"));
                    *pam_status = pam_chauthtok(pamh,
                        PAM_CHANGE_EXPIRED_AUTHTOK);
                    if (*pam_status == PAM_SUCCESS)
                        debug_return_int(AUTH_SUCCESS);
                    if ((s = pam_strerror(pamh, *pam_status)))
-                       log_error(NO_EXIT|NO_MAIL, _("pam_chauthtok: %s"), s);
+                       log_error(NO_MAIL, _("pam_chauthtok: %s"), s);
                    debug_return_int(AUTH_FAILURE);
                case PAM_AUTHTOK_EXPIRED:
-                   log_error(NO_EXIT|NO_MAIL,
+                   log_error(NO_MAIL,
                        _("Password expired, contact your system administrator"));
                    debug_return_int(AUTH_FATAL);
                case PAM_ACCT_EXPIRED:
-                   log_error(NO_EXIT|NO_MAIL,
+                   log_error(NO_MAIL,
                        _("Account expired or PAM config lacks an \"account\" "
                        "section for sudo, contact your system administrator"));
                    debug_return_int(AUTH_FATAL);
@@ -175,7 +175,7 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
            debug_return_int(AUTH_FAILURE);
        default:
            if ((s = pam_strerror(pamh, *pam_status)))
-               log_error(NO_EXIT|NO_MAIL, _("pam_authenticate: %s"), s);
+               log_error(NO_MAIL, _("pam_authenticate: %s"), s);
            debug_return_int(AUTH_FATAL);
     }
 }
index c5b93926f53a45ffd684593d8bac622972394c55..d9f685e17e7b8e0502498ac87470c644e636f338 100644 (file)
@@ -105,7 +105,7 @@ sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 
     if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, user_ttypath, 1, NULL) != SIASUCCESS) {
 
-       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+       log_error(USE_ERRNO|NO_MAIL,
            _("unable to initialize SIA session"));
        debug_return_int(AUTH_FATAL);
     }
index b914f39734a187e2d20b4e165f1357aaa0007330..3216582d4d3775c4efa58613524d3b39febf8353 100644 (file)
@@ -114,7 +114,7 @@ sudo_auth_init(struct passwd *pw)
     standalone = IS_STANDALONE(&auth_switch[0]);
     if (standalone && auth_switch[1].name != NULL) {
        audit_failure(NewArgv, "invalid authentication methods");
-       log_error(0, _("Invalid authentication methods compiled into sudo!  "
+       log_fatal(0, _("Invalid authentication methods compiled into sudo!  "
            "You may mix standalone and non-standalone authentication."));
        debug_return_int(-1);
     }
@@ -195,7 +195,7 @@ verify_user(struct passwd *pw, char *prompt)
     /* XXX - check FLAG_DISABLED too */
     if (auth_switch[0].name == NULL) {
        audit_failure(NewArgv, "no authentication methods");
-       log_error(0,
+       log_fatal(0,
            _("There are no authentication methods compiled into sudo!  "
            "If you want to turn off authentication, use the "
            "--disable-authentication configure option."));
@@ -268,7 +268,7 @@ done:
                    flags = 0;
                else
                    flags = NO_MAIL;
-               log_error(flags, ngettext("%d incorrect password attempt",
+               log_fatal(flags, ngettext("%d incorrect password attempt",
                    "%d incorrect password attempts",
                    def_passwd_tries - counter), def_passwd_tries - counter);
            }
index 0ce6caf710b9bffb10a3ca6d936cd79a7d188fac..f30eab433e9b129f958076ee316cae442a8cb2d1 100644 (file)
@@ -44,7 +44,7 @@
 # define AUDIT_NOT_CONFIGURED  ENOSYS
 #endif
 
-void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__));
+void log_fatal(int flags, const char *fmt, ...) __attribute__((__noreturn__));
 
 static int
 audit_sudo_selected(int sf)
@@ -58,10 +58,10 @@ audit_sudo_selected(int sf)
        if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
                if (errno == ENOSYS) {
                        if (getaudit(&ainfo) < 0)
-                               log_error(0, _("getaudit: failed"));
+                               log_fatal(0, _("getaudit: failed"));
                        mask = &ainfo.ai_mask;
                } else
-                       log_error(0, _("getaudit: failed"));
+                       log_fatal(0, _("getaudit: failed"));
         } else
                mask = &ainfo_addr.ai_mask;
        sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
@@ -88,7 +88,7 @@ bsm_audit_success(char **exec_args)
        if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
                if (errno == AUDIT_NOT_CONFIGURED)
                        return;
-               log_error(0, _("Could not determine audit condition"));
+               log_fatal(0, _("Could not determine audit condition"));
        }
        if (au_cond == AUC_NOAUDIT)
                debug_return;
@@ -99,9 +99,9 @@ bsm_audit_success(char **exec_args)
        if (!audit_sudo_selected(0))
                debug_return;
        if (getauid(&auid) < 0)
-               log_error(0, _("getauid failed"));
+               log_fatal(0, _("getauid failed"));
        if ((aufd = au_open()) == -1)
-               log_error(0, _("au_open: failed"));
+               log_fatal(0, _("au_open: failed"));
        if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
                tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
                    getuid(), pid, pid, &ainfo_addr.ai_termid);
@@ -110,24 +110,24 @@ bsm_audit_success(char **exec_args)
                 * NB: We should probably watch out for ERANGE here.
                 */
                if (getaudit(&ainfo) < 0)
-                       log_error(0, _("getaudit: failed"));
+                       log_fatal(0, _("getaudit: failed"));
                tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
                    getuid(), pid, pid, &ainfo.ai_termid);
        } else
-               log_error(0, _("getaudit: failed"));
+               log_fatal(0, _("getaudit: failed"));
        if (tok == NULL)
-               log_error(0, _("au_to_subject: failed"));
+               log_fatal(0, _("au_to_subject: failed"));
        au_write(aufd, tok);
        tok = au_to_exec_args(exec_args);
        if (tok == NULL)
-               log_error(0, _("au_to_exec_args: failed"));
+               log_fatal(0, _("au_to_exec_args: failed"));
        au_write(aufd, tok);
        tok = au_to_return32(0, 0);
        if (tok == NULL)
-               log_error(0, _("au_to_return32: failed"));
+               log_fatal(0, _("au_to_return32: failed"));
        au_write(aufd, tok);
        if (au_close(aufd, 1, AUE_sudo) == -1)
-               log_error(0, _("unable to commit audit record"));
+               log_fatal(0, _("unable to commit audit record"));
        debug_return;
 }
 
@@ -151,43 +151,43 @@ bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
        if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
                if (errno == AUDIT_NOT_CONFIGURED)
                        debug_return;
-               log_error(0, _("Could not determine audit condition"));
+               log_fatal(0, _("Could not determine audit condition"));
        }
        if (au_cond == AUC_NOAUDIT)
                debug_return;
        if (!audit_sudo_selected(1))
                debug_return;
        if (getauid(&auid) < 0)
-               log_error(0, _("getauid: failed"));
+               log_fatal(0, _("getauid: failed"));
        if ((aufd = au_open()) == -1)
-               log_error(0, _("au_open: failed"));
+               log_fatal(0, _("au_open: failed"));
        if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { 
                tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
                    getuid(), pid, pid, &ainfo_addr.ai_termid);
        } else if (errno == ENOSYS) {
                if (getaudit(&ainfo) < 0) 
-                       log_error(0, _("getaudit: failed"));
+                       log_fatal(0, _("getaudit: failed"));
                tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
                    getuid(), pid, pid, &ainfo.ai_termid);
        } else
-               log_error(0, _("getaudit: failed"));
+               log_fatal(0, _("getaudit: failed"));
        if (tok == NULL)
-               log_error(0, _("au_to_subject: failed"));
+               log_fatal(0, _("au_to_subject: failed"));
        au_write(aufd, tok);
        tok = au_to_exec_args(exec_args);
        if (tok == NULL)
-               log_error(0, _("au_to_exec_args: failed"));
+               log_fatal(0, _("au_to_exec_args: failed"));
        au_write(aufd, tok);
        (void) vsnprintf(text, sizeof(text), fmt, ap);
        tok = au_to_text(text);
        if (tok == NULL)
-               log_error(0, _("au_to_text: failed"));
+               log_fatal(0, _("au_to_text: failed"));
        au_write(aufd, tok);
        tok = au_to_return32(EPERM, 1);
        if (tok == NULL)
-               log_error(0, _("au_to_return32: failed"));
+               log_fatal(0, _("au_to_return32: failed"));
        au_write(aufd, tok);
        if (au_close(aufd, 1, AUE_sudo) == -1)
-               log_error(0, _("unable to commit audit record"));
+               log_fatal(0, _("unable to commit audit record"));
        debug_return;
 }
index 2850fe83a197987de17ab3ddab7c1103376ccd96..ddb61d9d72480cab55dc9b6929b9f40284dc18c1 100644 (file)
@@ -246,11 +246,11 @@ update_timestamp(char *timestampdir, char *timestampfile)
         */
        int fd = open(timestampfile, O_WRONLY|O_CREAT, 0600);
        if (fd == -1)
-           log_error(NO_EXIT|USE_ERRNO, _("unable to open %s"), timestampfile);
+           log_error(USE_ERRNO, _("unable to open %s"), timestampfile);
        else {
            lock_file(fd, SUDO_LOCK);
            if (write(fd, &tty_info, sizeof(tty_info)) != sizeof(tty_info)) {
-               log_error(NO_EXIT|USE_ERRNO, _("unable to write to %s"),
+               log_error(USE_ERRNO, _("unable to write to %s"),
                    timestampfile);
            }
            close(fd);
@@ -258,7 +258,7 @@ update_timestamp(char *timestampdir, char *timestampfile)
     } else {
        if (touch(-1, timestampdir, NULL) == -1) {
            if (mkdir(timestampdir, 0700) == -1) {
-               log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"),
+               log_error(USE_ERRNO, _("unable to mkdir %s"),
                    timestampdir);
            }
        }
@@ -453,7 +453,7 @@ build_timestamp(char **timestampdir, char **timestampfile)
 
     debug_return_int(len);
 bad:
-    log_error(0, _("timestamp path too long: %s"), *timestampfile);
+    log_fatal(0, _("timestamp path too long: %s"), *timestampfile);
     debug_return_int(-1);
 }
 
@@ -482,14 +482,14 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
      */
     if (lstat(dirparent, &sb) == 0) {
        if (!S_ISDIR(sb.st_mode))
-           log_error(NO_EXIT, _("%s exists but is not a directory (0%o)"),
+           log_error(0, _("%s exists but is not a directory (0%o)"),
                dirparent, (unsigned int) sb.st_mode);
        else if (sb.st_uid != timestamp_uid)
-           log_error(NO_EXIT, _("%s owned by uid %u, should be uid %u"),
+           log_error(0, _("%s owned by uid %u, should be uid %u"),
                dirparent, (unsigned int) sb.st_uid,
                (unsigned int) timestamp_uid);
        else if ((sb.st_mode & 0000022))
-           log_error(NO_EXIT,
+           log_error(0,
                _("%s writable by non-owner (0%o), should be mode 0700"),
                dirparent, (unsigned int) sb.st_mode);
        else {
@@ -498,12 +498,12 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
            status = TS_MISSING;
        }
     } else if (errno != ENOENT) {
-       log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), dirparent);
+       log_error(USE_ERRNO, _("unable to stat %s"), dirparent);
     } else {
        /* No dirparent, try to make one. */
        if (ISSET(flags, TS_MAKE_DIRS)) {
            if (mkdir(dirparent, S_IRWXU))
-               log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"),
+               log_error(USE_ERRNO, _("unable to mkdir %s"),
                    dirparent);
            else
                status = TS_MISSING;
@@ -526,14 +526,14 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
                if (unlink(timestampdir) == 0)
                    status = TS_MISSING;
            } else
-               log_error(NO_EXIT, _("%s exists but is not a directory (0%o)"),
+               log_error(0, _("%s exists but is not a directory (0%o)"),
                    timestampdir, (unsigned int) sb.st_mode);
        } else if (sb.st_uid != timestamp_uid)
-           log_error(NO_EXIT, _("%s owned by uid %u, should be uid %u"),
+           log_error(0, _("%s owned by uid %u, should be uid %u"),
                timestampdir, (unsigned int) sb.st_uid,
                (unsigned int) timestamp_uid);
        else if ((sb.st_mode & 0000022))
-           log_error(NO_EXIT,
+           log_error(0,
                _("%s writable by non-owner (0%o), should be mode 0700"),
                timestampdir, (unsigned int) sb.st_mode);
        else {
@@ -542,7 +542,7 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
            status = TS_OLD;            /* do date check later */
        }
     } else if (errno != ENOENT) {
-       log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), timestampdir);
+       log_error(USE_ERRNO, _("unable to stat %s"), timestampdir);
     } else
        status = TS_MISSING;
 
@@ -553,7 +553,7 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
     if (status == TS_MISSING && timestampfile && ISSET(flags, TS_MAKE_DIRS)) {
        if (mkdir(timestampdir, S_IRWXU) == -1) {
            status = TS_ERROR;
-           log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"), timestampdir);
+           log_error(USE_ERRNO, _("unable to mkdir %s"), timestampdir);
        }
     }
 
@@ -568,18 +568,18 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
        if (lstat(timestampfile, &sb) == 0) {
            if (!S_ISREG(sb.st_mode)) {
                status = TS_ERROR;
-               log_error(NO_EXIT, _("%s exists but is not a regular file (0%o)"),
+               log_error(0, _("%s exists but is not a regular file (0%o)"),
                    timestampfile, (unsigned int) sb.st_mode);
            } else {
                /* If bad uid or file mode, complain and kill the bogus file. */
                if (sb.st_uid != timestamp_uid) {
-                   log_error(NO_EXIT,
+                   log_error(0,
                        _("%s owned by uid %u, should be uid %u"),
                        timestampfile, (unsigned int) sb.st_uid,
                        (unsigned int) timestamp_uid);
                    (void) unlink(timestampfile);
                } else if ((sb.st_mode & 0000022)) {
-                   log_error(NO_EXIT,
+                   log_error(0,
                        _("%s writable by non-owner (0%o), should be mode 0600"),
                        timestampfile, (unsigned int) sb.st_mode);
                    (void) unlink(timestampfile);
@@ -610,7 +610,7 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
                }
            }
        } else if (errno != ENOENT) {
-           log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), timestampfile);
+           log_error(USE_ERRNO, _("unable to stat %s"), timestampfile);
            status = TS_ERROR;
        }
     }
@@ -633,7 +633,7 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
                 */
                if (mtime.tv_sec > now + 60 * def_timestamp_timeout * 2) {
                    time_t tv_sec = (time_t)mtime.tv_sec;
-                   log_error(NO_EXIT,
+                   log_error(0,
                        _("timestamp too far in the future: %20.20s"),
                        4 + ctime(&tv_sec));
                    if (timestampfile)
@@ -680,7 +680,7 @@ remove_timestamp(bool remove)
            else
                status = rmdir(timestampdir);
            if (status == -1 && errno != ENOENT) {
-               log_error(NO_EXIT,
+               log_error(0,
                    _("unable to remove %s (%s), will reset to the epoch"),
                    path, strerror(errno));
                remove = false;
@@ -749,13 +749,13 @@ get_authpw(void)
 
     if (def_rootpw) {
        if ((pw = sudo_getpwuid(ROOT_UID)) == NULL)
-           log_error(0, _("unknown uid: %u"), ROOT_UID);
+           log_fatal(0, _("unknown uid: %u"), ROOT_UID);
     } else if (def_runaspw) {
        if ((pw = sudo_getpwnam(def_runas_default)) == NULL)
-           log_error(0, _("unknown user: %s"), def_runas_default);
+           log_fatal(0, _("unknown user: %s"), def_runas_default);
     } else if (def_targetpw) {
        if (runas_pw->pw_name == NULL)
-           log_error(NO_MAIL|MSG_ONLY, _("unknown uid: %u"),
+           log_fatal(NO_MAIL|MSG_ONLY, _("unknown uid: %u"),
                (unsigned int) runas_pw->pw_uid);
        pw_addref(runas_pw);
        pw = runas_pw;
index de3fcba0dfbf1ad899c7a01ac7a947a7d8982cde..32d06049d7b0f2751df7e3fc2462e12e4146fded 100644 (file)
@@ -870,7 +870,7 @@ insert_env_vars(char * const envp[])
 /*
  * Validate the list of environment variables passed in on the command
  * line against env_delete, env_check, and env_keep.
- * Calls log_error() if any specified variables are not allowed.
+ * Calls log_fatal() if any specified variables are not allowed.
  */
 void
 validate_env_vars(char * const env_vars[])
@@ -914,7 +914,7 @@ validate_env_vars(char * const env_vars[])
     }
     if (bad != NULL) {
        bad[blen - 2] = '\0';           /* remove trailing ", " */
-       log_error(NO_MAIL,
+       log_fatal(NO_MAIL,
            _("sorry, you are not allowed to set the following environment variables: %s"), bad);
        /* NOTREACHED */
        efree(bad);
index 1f591e924fea262916ea313d5fe024fd22ebf159..f265920e11aff16511dd99b97cab37d2cf277f87 100644 (file)
@@ -120,9 +120,9 @@ mkdir_parents(char *path)
        *slash = '\0';
        if (stat(path, &sb) != 0) {
            if (mkdir(path, S_IRWXU) != 0)
-               log_error(USE_ERRNO, _("unable to mkdir %s"), path);
+               log_fatal(USE_ERRNO, _("unable to mkdir %s"), path);
        } else if (!S_ISDIR(sb.st_mode)) {
-           log_error(0, _("%s: %s"), path, strerror(ENOTDIR));
+           log_fatal(0, _("%s: %s"), path, strerror(ENOTDIR));
        }
        *slash = '/';
     }
@@ -153,9 +153,9 @@ io_nextid(char *iolog_dir, char sessid[7])
     mkdir_parents(iolog_dir);
     if (stat(iolog_dir, &sb) != 0) {
        if (mkdir(iolog_dir, S_IRWXU) != 0)
-           log_error(USE_ERRNO, _("unable to mkdir %s"), iolog_dir);
+           log_fatal(USE_ERRNO, _("unable to mkdir %s"), iolog_dir);
     } else if (!S_ISDIR(sb.st_mode)) {
-       log_error(0, _("%s exists but is not a directory (0%o)"),
+       log_fatal(0, _("%s exists but is not a directory (0%o)"),
            iolog_dir, (unsigned int) sb.st_mode);
     }
 
@@ -165,21 +165,21 @@ io_nextid(char *iolog_dir, char sessid[7])
     len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", iolog_dir);
     if (len <= 0 || len >= sizeof(pathbuf)) {
        errno = ENAMETOOLONG;
-       log_error(USE_ERRNO, "%s/seq", pathbuf);
+       log_fatal(USE_ERRNO, "%s/seq", pathbuf);
     }
     fd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
     if (fd == -1)
-       log_error(USE_ERRNO, _("unable to open %s"), pathbuf);
+       log_fatal(USE_ERRNO, _("unable to open %s"), pathbuf);
     lock_file(fd, SUDO_LOCK);
 
     /* Read seq number (base 36). */
     nread = read(fd, buf, sizeof(buf));
     if (nread != 0) {
        if (nread == -1)
-           log_error(USE_ERRNO, _("unable to read %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to read %s"), pathbuf);
        id = strtoul(buf, &ep, 36);
        if (buf == ep || id >= SESSID_MAX)
-           log_error(0, _("invalid sequence number %s"), pathbuf);
+           log_fatal(0, _("invalid sequence number %s"), pathbuf);
     }
     id++;
 
@@ -199,7 +199,7 @@ io_nextid(char *iolog_dir, char sessid[7])
 
     /* Rewind and overwrite old seq file. */
     if (lseek(fd, 0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
-       log_error(USE_ERRNO, _("unable to write to %s"), pathbuf);
+       log_fatal(USE_ERRNO, _("unable to write to %s"), pathbuf);
     close(fd);
 
     debug_return;
@@ -218,7 +218,7 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
     len = strlcpy(pathbuf, iolog_path, pathsize);
     if (len >= pathsize) {
        errno = ENAMETOOLONG;
-       log_error(USE_ERRNO, "%s", iolog_path);
+       log_fatal(USE_ERRNO, "%s", iolog_path);
     }
 
     /*
@@ -228,10 +228,10 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
     mkdir_parents(pathbuf);
     if (len >= 6 && strcmp(&pathbuf[len - 6], "XXXXXX") == 0) {
        if (mkdtemp(pathbuf) == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        if (mkdir(pathbuf, S_IRWXU) != 0)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     }
 
     debug_return_size_t(len);
@@ -439,7 +439,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        debug_return_bool(true);
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        rval = -1;
        goto done;
     }
@@ -496,18 +496,18 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
      */
     io_logfile = open_io_fd(pathbuf, len, "/log", false);
     if (io_logfile == NULL)
-       log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+       log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
 
     io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing",
        iolog_compress);
     if (io_fds[IOFD_TIMING].v == NULL)
-       log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+       log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
 
     if (details.iolog_ttyin) {
        io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin",
            iolog_compress);
        if (io_fds[IOFD_TTYIN].v == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_ttyin = NULL;
     }
@@ -515,7 +515,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin",
            iolog_compress);
        if (io_fds[IOFD_STDIN].v == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stdin = NULL;
     }
@@ -523,7 +523,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout",
            iolog_compress);
        if (io_fds[IOFD_TTYOUT].v == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_ttyout = NULL;
     }
@@ -531,7 +531,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout",
            iolog_compress);
        if (io_fds[IOFD_STDOUT].v == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stdout = NULL;
     }
@@ -539,7 +539,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr",
            iolog_compress);
        if (io_fds[IOFD_STDERR].v == NULL)
-           log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stderr = NULL;
     }
@@ -581,7 +581,7 @@ sudoers_io_close(int exit_status, int error)
     debug_decl(sudoers_io_close, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        debug_return;
     }
 
@@ -604,7 +604,7 @@ sudoers_io_version(int verbose)
     debug_decl(sudoers_io_version, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        debug_return_bool(-1);
     }
 
@@ -626,7 +626,7 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
     gettimeofday(&now, NULL);
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        debug_return_bool(-1);
     }
 
index 395f83b41f8b517ed84eb5e885c0270e473686ec..c6cff0be832fc6083ebe1b798e574ac2bde9bacd 100644 (file)
@@ -325,18 +325,18 @@ log_allowed(int status)
     debug_return;
 }
 
-void
-log_error(int flags, const char *fmt, ...)
+/*
+ * Perform logging for log_error()/log_fatal()
+ */
+static void
+vlog_error(int flags, const char *fmt, va_list ap)
 {
     int serrno = errno;
     char *logline, *message;
-    va_list ap;
-    debug_decl(log_error, SUDO_DEBUG_LOGGING)
+    debug_decl(vlog_error, SUDO_DEBUG_LOGGING)
 
     /* Expand printf-style format + args. */
-    va_start(ap, fmt);
     evasprintf(&message, fmt, ap);
-    va_end(ap);
 
     /* Become root if we are not already to avoid user interference */
     set_perms(PERM_ROOT|PERM_NOEXIT);
@@ -376,13 +376,40 @@ log_error(int flags, const char *fmt, ...)
 
     restore_perms();
 
-    if (!ISSET(flags, NO_EXIT)) {
-       plugin_cleanup(0);
-       siglongjmp(error_jmp, 1);
-    }
     debug_return;
 }
 
+void
+log_error(int flags, const char *fmt, ...)
+{
+    va_list ap;
+    debug_decl(log_error, SUDO_DEBUG_LOGGING)
+
+    /* Log the error. */
+    va_start(ap, fmt);
+    vlog_error(flags, fmt, ap);
+    va_end(ap);
+
+    debug_return;
+}
+
+void
+log_fatal(int flags, const char *fmt, ...)
+{
+    va_list ap;
+    debug_decl(log_error, SUDO_DEBUG_LOGGING)
+
+    /* Log the error. */
+    va_start(ap, fmt);
+    vlog_error(flags, fmt, ap);
+    va_end(ap);
+
+    /* Exit the plugin. */
+    plugin_cleanup(0);
+    sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+    siglongjmp(error_jmp, 1);
+}
+
 #define MAX_MAILFLAGS  63
 
 /*
index 7a89738c381fbc8916a321bdd32f3fbf0577b1dc..d8611ec08c244eb7d05c18e50d47ef2b130ed844 100644 (file)
 #define SLOG_FILE              0x02
 #define SLOG_BOTH              0x03
 
-/* Flags for log_error() */
+/* Flags for log_error()/log_fatal() */
 #define MSG_ONLY               0x01
 #define USE_ERRNO              0x02
 #define NO_MAIL                        0x04
-#define NO_EXIT                        0x08
-#define NO_STDERR              0x10
+#define NO_STDERR              0x08
 
 /*
  * Maximum number of characters to log per entry.  The syslogger
@@ -57,6 +56,7 @@ void audit_failure(char *[], char const * const, ...);
 void log_allowed(int);
 void log_denial(int, int);
 void log_error(int flags, const char *fmt, ...) __printflike(2, 3);
+void log_fatal(int flags, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__));
 void reapchild(int);
 void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
 
index 66385f07a8768989c1ff7f1ba0b85e3e199bc6cc..4937145f5aafa2eef2927a689502c3b9e3e826cf 100644 (file)
@@ -120,10 +120,10 @@ sudo_file_parse(struct sudo_nss *nss)
     yyin = nss->handle;
     if (yyparse() != 0 || parse_error) {
        if (errorlineno != -1) {
-           log_error(NO_EXIT, _("parse error in %s near line %d"),
+           log_error(0, _("parse error in %s near line %d"),
                errorfile, errorlineno);
        } else {
-           log_error(NO_EXIT, _("parse error in %s"), errorfile);
+           log_error(0, _("parse error in %s"), errorfile);
        }
        debug_return_int(-1);
     }
index e3269f2cdc2983cf747a26d8427971e4c9044dc9..7a2036a00f409a67a742f5b994c8eb3a74062bce 100644 (file)
@@ -1511,7 +1511,7 @@ runas_setgroups(void)
     aix_restoreauthdb();
 #endif
     if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
-       log_error(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
+       log_fatal(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
     debug_return_ptr(grlist);
 }
 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
index 26bb926ed8952105e1e070df38be8fa559fada3a..3f86ea19fcd678ef16b600e8e17817e566fdc3ba 100644 (file)
@@ -158,7 +158,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        args = NULL;
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        rewind_perms();
        debug_return_bool(-1);
     }
@@ -205,7 +205,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
            sources++;
            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) {
@@ -236,7 +236,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        set_runaspw(runas_user ? runas_user : def_runas_default);
 
     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)
        set_fqdn();     /* deferred until after sudoers is parsed */
@@ -255,7 +255,7 @@ sudoers_policy_close(int exit_status, int error_code)
     debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        debug_return;
     }
 
@@ -292,7 +292,7 @@ sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
        user_env = NULL;
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* called via error(), errorx() or log_error() */
+       /* called via error(), errorx() or log_fatal() */
        return -1;
     }
 
@@ -312,7 +312,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     debug_decl(sudoers_policy_main, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* error recovery via error(), errorx() or log_error() */
+       /* error recovery via error(), errorx() or log_fatal() */
        rval = -1;
        goto done;
     }
@@ -416,7 +416,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        else
            pw = sudo_getpwnam(def_timestampowner);
        if (!pw)
-           log_error(0, _("timestamp owner (%s): No such user"),
+           log_fatal(0, _("timestamp owner (%s): No such user"),
                def_timestampowner);
        timestamp_uid = pw->pw_uid;
        pw_delref(pw);
@@ -852,9 +852,9 @@ init_vars(char * const envp[])
        if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE)
            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);
-       log_error(0, _("unknown uid: %u"), (unsigned int) user_uid);
+       log_fatal(0, _("unknown uid: %u"), (unsigned int) user_uid);
        /* NOTREACHED */
     }
 
@@ -867,7 +867,7 @@ init_vars(char * const envp[])
     /* Set runas callback. */
     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;
 }
 
@@ -952,7 +952,7 @@ set_cmnd(void)
        user_base = user_cmnd;
 
     if (!update_defaults(SETDEF_CMND))
-       log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries"));
+       log_error(NO_STDERR, _("problem with defaults entries"));
 
     debug_return_int(rval);
 }
@@ -973,14 +973,14 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
        case SUDO_PATH_SECURE:
            if ((fp = fopen(sudoers, "r")) == NULL) {
-               log_error(USE_ERRNO|NO_EXIT, _("unable to open %s"), sudoers);
+               log_error(USE_ERRNO, _("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 (sb.st_size != 0 && fgetc(fp) == EOF) {
-                   log_error(USE_ERRNO|NO_EXIT, _("unable to read %s"),
+                   log_error(USE_ERRNO, _("unable to read %s"),
                        sudoers);
                    fclose(fp);
                    fp = NULL;
@@ -992,20 +992,20 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
            }
            break;
        case SUDO_PATH_MISSING:
-           log_error(USE_ERRNO|NO_EXIT, _("unable to stat %s"), sudoers);
+           log_error(USE_ERRNO, _("unable to stat %s"), sudoers);
            break;
        case SUDO_PATH_BAD_TYPE:
-           log_error(NO_EXIT, _("%s is not a regular file"), sudoers);
+           log_error(0, _("%s is not a regular file"), sudoers);
            break;
        case SUDO_PATH_WRONG_OWNER:
-           log_error(NO_EXIT, _("%s is owned by uid %u, should be %u"),
+           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(NO_EXIT, _("%s is world writable"), sudoers);
+           log_error(0, _("%s is world writable"), sudoers);
            break;
        case SUDO_PATH_GROUP_WRITABLE:
-           log_error(NO_EXIT, _("%s is owned by gid %u, should be %u"),
+           log_error(0, _("%s is owned by gid %u, should be %u"),
                sudoers, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
            break;
        default:
@@ -1022,23 +1022,13 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
 static void
 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)
        debug_return;
 
-    /*
-     * Don't make it a fatal error if the user didn't specify the login
-     * 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 (user_uid != 0 &&
            strcmp(runas_user ? runas_user : def_runas_default, "root") != 0)
@@ -1053,7 +1043,15 @@ set_loginclass(struct passwd *pw)
     /* Make sure specified login class is valid. */
     lc = login_getclass(login_class);
     if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
-       log_error(errflags, _("unknown login class: %s"), login_class);
+       /*
+        * Don't make it a fatal error if the user didn't specify the login
+        * 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);
@@ -1080,8 +1078,7 @@ set_fqdn(void)
     hint.ai_family = PF_UNSPEC;
     hint.ai_flags = AI_CANONNAME;
     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
-       log_error(MSG_ONLY|NO_EXIT,
-           _("unable to resolve host %s"), user_host);
+       log_error(MSG_ONLY, _("unable to resolve host %s"), user_host);
     } else {
        if (user_shost != user_host)
            efree(user_shost);
@@ -1112,7 +1109,7 @@ set_runaspw(const char *user)
            runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
     } else {
        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;
 }
@@ -1133,7 +1130,7 @@ set_runasgr(const char *group)
            runas_gr = sudo_fakegrnam(group);
     } else {
        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;
 }
@@ -1178,7 +1175,7 @@ sudoers_policy_version(int verbose)
     debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
-       /* error recovery via error(), errorx() or log_error() */
+       /* error recovery via error(), errorx() or log_fatal() */
        debug_return_bool(-1);
     }