]> granicus.if.org Git - sudo/commitdiff
Add SUDO_DEBUG_ERRNO flag to debug functions so we can log errno.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 4 Apr 2012 20:59:31 +0000 (16:59 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 4 Apr 2012 20:59:31 +0000 (16:59 -0400)
Use this flag when wrapping error() and warning() so the debug
output includes the error string.

common/sudo_debug.c
include/error.h
include/sudo_debug.h
src/conversation.c

index 84b1ad1ae0ac52433ec75508159cdc9d34de57ca..2b2a12355eb78a9be2ed05b6c51d03e3f17c5d42 100644 (file)
@@ -252,12 +252,13 @@ void sudo_debug_exit_ptr(const char *func, const char *file, int line,
 }
 
 void
-sudo_debug_write(const char *str, int len)
+sudo_debug_write(const char *str, int len, int errno_val)
 {
     char *timestr;
     time_t now;
-    struct iovec iov[5];
+    struct iovec iov[7];
     int iovcnt = 4;
+    bool need_newline = false;
 
     if (len <= 0)
        return;
@@ -266,14 +267,22 @@ sudo_debug_write(const char *str, int len)
     case SUDO_DEBUG_MODE_CONV:
        /* Call conversation function */
        if (sudo_conv != NULL) {
-           struct sudo_conv_message msg;
-           struct sudo_conv_reply repl;
-
-           memset(&msg, 0, sizeof(msg));
-           memset(&repl, 0, sizeof(repl));
-           msg.msg_type = SUDO_CONV_DEBUG_MSG;
-           msg.msg = str;
-           sudo_conv(1, &msg, &repl);
+           struct sudo_conv_message msg[3];
+           struct sudo_conv_reply repl[3];
+           int msgcnt = 1;
+
+           memset(msg, 0, sizeof(msg));
+           memset(repl, 0, sizeof(repl));
+           msg[0].msg_type = SUDO_CONV_DEBUG_MSG;
+           msg[0].msg = str;
+           if (errno_val) {
+               msgcnt = 3;
+               msg[1].msg_type = SUDO_CONV_DEBUG_MSG;
+               msg[1].msg = ": ";
+               msg[2].msg_type = SUDO_CONV_DEBUG_MSG;
+               msg[2].msg = strerror(errno_val);
+           }
+           sudo_conv(msgcnt, msg, repl);
        }
        break;
     case SUDO_DEBUG_MODE_FILE:
@@ -286,10 +295,30 @@ sudo_debug_write(const char *str, int len)
        /* Add string along with newline if it doesn't have one. */
        iov[3].iov_base = (char *)str;
        iov[3].iov_len = len;
-       if (str[len - 1] != '\n') {
+       if (str[len - 1] != '\n')
+           need_newline = true;
+
+       /* Append error string if errno is specified. */
+       if (errno_val) {
+           iov[iovcnt].iov_base = ": ";
+           iov[iovcnt].iov_len = 2;
+           iovcnt++;
+           iov[iovcnt].iov_base = strerror(errno_val);
+           iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base);
+           iovcnt++;
+
+           /* Move newline to the end. */
+           if (!need_newline) {
+               need_newline = true;
+               iov[3].iov_len--;
+           }
+       }
+
+       /* Append newline as needed. */
+       if (need_newline) {
            /* force newline */
-           iov[4].iov_base = "\n";
-           iov[4].iov_len = 1;
+           iov[iovcnt].iov_base = "\n";
+           iov[iovcnt].iov_len = 1;
            iovcnt++;
        }
 
@@ -310,7 +339,7 @@ sudo_debug_write(const char *str, int len)
 void
 sudo_debug_printf2(int level, const char *fmt, ...)
 {
-    int buflen, pri, subsys;
+    int buflen, pri, subsys, saved_errno = errno;
     va_list ap;
     char *buf;
 
@@ -322,16 +351,20 @@ sudo_debug_printf2(int level, const char *fmt, ...)
     subsys = SUDO_DEBUG_SUBSYS(level);
 
     /* Make sure we want debug info at this level. */
-    if (subsys >= NUM_SUBSYSTEMS || sudo_debug_settings[subsys] < pri)
-       return;
-
-    va_start(ap, fmt);
-    buflen = vasprintf(&buf, fmt, ap);
-    va_end(ap);
-    if (buflen != -1) {
-       sudo_debug_write(buf, buflen);
-       free(buf);
+    if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) {
+       va_start(ap, fmt);
+       buflen = vasprintf(&buf, fmt, ap);
+       va_end(ap);
+       if (buflen != -1) {
+           if (ISSET(level, SUDO_DEBUG_ERRNO))
+               sudo_debug_write(buf, buflen, saved_errno);
+           else
+               sudo_debug_write(buf, buflen, 0);
+           free(buf);
+       }
     }
+
+    errno = saved_errno;
 }
 
 void
@@ -411,7 +444,7 @@ sudo_debug_execve2(int level, const char *path, char *const argv[], char *const
 
     *cp = '\0';
 
-    sudo_debug_write(buf, buflen);
+    sudo_debug_write(buf, buflen, 0);
     free(buf);
 }
 
index fdc1e08bf1d45657e43cda88b9195f764d7da67e..17cc0697c57682fe8488d91d4a7a31d87f62bc0b 100644 (file)
@@ -38,7 +38,7 @@
 #else /* SUDO_ERROR_WRAP */
 # if defined(__GNUC__) && __GNUC__ == 2
 #  define error(rval, fmt...) do {                                            \
-    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|sudo_debug_subsys, (fmt));\
     error2((rval), (fmt));                                                    \
 } while (0)
 #  define errorx(rval, fmt...) do {                                           \
@@ -46,7 +46,7 @@
     errorx2((rval), (fmt));                                                   \
 } while (0)
 #  define warning(fmt...) do {                                                \
-    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|sudo_debug_subsys, (fmt));\
     warning2((fmt));                                                          \
 } while (0)
 #  define warningx(fmt...) do {                                                       \
@@ -55,7 +55,7 @@
 } while (0)
 # else
 #  define error(rval, ...) do {                                                       \
-    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);      \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|sudo_debug_subsys, __VA_ARGS__);\
     error2((rval), __VA_ARGS__);                                              \
 } while (0)
 #  define errorx(rval, ...) do {                                              \
@@ -63,7 +63,7 @@
     errorx2((rval), __VA_ARGS__);                                             \
 } while (0)
 #  define warning(...) do {                                                   \
-    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);      \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|sudo_debug_subsys, __VA_ARGS__);\
     warning2(__VA_ARGS__);                                                    \
 } while (0)
 #  define warningx(...) do {                                                  \
index e2896f7e86d0ece224d59fae738e84f6fee2cd3b..41389c7989a2c051c8eda27f8bd7b5735e585ddf 100644 (file)
@@ -21,8 +21,9 @@
 
 /*
  * The priority and subsystem are encoded in a single 32-bit value.
- * The lower 4 bits are the priority and the top 28 bits are the subsystem.
+ * The lower 4 bits are the priority and the top 27 bits are the subsystem.
  * This allows for 16 priorities and a very large number of subsystems.
+ * Bit 5 is used as a flag to specify whether to log the errno value.
  */
 
 /*
  * This includes subsystems in the sudoers plugin.
  * Note: order must match sudo_debug_subsystems[]
  */
-#define SUDO_DEBUG_MAIN                (1<<4)  /* sudo main() */
-#define SUDO_DEBUG_ARGS                (2<<4)  /* command line argument processing */
-#define SUDO_DEBUG_EXEC                (3<<4)  /* command execution */
-#define SUDO_DEBUG_PTY         (4<<4)  /* pseudo-tty */
-#define SUDO_DEBUG_UTMP                (5<<4)  /* utmp file ops */
-#define SUDO_DEBUG_CONV                (6<<4)  /* user conversation */
-#define SUDO_DEBUG_PCOMM       (7<<4)  /* plugin communications */
-#define SUDO_DEBUG_UTIL                (8<<4)  /* utility functions */
-#define SUDO_DEBUG_NETIF       (9<<4)  /* network interface functions */
-#define SUDO_DEBUG_AUDIT       (10<<4) /* audit */
-#define SUDO_DEBUG_EDIT                (11<<4) /* sudoedit */
-#define SUDO_DEBUG_SELINUX     (12<<4) /* selinux */
-#define SUDO_DEBUG_LDAP                (13<<4) /* sudoers LDAP */
-#define SUDO_DEBUG_MATCH       (14<<4) /* sudoers matching */
-#define SUDO_DEBUG_PARSER      (15<<4) /* sudoers parser */
-#define SUDO_DEBUG_ALIAS       (16<<4) /* sudoers alias functions */
-#define SUDO_DEBUG_DEFAULTS    (17<<4) /* sudoers defaults settings */
-#define SUDO_DEBUG_AUTH                (18<<4) /* authentication functions */
-#define SUDO_DEBUG_ENV         (19<<4) /* environment handling */
-#define SUDO_DEBUG_LOGGING     (20<<4) /* logging functions */
-#define SUDO_DEBUG_NSS         (21<<4) /* network service switch */
-#define SUDO_DEBUG_RBTREE      (22<<4) /* red-black tree functions */
-#define SUDO_DEBUG_PERMS       (23<<4) /* uid/gid swapping functions */
-#define SUDO_DEBUG_PLUGIN      (24<<4) /* main plugin functions */
-#define SUDO_DEBUG_HOOKS       (25<<4) /* hook functions */
+#define SUDO_DEBUG_MAIN                ( 1<<5) /* sudo main() */
+#define SUDO_DEBUG_ARGS                ( 2<<5) /* command line argument processing */
+#define SUDO_DEBUG_EXEC                ( 3<<5) /* command execution */
+#define SUDO_DEBUG_PTY         ( 4<<5) /* pseudo-tty */
+#define SUDO_DEBUG_UTMP                ( 5<<5) /* utmp file ops */
+#define SUDO_DEBUG_CONV                ( 6<<5) /* user conversation */
+#define SUDO_DEBUG_PCOMM       ( 7<<5) /* plugin communications */
+#define SUDO_DEBUG_UTIL                ( 8<<5) /* utility functions */
+#define SUDO_DEBUG_NETIF       ( 9<<5) /* network interface functions */
+#define SUDO_DEBUG_AUDIT       (10<<5) /* audit */
+#define SUDO_DEBUG_EDIT                (11<<5) /* sudoedit */
+#define SUDO_DEBUG_SELINUX     (12<<5) /* selinux */
+#define SUDO_DEBUG_LDAP                (13<<5) /* sudoers LDAP */
+#define SUDO_DEBUG_MATCH       (14<<5) /* sudoers matching */
+#define SUDO_DEBUG_PARSER      (15<<5) /* sudoers parser */
+#define SUDO_DEBUG_ALIAS       (16<<5) /* sudoers alias functions */
+#define SUDO_DEBUG_DEFAULTS    (17<<5) /* sudoers defaults settings */
+#define SUDO_DEBUG_AUTH                (18<<5) /* authentication functions */
+#define SUDO_DEBUG_ENV         (19<<5) /* environment handling */
+#define SUDO_DEBUG_LOGGING     (20<<5) /* logging functions */
+#define SUDO_DEBUG_NSS         (21<<5) /* network service switch */
+#define SUDO_DEBUG_RBTREE      (22<<5) /* red-black tree functions */
+#define SUDO_DEBUG_PERMS       (23<<5) /* uid/gid swapping functions */
+#define SUDO_DEBUG_PLUGIN      (24<<5) /* main plugin functions */
+#define SUDO_DEBUG_HOOKS       (25<<5) /* hook functions */
 #define SUDO_DEBUG_ALL         0xfff0  /* all subsystems */
 
+/* Flag to include string version of errno in debug info. */
+#define SUDO_DEBUG_ERRNO       (1<<4)
+
 /* Extract priority and convert to an index. */
 #define SUDO_DEBUG_PRI(n) (((n) & 0xf) - 1)
 
 /* Extract subsystem and convert to an index. */
-#define SUDO_DEBUG_SUBSYS(n) (((n) >> 4) - 1)
+#define SUDO_DEBUG_SUBSYS(n) (((n) >> 5) - 1)
 
 /*
  * Wrapper for sudo_debug_enter() that declares __func__ as needed
@@ -191,6 +195,6 @@ void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsy
 int sudo_debug_fd_set(int fd);
 int sudo_debug_init(const char *debugfile, const char *settings);
 void sudo_debug_printf2(int level, const char *format, ...) __printflike(2, 3);
-void sudo_debug_write(const char *str, int len);
+void sudo_debug_write(const char *str, int len, int errno_val);
 
 #endif /* _SUDO_DEBUG_H */
index a2dab5a7c385b142a81ee69fe8f6af65583c4241..737335eb8bda24a4004cf6e6647446738bca37ad 100644 (file)
@@ -98,7 +98,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
                break;
            case SUDO_CONV_DEBUG_MSG:
                if (msg->msg)
-                   sudo_debug_write(msg->msg, strlen(msg->msg));
+                   sudo_debug_write(msg->msg, strlen(msg->msg), 0);
                break;
            default:
                goto err;