Add SUDO_DEBUG_ERRNO flag to debug functions so we can log errno.
Use this flag when wrapping error() and warning() so the debug output includes the error string.
This commit is contained in:
@@ -252,12 +252,13 @@ void sudo_debug_exit_ptr(const char *func, const char *file, int line,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sudo_debug_write(const char *str, int len)
|
sudo_debug_write(const char *str, int len, int errno_val)
|
||||||
{
|
{
|
||||||
char *timestr;
|
char *timestr;
|
||||||
time_t now;
|
time_t now;
|
||||||
struct iovec iov[5];
|
struct iovec iov[7];
|
||||||
int iovcnt = 4;
|
int iovcnt = 4;
|
||||||
|
bool need_newline = false;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
@@ -266,14 +267,22 @@ sudo_debug_write(const char *str, int len)
|
|||||||
case SUDO_DEBUG_MODE_CONV:
|
case SUDO_DEBUG_MODE_CONV:
|
||||||
/* Call conversation function */
|
/* Call conversation function */
|
||||||
if (sudo_conv != NULL) {
|
if (sudo_conv != NULL) {
|
||||||
struct sudo_conv_message msg;
|
struct sudo_conv_message msg[3];
|
||||||
struct sudo_conv_reply repl;
|
struct sudo_conv_reply repl[3];
|
||||||
|
int msgcnt = 1;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(msg, 0, sizeof(msg));
|
||||||
memset(&repl, 0, sizeof(repl));
|
memset(repl, 0, sizeof(repl));
|
||||||
msg.msg_type = SUDO_CONV_DEBUG_MSG;
|
msg[0].msg_type = SUDO_CONV_DEBUG_MSG;
|
||||||
msg.msg = str;
|
msg[0].msg = str;
|
||||||
sudo_conv(1, &msg, &repl);
|
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;
|
break;
|
||||||
case SUDO_DEBUG_MODE_FILE:
|
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. */
|
/* Add string along with newline if it doesn't have one. */
|
||||||
iov[3].iov_base = (char *)str;
|
iov[3].iov_base = (char *)str;
|
||||||
iov[3].iov_len = len;
|
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 */
|
/* force newline */
|
||||||
iov[4].iov_base = "\n";
|
iov[iovcnt].iov_base = "\n";
|
||||||
iov[4].iov_len = 1;
|
iov[iovcnt].iov_len = 1;
|
||||||
iovcnt++;
|
iovcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +339,7 @@ sudo_debug_write(const char *str, int len)
|
|||||||
void
|
void
|
||||||
sudo_debug_printf2(int level, const char *fmt, ...)
|
sudo_debug_printf2(int level, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
int buflen, pri, subsys;
|
int buflen, pri, subsys, saved_errno = errno;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
@@ -322,16 +351,20 @@ sudo_debug_printf2(int level, const char *fmt, ...)
|
|||||||
subsys = SUDO_DEBUG_SUBSYS(level);
|
subsys = SUDO_DEBUG_SUBSYS(level);
|
||||||
|
|
||||||
/* Make sure we want debug info at this level. */
|
/* Make sure we want debug info at this level. */
|
||||||
if (subsys >= NUM_SUBSYSTEMS || sudo_debug_settings[subsys] < pri)
|
if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) {
|
||||||
return;
|
va_start(ap, fmt);
|
||||||
|
buflen = vasprintf(&buf, fmt, ap);
|
||||||
va_start(ap, fmt);
|
va_end(ap);
|
||||||
buflen = vasprintf(&buf, fmt, ap);
|
if (buflen != -1) {
|
||||||
va_end(ap);
|
if (ISSET(level, SUDO_DEBUG_ERRNO))
|
||||||
if (buflen != -1) {
|
sudo_debug_write(buf, buflen, saved_errno);
|
||||||
sudo_debug_write(buf, buflen);
|
else
|
||||||
free(buf);
|
sudo_debug_write(buf, buflen, 0);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errno = saved_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -411,7 +444,7 @@ sudo_debug_execve2(int level, const char *path, char *const argv[], char *const
|
|||||||
|
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
sudo_debug_write(buf, buflen);
|
sudo_debug_write(buf, buflen, 0);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,7 +38,7 @@
|
|||||||
#else /* SUDO_ERROR_WRAP */
|
#else /* SUDO_ERROR_WRAP */
|
||||||
# if defined(__GNUC__) && __GNUC__ == 2
|
# if defined(__GNUC__) && __GNUC__ == 2
|
||||||
# define error(rval, fmt...) do { \
|
# 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)); \
|
error2((rval), (fmt)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define errorx(rval, fmt...) do { \
|
# define errorx(rval, fmt...) do { \
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
errorx2((rval), (fmt)); \
|
errorx2((rval), (fmt)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define warning(fmt...) do { \
|
# 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)); \
|
warning2((fmt)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define warningx(fmt...) do { \
|
# define warningx(fmt...) do { \
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
# else
|
# else
|
||||||
# define error(rval, ...) do { \
|
# 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__); \
|
error2((rval), __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define errorx(rval, ...) do { \
|
# define errorx(rval, ...) do { \
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
errorx2((rval), __VA_ARGS__); \
|
errorx2((rval), __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define warning(...) do { \
|
# 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__); \
|
warning2(__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define warningx(...) do { \
|
# define warningx(...) do { \
|
||||||
|
@@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The priority and subsystem are encoded in a single 32-bit value.
|
* 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.
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -44,38 +45,41 @@
|
|||||||
* This includes subsystems in the sudoers plugin.
|
* This includes subsystems in the sudoers plugin.
|
||||||
* Note: order must match sudo_debug_subsystems[]
|
* Note: order must match sudo_debug_subsystems[]
|
||||||
*/
|
*/
|
||||||
#define SUDO_DEBUG_MAIN (1<<4) /* sudo main() */
|
#define SUDO_DEBUG_MAIN ( 1<<5) /* sudo main() */
|
||||||
#define SUDO_DEBUG_ARGS (2<<4) /* command line argument processing */
|
#define SUDO_DEBUG_ARGS ( 2<<5) /* command line argument processing */
|
||||||
#define SUDO_DEBUG_EXEC (3<<4) /* command execution */
|
#define SUDO_DEBUG_EXEC ( 3<<5) /* command execution */
|
||||||
#define SUDO_DEBUG_PTY (4<<4) /* pseudo-tty */
|
#define SUDO_DEBUG_PTY ( 4<<5) /* pseudo-tty */
|
||||||
#define SUDO_DEBUG_UTMP (5<<4) /* utmp file ops */
|
#define SUDO_DEBUG_UTMP ( 5<<5) /* utmp file ops */
|
||||||
#define SUDO_DEBUG_CONV (6<<4) /* user conversation */
|
#define SUDO_DEBUG_CONV ( 6<<5) /* user conversation */
|
||||||
#define SUDO_DEBUG_PCOMM (7<<4) /* plugin communications */
|
#define SUDO_DEBUG_PCOMM ( 7<<5) /* plugin communications */
|
||||||
#define SUDO_DEBUG_UTIL (8<<4) /* utility functions */
|
#define SUDO_DEBUG_UTIL ( 8<<5) /* utility functions */
|
||||||
#define SUDO_DEBUG_NETIF (9<<4) /* network interface functions */
|
#define SUDO_DEBUG_NETIF ( 9<<5) /* network interface functions */
|
||||||
#define SUDO_DEBUG_AUDIT (10<<4) /* audit */
|
#define SUDO_DEBUG_AUDIT (10<<5) /* audit */
|
||||||
#define SUDO_DEBUG_EDIT (11<<4) /* sudoedit */
|
#define SUDO_DEBUG_EDIT (11<<5) /* sudoedit */
|
||||||
#define SUDO_DEBUG_SELINUX (12<<4) /* selinux */
|
#define SUDO_DEBUG_SELINUX (12<<5) /* selinux */
|
||||||
#define SUDO_DEBUG_LDAP (13<<4) /* sudoers LDAP */
|
#define SUDO_DEBUG_LDAP (13<<5) /* sudoers LDAP */
|
||||||
#define SUDO_DEBUG_MATCH (14<<4) /* sudoers matching */
|
#define SUDO_DEBUG_MATCH (14<<5) /* sudoers matching */
|
||||||
#define SUDO_DEBUG_PARSER (15<<4) /* sudoers parser */
|
#define SUDO_DEBUG_PARSER (15<<5) /* sudoers parser */
|
||||||
#define SUDO_DEBUG_ALIAS (16<<4) /* sudoers alias functions */
|
#define SUDO_DEBUG_ALIAS (16<<5) /* sudoers alias functions */
|
||||||
#define SUDO_DEBUG_DEFAULTS (17<<4) /* sudoers defaults settings */
|
#define SUDO_DEBUG_DEFAULTS (17<<5) /* sudoers defaults settings */
|
||||||
#define SUDO_DEBUG_AUTH (18<<4) /* authentication functions */
|
#define SUDO_DEBUG_AUTH (18<<5) /* authentication functions */
|
||||||
#define SUDO_DEBUG_ENV (19<<4) /* environment handling */
|
#define SUDO_DEBUG_ENV (19<<5) /* environment handling */
|
||||||
#define SUDO_DEBUG_LOGGING (20<<4) /* logging functions */
|
#define SUDO_DEBUG_LOGGING (20<<5) /* logging functions */
|
||||||
#define SUDO_DEBUG_NSS (21<<4) /* network service switch */
|
#define SUDO_DEBUG_NSS (21<<5) /* network service switch */
|
||||||
#define SUDO_DEBUG_RBTREE (22<<4) /* red-black tree functions */
|
#define SUDO_DEBUG_RBTREE (22<<5) /* red-black tree functions */
|
||||||
#define SUDO_DEBUG_PERMS (23<<4) /* uid/gid swapping functions */
|
#define SUDO_DEBUG_PERMS (23<<5) /* uid/gid swapping functions */
|
||||||
#define SUDO_DEBUG_PLUGIN (24<<4) /* main plugin functions */
|
#define SUDO_DEBUG_PLUGIN (24<<5) /* main plugin functions */
|
||||||
#define SUDO_DEBUG_HOOKS (25<<4) /* hook functions */
|
#define SUDO_DEBUG_HOOKS (25<<5) /* hook functions */
|
||||||
#define SUDO_DEBUG_ALL 0xfff0 /* all subsystems */
|
#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. */
|
/* Extract priority and convert to an index. */
|
||||||
#define SUDO_DEBUG_PRI(n) (((n) & 0xf) - 1)
|
#define SUDO_DEBUG_PRI(n) (((n) & 0xf) - 1)
|
||||||
|
|
||||||
/* Extract subsystem and convert to an index. */
|
/* 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
|
* 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_fd_set(int fd);
|
||||||
int sudo_debug_init(const char *debugfile, const char *settings);
|
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_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 */
|
#endif /* _SUDO_DEBUG_H */
|
||||||
|
@@ -98,7 +98,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
|||||||
break;
|
break;
|
||||||
case SUDO_CONV_DEBUG_MSG:
|
case SUDO_CONV_DEBUG_MSG:
|
||||||
if (msg->msg)
|
if (msg->msg)
|
||||||
sudo_debug_write(msg->msg, strlen(msg->msg));
|
sudo_debug_write(msg->msg, strlen(msg->msg), 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto err;
|
goto err;
|
||||||
|
Reference in New Issue
Block a user