Imported Upstream version 1.8.4p4
[debian/sudo] / plugins / sudoers / sudoers.c
index 0e25866d4d3396734a336231b845c103573b518e..168b23307994acac2ac0cd8f8cff37563932201d 100644 (file)
@@ -76,6 +76,9 @@
 #endif
 #include <ctype.h>
 #include <setjmp.h>
+#ifndef HAVE_GETADDRINFO
+# include "compat/getaddrinfo.h"
+#endif
 
 #include "sudoers.h"
 #include "interfaces.h"
@@ -107,14 +110,10 @@ struct sudo_user sudo_user;
 struct passwd *list_pw;
 struct interface *interfaces;
 int long_list;
-int debug_level;
 uid_t timestamp_uid;
 extern int errorlineno;
-extern int parse_error;
+extern bool parse_error;
 extern char *errorfile;
-#ifdef HAVE_LOGIN_CAP_H
-login_cap_t *lc;
-#endif /* HAVE_LOGIN_CAP_H */
 #ifdef HAVE_BSD_AUTH_H
 char *login_style;
 #endif /* HAVE_BSD_AUTH_H */
@@ -133,8 +132,8 @@ static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
 int NewArgc;
 char **NewArgv;
 
-/* plugin_error.c */
-extern sigjmp_buf error_jmp;
+/* Declared here instead of plugin_error.c for static sudo builds. */
+sigjmp_buf error_jmp;
 
 static int
 sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
@@ -144,6 +143,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     volatile int sources = 0;
     sigaction_t sa;
     struct sudo_nss *nss;
+    debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
 
     if (!sudo_conv)
        sudo_conv = conversation;
@@ -153,7 +153,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
        rewind_perms();
-       return -1;
+       debug_return_bool(-1);
     }
 
     bindtextdomain("sudoers", LOCALEDIR);
@@ -203,7 +203,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     }
     if (sources == 0) {
        warningx(_("no valid sudoers sources found, quitting"));
-       return -1;
+       debug_return_bool(-1);
     }
 
     /* XXX - collect post-sudoers parse settings into a function */
@@ -212,7 +212,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
      * Initialize external group plugin, if any.
      */
     if (def_group_plugin) {
-       if (group_plugin_load(def_group_plugin) != TRUE)
+       if (group_plugin_load(def_group_plugin) != true)
            def_group_plugin = NULL;
     }
 
@@ -235,19 +235,21 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        set_fqdn();     /* deferred until after sudoers is parsed */
 
     /* Set login class if applicable. */
-    set_loginclass(sudo_user.pw);
+    set_loginclass(runas_pw ? runas_pw : sudo_user.pw);
 
     restore_perms();
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static void
 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() */
-       return;
+       debug_return;
     }
 
     /* We do not currently log the exit status. */
@@ -265,6 +267,8 @@ sudoers_policy_close(int exit_status, int error_code)
        gr_delref(runas_gr);
     if (user_group_list != NULL)
        grlist_delref(user_group_list);
+
+    debug_return;
 }
 
 /*
@@ -274,12 +278,14 @@ sudoers_policy_close(int exit_status, int error_code)
 static int
 sudoers_policy_init_session(struct passwd *pwd)
 {
+    debug_decl(sudoers_policy_init, SUDO_DEBUG_PLUGIN)
+
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
        return -1;
     }
 
-    return sudo_auth_begin_session(pwd);
+    debug_return_bool(sudo_auth_begin_session(pwd));
 }
 
 static int
@@ -291,7 +297,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     struct sudo_nss *nss;
     int cmnd_status = -1, validated;
     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)) {
        /* error recovery via error(), errorx() or log_error() */
@@ -335,13 +342,13 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        NewArgv = emalloc2(NewArgc + 2, sizeof(char *));
        memcpy(++NewArgv, argv, argc * sizeof(char *));
        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);
     }
 
     /* If given the -P option, set the "preserve_groups" flag. */
     if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
-       def_preserve_groups = TRUE;
+       def_preserve_groups = true;
 
     /* Find command in path */
     cmnd_status = set_cmnd();
@@ -427,14 +434,14 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
      */
     if (ISSET(sudo_mode, MODE_EDIT) ||
        (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. */
     rebuild_env();
 
     /* Require a password if sudoers says so.  */
     rval = check_user(validated, sudo_mode);
-    if (rval != TRUE)
+    if (rval != true)
        goto done;
 
     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
@@ -584,13 +591,13 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
 
 #if defined(__linux__) || defined(_AIX)
        /* Insert system-wide environment variables. */
-       read_env_file(_PATH_ENVIRONMENT, TRUE);
+       read_env_file(_PATH_ENVIRONMENT, true);
 #endif
     }
 
     /* Insert system-wide environment variables. */
     if (def_env_file)
-       read_env_file(def_env_file, FALSE);
+       read_env_file(def_env_file, false);
 
     /* Insert user-specified environment variables. */
     insert_env_vars(sudo_user.env_vars);
@@ -630,19 +637,33 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        command_info[info_len++] = "preserve_groups=true";
     } else {
        int i, len;
+       gid_t egid;
        size_t glsize;
        char *cp, *gid_list;
        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);
        memcpy(gid_list, "runas_groups=", 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++) {
-           /* XXX - check rval */
-           len = snprintf(cp, glsize - (cp - gid_list), "%s%u",
-                i ? "," : "", (unsigned int) grlist->gids[i]);
-           cp += len;
+           if (grlist->gids[i] != egid) {
+               len = snprintf(cp, glsize - (cp - gid_list), ",%u",
+                    (unsigned int) grlist->gids[i]);
+               if (len < 0 || len >= glsize - (cp - gid_list))
+                   errorx(1, _("internal error, runas_groups overflow"));
+               cp += len;
+           }
        }
        command_info[info_len++] = gid_list;
        grlist_delref(grlist);
@@ -651,8 +672,6 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
     if (def_noexec)
        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)
        command_info[info_len++] = estrdup("set_utmp=true");
     if (def_use_pty)
@@ -660,8 +679,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     if (def_utmp_runas)
        command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name);
 #ifdef HAVE_LOGIN_CAP_H
-    if (lc != NULL)
-       command_info[info_len++] = fmt_string("login_class", lc->lc_class);
+    if (def_use_loginclass)
+       command_info[info_len++] = fmt_string("login_class", login_class);
 #endif /* HAVE_LOGIN_CAP_H */
 #ifdef HAVE_SELINUX
     if (user_role != NULL)
@@ -681,7 +700,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     goto done;
 
 bad:
-    rval = FALSE;
+    rval = false;
 
 done:
     rewind_perms();
@@ -690,37 +709,45 @@ done:
     sudo_endpwent();
     sudo_endgrent();
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 static int
 sudoers_policy_check(int argc, char * const argv[], char *env_add[],
     char **command_infop[], char **argv_out[], char **user_env_out[])
 {
+    debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN)
+
     if (!ISSET(sudo_mode, MODE_EDIT))
        SET(sudo_mode, MODE_RUN);
 
-    return sudoers_policy_main(argc, argv, 0, env_add, command_infop,
-       argv_out, user_env_out);
+    debug_return_bool(sudoers_policy_main(argc, argv, 0, env_add, command_infop,
+       argv_out, user_env_out));
 }
 
 static int
 sudoers_policy_validate(void)
 {
+    debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN)
+
     user_cmnd = "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
 sudoers_policy_invalidate(int remove)
 {
+    debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN)
+
     user_cmnd = "kill";
     if (sigsetjmp(error_jmp, 1) == 0) {
        remove_timestamp(remove);
        plugin_cleanup(0);
     }
+
+    debug_return;
 }
 
 static int
@@ -728,6 +755,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
     const char *list_user)
 {
     int rval;
+    debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN)
 
     user_cmnd = "list";
     if (argc)
@@ -740,7 +768,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
        list_pw = sudo_getpwnam(list_user);
        if (list_pw == NULL) {
            warningx(_("unknown user: %s"), list_user);
-           return -1;
+           debug_return_bool(-1);
        }
     }
     rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL);
@@ -749,7 +777,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
        list_pw = NULL;
     }
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 /*
@@ -760,6 +788,7 @@ static void
 init_vars(char * const envp[])
 {
     char * const * ep;
+    debug_decl(init_vars, SUDO_DEBUG_PLUGIN)
 
 #ifdef HAVE_TZSET
     (void) tzset();            /* set the timezone if applicable */
@@ -815,6 +844,7 @@ init_vars(char * const envp[])
     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
 
     /* It is now safe to use log_error() and set_perms() */
+    debug_return;
 }
 
 /*
@@ -826,6 +856,7 @@ set_cmnd(void)
 {
     int rval;
     char *path = user_path;
+    debug_decl(set_cmnd, SUDO_DEBUG_PLUGIN)
 
     /* Resolve the path and return. */
     rval = FOUND;
@@ -899,7 +930,7 @@ set_cmnd(void)
     if (!update_defaults(SETDEF_CMND))
        log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries"));
 
-    return rval;
+    debug_return_int(rval);
 }
 
 /*
@@ -907,11 +938,12 @@ set_cmnd(void)
  * Returns a handle to the sudoers file or NULL on error.
  */
 FILE *
-open_sudoers(const char *sudoers, int doedit, int *keepopen)
+open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
 {
     struct stat statbuf;
     FILE *fp = NULL;
     int rootstat;
+    debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN)
 
     /*
      * Fix the mode and group on sudoers file from old default.
@@ -946,7 +978,7 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
        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)
+    else if ((statbuf.st_mode & 07577) != (sudoers_mode & 07577))
        log_error(NO_EXIT, _("%s is mode 0%o, should be 0%o"), sudoers,
            (unsigned int) (statbuf.st_mode & 07777),
            (unsigned int) sudoers_mode);
@@ -976,7 +1008,7 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
     }
 
     restore_perms();           /* change back to root */
-    return fp;
+    debug_return_ptr(fp);
 }
 
 #ifdef HAVE_LOGIN_CAP_H
@@ -984,6 +1016,11 @@ static void
 set_loginclass(struct passwd *pw)
 {
     int errflags;
+    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
@@ -1006,12 +1043,14 @@ set_loginclass(struct passwd *pw)
                (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
     }
 
+    /* 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);
-       if (!lc)
-           lc = login_getclass(NULL);  /* needed for login_getstyle() later */
+       def_use_loginclass = false;
     }
+    login_close(lc);
+    debug_return;
 }
 #else
 static void
@@ -1026,47 +1065,39 @@ set_loginclass(struct passwd *pw)
 void
 set_fqdn(void)
 {
-#ifdef HAVE_GETADDRINFO
     struct addrinfo *res0, hint;
-#else
-    struct hostent *hp;
-#endif
     char *p;
+    debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN)
 
-#ifdef HAVE_GETADDRINFO
     zero_bytes(&hint, sizeof(hint));
     hint.ai_family = PF_UNSPEC;
     hint.ai_flags = AI_CANONNAME;
     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
-#else
-    if (!(hp = gethostbyname(user_host))) {
-#endif
        log_error(MSG_ONLY|NO_EXIT,
            _("unable to resolve host %s"), user_host);
     } else {
        if (user_shost != user_host)
            efree(user_shost);
        efree(user_host);
-#ifdef HAVE_GETADDRINFO
        user_host = estrdup(res0->ai_canonname);
        freeaddrinfo(res0);
-#else
-       user_host = estrdup(hp->h_name);
-#endif
     }
     if ((p = strchr(user_host, '.')) != NULL)
        user_shost = estrndup(user_host, (size_t)(p - user_host));
     else
        user_shost = user_host;
+    debug_return;
 }
 
 /*
  * 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".
  */
-void
+static void
 set_runaspw(const char *user)
 {
+    debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
+
     if (runas_pw != NULL)
        pw_delref(runas_pw);
     if (*user == '#') {
@@ -1076,6 +1107,7 @@ set_runaspw(const char *user)
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
            log_error(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user);
     }
+    debug_return;
 }
 
 /*
@@ -1085,6 +1117,8 @@ set_runaspw(const char *user)
 static void
 set_runasgr(const char *group)
 {
+    debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
+
     if (runas_gr != NULL)
        gr_delref(runas_gr);
     if (*group == '#') {
@@ -1094,6 +1128,7 @@ set_runasgr(const char *group)
        if ((runas_gr = sudo_getgrnam(group)) == NULL)
            log_error(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group);
     }
+    debug_return;
 }
 
 /*
@@ -1105,7 +1140,7 @@ cb_runas_default(const char *user)
     /* Only reset runaspw if user didn't specify one. */
     if (!runas_user && !runas_group)
        set_runaspw(user);
-    return TRUE;
+    return true;
 }
 
 /*
@@ -1117,6 +1152,7 @@ plugin_cleanup(int gotsignal)
     struct sudo_nss *nss;
 
     if (!gotsignal) {
+       debug_decl(plugin_cleanup, SUDO_DEBUG_PLUGIN)
        if (snl != NULL) {
            tq_foreach_fwd(snl, nss)
                nss->close(nss);
@@ -1125,15 +1161,18 @@ plugin_cleanup(int gotsignal)
            group_plugin_unload();
        sudo_endpwent();
        sudo_endgrent();
+       debug_return;
     }
 }
 
 static int
 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() */
-       return -1;
+       debug_return_bool(-1);
     }
 
     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
@@ -1153,10 +1192,12 @@ sudoers_policy_version(int verbose)
        dump_auth_methods();
        dump_defaults();
        sudo_printf(SUDO_CONV_INFO_MSG, "\n");
-       dump_interfaces(interfaces_string);
-       sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+       if (interfaces_string != NULL) {
+           dump_interfaces(interfaces_string);
+           sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+       }
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static int
@@ -1164,7 +1205,9 @@ deserialize_info(char * const settings[], char * const user_info[])
 {
     char * const *cur;
     const char *p, *groups = NULL;
+    const char *debug_flags = NULL;
     int flags = 0;
+    debug_decl(deserialize_info, SUDO_DEBUG_PLUGIN)
 
 #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
 
@@ -1175,8 +1218,8 @@ deserialize_info(char * const settings[], char * const user_info[])
            user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
            continue;
        }
-       if (MATCHES(*cur, "debug_level=")) {
-           debug_level = atoi(*cur + sizeof("debug_level=") - 1);
+       if (MATCHES(*cur, "debug_flags=")) {
+           debug_flags = *cur + sizeof("debug_flags=") - 1;
            continue;
        }
        if (MATCHES(*cur, "runas_user=")) {
@@ -1189,59 +1232,59 @@ deserialize_info(char * const settings[], char * const user_info[])
        }
        if (MATCHES(*cur, "prompt=")) {
            user_prompt = *cur + sizeof("prompt=") - 1;
-           def_passprompt_override = TRUE;
+           def_passprompt_override = true;
            continue;
        }
        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);
            continue;
        }
        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);
            continue;
        }
        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);
            continue;
        }
        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);
-               def_env_reset = TRUE;
+               def_env_reset = true;
            }
            continue;
        }
        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);
            continue;
        }
        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);
            continue;
        }
        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);
            continue;
        }
        if (MATCHES(*cur, "noninteractive=")) {
-           if (atobool(*cur + sizeof("noninteractive=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("noninteractive=") - 1) == true)
                SET(flags, MODE_NONINTERACTIVE);
            continue;
        }
        if (MATCHES(*cur, "sudoedit=")) {
-           if (atobool(*cur + sizeof("sudoedit=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("sudoedit=") - 1) == true)
                SET(flags, MODE_EDIT);
            continue;
        }
        if (MATCHES(*cur, "login_class=")) {
            login_class = *cur + sizeof("login_class=") - 1;
-           def_use_loginclass = TRUE;
+           def_use_loginclass = true;
            continue;
        }
 #ifdef HAVE_SELINUX
@@ -1368,15 +1411,26 @@ deserialize_info(char * const settings[], char * const user_info[])
        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
-    return flags;
+    debug_return_int(flags);
 }
 
 static char *
 resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
 {
     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 */
 
@@ -1386,11 +1440,11 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
      * line args so look for those and alloc space for them too.
      */
     nargc = 1;
-    for (wasblank = FALSE, cp = editor; *cp != '\0'; cp++) {
+    for (wasblank = false, cp = editor; *cp != '\0'; cp++) {
        if (isblank((unsigned char) *cp))
-           wasblank = TRUE;
+           wasblank = true;
        else if (wasblank) {
-           wasblank = FALSE;
+           wasblank = false;
            nargc++;
        }
     }
@@ -1399,7 +1453,7 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
     if (cp == NULL ||
        find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) {
        efree(editor);
-       return NULL;
+       debug_return_str(NULL);
     }
     nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *));
     for (ac = 0; cp != NULL && ac < nargc; ac++) {
@@ -1412,7 +1466,7 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
     nargv[ac] = NULL;
 
     *argv_out = nargv;
-    return editor_path;
+    debug_return_str(editor_path);
 }
 
 /*
@@ -1424,6 +1478,7 @@ static char *
 find_editor(int nfiles, char **files, char ***argv_out)
 {
     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.
@@ -1454,7 +1509,7 @@ find_editor(int nfiles, char **files, char ***argv_out)
        audit_failure(NewArgv, _("%s: command not found"), editor);
        warningx(_("%s: command not found"), editor);
     }
-    return editor_path;
+    debug_return_str(editor_path);
 }
 
 #ifdef USE_ADMIN_FLAG
@@ -1464,16 +1519,17 @@ create_admin_success_flag(void)
     struct stat statbuf;
     char flagfile[PATH_MAX];
     int fd, n;
+    debug_decl(create_admin_success_flag, SUDO_DEBUG_PLUGIN)
 
     /* Check whether the user is in the admin group. */
     if (!user_in_group(sudo_user.pw, "admin"))
-       return;
+       debug_return;
 
     /* Build path to flag file. */
     n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful",
        user_dir);
     if (n <= 0 || n >= sizeof(flagfile))
-       return;
+       debug_return;
 
     /* Create admin flag file if it doesn't already exist. */
     set_perms(PERM_USER);
@@ -1482,6 +1538,7 @@ create_admin_success_flag(void)
        close(fd);
     }
     restore_perms();
+    debug_return;
 }
 #else /* !USE_ADMIN_FLAG */
 static void