]> granicus.if.org Git - sudo/commitdiff
Make the I/O log file/dir permissions and owner configurable.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 29 Oct 2016 18:45:55 +0000 (12:45 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 29 Oct 2016 18:45:55 +0000 (12:45 -0600)
doc/sudoers.cat
doc/sudoers.man.in
doc/sudoers.mdoc.in
plugins/sudoers/def_data.c
plugins/sudoers/def_data.h
plugins/sudoers/def_data.in
plugins/sudoers/defaults.c
plugins/sudoers/iolog.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h

index 88652b7d646bafc70b43dc8674187c92295105a0..e54f463da44a064830c5ee6ddea2973f6bdf3c2a 100644 (file)
@@ -1543,6 +1543,30 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
                        will be truncated and overwritten unless _\bi_\bo_\bl_\bo_\bg_\b__\bf_\bi_\bl_\be
                        ends in six or more Xs.
 
+     iolog_group       The group name to look up when setting the group ID on
+                       new I/O log files and directories.  By default, I/O log
+                       files and directories inherit the group ID of the
+                       parent directory.
+
+                       This setting is only supported by version 1.8.19 or
+                       higher.
+
+     iolog_mode        The file permision mode to use when creating I/O log
+                       files.  When creating I/O log directories, search
+                       (execute) bits are added to to match the read and write
+                       bits specified by _\bi_\bo_\bl_\bo_\bg_\b__\bm_\bo_\bd_\be.  Defaults to 0600.
+
+                       This setting is only supported by version 1.8.19 or
+                       higher.
+
+     iolog_user        The user name to look up when setting the user ID on
+                       new I/O log files and directories.  By default, I/O log
+                       files and directories are owned by the superuser (user
+                       ID 0).
+
+                       This setting is only supported by version 1.8.19 or
+                       higher.
+
      lecture_status_dir
                        The directory in which s\bsu\bud\bdo\bo stores per-user lecture
                        status files.  Once a user has received the lecture, a
@@ -2607,4 +2631,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
      file distributed with s\bsu\bud\bdo\bo or https://www.sudo.ws/license.html for
      complete details.
 
-Sudo 1.8.18                    October 19, 2016                    Sudo 1.8.18
+Sudo 1.8.19                    October 29, 2016                    Sudo 1.8.19
index 10f80823499181e62787ee2f27169716a759a3f7..159d17c00e92fbb2bef3c457cb174d5d35eae3af 100644 (file)
@@ -21,7 +21,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.TH "SUDOERS" "5" "October 19, 2016" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDOERS" "5" "October 29, 2016" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
 .nh
 .if n .ad l
 .SH "NAME"
@@ -3188,6 +3188,31 @@ ends in six or
 more
 \fRX\fRs.
 .TP 18n
+iolog_group
+The group name to look up when setting the group ID on new I/O log
+files and directories.
+By default, I/O log files and directories inherit the group ID of
+the parent directory.
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
+iolog_mode
+The file permision mode to use when creating I/O log files.
+When creating I/O log directories, search (execute) bits are added
+to to match the read and write bits specified by
+\fIiolog_mode\fR.
+Defaults to 0600.
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
+iolog_user
+The user name to look up when setting the user ID on new I/O log
+files and directories.
+By default, I/O log files and directories are owned by the superuser
+(user ID 0).
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
 lecture_status_dir
 The directory in which
 \fBsudo\fR
index 6038a1ecc7e6c3fccda258d63947ea99368c85af..2b4298ee6fd6755fcf66489edcb33b8e2c8ccc82 100644 (file)
@@ -19,7 +19,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd October 19, 2016
+.Dd October 29, 2016
 .Dt SUDOERS @mansectform@
 .Os Sudo @PACKAGE_VERSION@
 .Sh NAME
@@ -2988,6 +2988,28 @@ overwritten unless
 ends in six or
 more
 .Li X Ns s .
+.It iolog_group
+The group name to look up when setting the group ID on new I/O log
+files and directories.
+By default, I/O log files and directories inherit the group ID of
+the parent directory.
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.It iolog_mode
+The file permision mode to use when creating I/O log files.
+When creating I/O log directories, search (execute) bits are added
+to to match the read and write bits specified by
+.Em iolog_mode .
+Defaults to 0600.
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.It iolog_user
+The user name to look up when setting the user ID on new I/O log
+files and directories.
+By default, I/O log files and directories are owned by the superuser
+(user ID 0).
+.Pp
+This setting is only supported by version 1.8.19 or higher.
 .It lecture_status_dir
 The directory in which
 .Nm sudo
index ec749637ae88e493e30848f43cc901acd0c95409..bdcbbdb4c503dc57e14bb8ac0942b57096542af3 100644 (file)
@@ -422,6 +422,18 @@ struct sudo_defs_types sudo_defs_table[] = {
        "syslog_maxlen", T_UINT,
        N_("Log entries larger than this value will be split into multiple syslog messages"),
        NULL,
+    }, {
+       "iolog_user", T_STR|T_BOOL,
+       N_("User that will own the I/O log files: %s"),
+       NULL,
+    }, {
+       "iolog_group", T_STR|T_BOOL,
+       N_("Group that will own the I/O log files: %s"),
+       NULL,
+    }, {
+       "iolog_mode", T_MODE,
+       N_("File mode to use for the I/O log files: 0%o"),
+       NULL,
     }, {
        NULL, 0, NULL
     }
index d16c17ccb2f1a2fd405c0402e014586427c4176b..d83d2c3b6a56fd251901307df0cd4d9d4391b2ab 100644 (file)
 #define def_match_group_by_gid  (sudo_defs_table[I_MATCH_GROUP_BY_GID].sd_un.flag)
 #define I_SYSLOG_MAXLEN         99
 #define def_syslog_maxlen       (sudo_defs_table[I_SYSLOG_MAXLEN].sd_un.uival)
+#define I_IOLOG_USER            100
+#define def_iolog_user          (sudo_defs_table[I_IOLOG_USER].sd_un.str)
+#define I_IOLOG_GROUP           101
+#define def_iolog_group         (sudo_defs_table[I_IOLOG_GROUP].sd_un.str)
+#define I_IOLOG_MODE            102
+#define def_iolog_mode          (sudo_defs_table[I_IOLOG_MODE].sd_un.mode)
 
 enum def_tuple {
        never,
index 1190fefed407aa3ed1892d829cf43bfa540a81c1..2a16166c083f5a40e7ad273e6ce8cb356fee12f7 100644 (file)
@@ -313,3 +313,12 @@ match_group_by_gid
 syslog_maxlen
        T_UINT
        "Log entries larger than this value will be split into multiple syslog messages"
+iolog_user
+       T_STR|T_BOOL
+       "User that will own the I/O log files: %s"
+iolog_group
+       T_STR|T_BOOL
+       "Group that will own the I/O log files: %s"
+iolog_mode
+       T_MODE
+       "File mode to use for the I/O log files: 0%o"
index cb6e16ff39502906e551c19eae129c1f6c18e45a..a4c1f705e66e931498ed3107b965b0d35e530d55 100644 (file)
@@ -22,6 +22,7 @@
 #include <config.h>
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef HAVE_STRING_H
@@ -493,6 +494,7 @@ init_defaults(void)
 #endif
     def_netgroup_tuple = false;
     def_sudoedit_checkdir = true;
+    def_iolog_mode = S_IRUSR|S_IWUSR;
 
     /* Syslog options need special care since they both strings and ints */
 #if (LOGGING & SLOG_SYSLOG)
index 26a7021b94a6476dd79b8082d2f9b6842e001ca9..d652fcfea652aba7bbcf4cbc4d8a713f50d870cc 100644 (file)
@@ -71,89 +71,163 @@ static bool iolog_compress = false;
 static bool warned = false;
 static struct timeval last_time;
 static unsigned int sessid_max = SESSID_MAX;
+static uid_t iolog_uid = ROOT_UID;
+static gid_t iolog_gid = (gid_t)-1;
+static mode_t iolog_dirmode = S_IRWXU;
 
 /* sudoers_io is declared at the end of this file. */
 extern __dso_public struct io_plugin sudoers_io;
 
 /*
  * Create path and any parent directories as needed.
- * If is_temp is set, use mkdtemp() for the final directory.
  */
 static bool
-io_mkdirs(char *path, mode_t mode, gid_t *gidp, bool is_temp)
+io_mkdir_parents(char *path, uid_t uid, gid_t *gidp, mode_t mode)
 {
     struct stat sb;
-    gid_t parent_gid = 0;
+    gid_t parent_gid;
     char *slash = path;
-    bool ok = true;
-    debug_decl(io_mkdirs, SUDOERS_DEBUG_UTIL)
-
-    /* Fast path: not a temporary and already exists. */
-    if (!is_temp && stat(path, &sb) == 0) {
-       if (!S_ISDIR(sb.st_mode)) {
-           log_warningx(SLOG_SEND_MAIL,
-               N_("%s exists but is not a directory (0%o)"),
-               path, (unsigned int) sb.st_mode);
-           ok = false;
-       }
-       if (gidp != NULL)
-           *gidp = sb.st_gid;
-       debug_return_bool(ok);
-    }
+    bool rval = true;
+    debug_decl(io_mkdir_parents, SUDOERS_DEBUG_UTIL)
 
+    /* Create parent directories as needed. */
+    parent_gid = *gidp != (gid_t)-1 ? *gidp : 0;
     while ((slash = strchr(slash + 1, '/')) != NULL) {
        *slash = '\0';
        sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
-           "mkdir %s, mode 0%o", path, (unsigned int) mode);
+           "mkdir %s, mode 0%o, uid %d, gid %d", path, mode,
+           (int)uid, (int)parent_gid);
        if (mkdir(path, mode) == 0) {
-           ignore_result(chown(path, (uid_t)-1, parent_gid));
+           ignore_result(chown(path, uid, parent_gid));
        } else {
            if (errno != EEXIST) {
                log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
-               ok = false;
+               rval = false;
                break;
            }
            /* Already exists, make sure it is a directory. */
            if (stat(path, &sb) != 0) {
                log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
-               ok = false;
+               rval = false;
                break;
            }
            if (!S_ISDIR(sb.st_mode)) {
                log_warningx(SLOG_SEND_MAIL,
                    N_("%s exists but is not a directory (0%o)"),
                    path, (unsigned int) sb.st_mode);
-               ok = false;
+               rval = false;
                break;
            }
            /* Inherit gid of parent dir for ownership. */
-           parent_gid = sb.st_gid;
+           if (*gidp == (gid_t)-1)
+               parent_gid = sb.st_gid;
        }
        *slash = '/';
     }
+
+    /* Return parent gid if none was specified by caller. */
+    if (rval && *gidp == (gid_t)-1)
+       *gidp = parent_gid;
+    debug_return_bool(rval);
+}
+
+/*
+ * Create directory and any parent directories as needed.
+ */
+static bool
+io_mkdirs(char *path, uid_t uid, gid_t *gidp, mode_t mode, bool set_intermediate)
+{
+    struct stat sb;
+    uid_t parent_uid;
+    gid_t parent_gid;
+    mode_t parent_mode;
+    bool ok = true;
+    debug_decl(io_mkdirs, SUDOERS_DEBUG_UTIL)
+
+    if (stat(path, &sb) == 0) {
+       if (S_ISDIR(sb.st_mode)) {
+           parent_gid = sb.st_gid;
+       } else {
+           log_warningx(SLOG_SEND_MAIL,
+               N_("%s exists but is not a directory (0%o)"),
+               path, (unsigned int) sb.st_mode);
+           ok = false;
+       }
+       goto done;
+    }
+
+    /* Parent directory ownership and mode. */
+    if (!set_intermediate) {
+       parent_mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+       parent_uid = ROOT_UID;
+       parent_gid = 0;
+    } else {
+       parent_mode = mode;
+       parent_uid = uid;
+       parent_gid = *gidp;
+    }
+
+    ok = io_mkdir_parents(path, parent_uid, &parent_gid, parent_mode);
     if (ok) {
+       /* Use group ID if specified, else parent gid. */
+       gid_t gid = *gidp != (gid_t)-1 ? *gidp : parent_gid;
+
        /* Create final path component. */
-       if (is_temp) {
-           sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
-               "mkdtemp %s", path);
-           if (mkdtemp(path) == NULL) {
-               log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
-               ok = false;
-           } else {
-               ignore_result(chown(path, (uid_t)-1, parent_gid));
-           }
+       sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+           "mkdir %s, mode 0%o", path, (unsigned int) mode);
+       if (mkdir(path, mode) != 0 && errno != EEXIST) {
+           log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
+           ok = false;
        } else {
-           sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
-               "mkdir %s, mode 0%o", path, (unsigned int) mode);
-           if (mkdir(path, mode) != 0 && errno != EEXIST) {
-               log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
-               ok = false;
-           } else {
-               ignore_result(chown(path, (uid_t)-1, parent_gid));
-           }
+           ignore_result(chown(path, uid, gid));
+       }
+    }
+done:
+    if (ok && *gidp == (gid_t)-1)
+       *gidp = parent_gid;
+    debug_return_bool(ok);
+}
+
+/*
+ * Create temporary directory and any parent directories as needed.
+ */
+static bool
+io_mkdtemp(char *path, uid_t uid, gid_t *gidp, mode_t mode, bool set_intermediate)
+{
+    uid_t parent_uid;
+    gid_t parent_gid;
+    mode_t parent_mode;
+    bool ok = true;
+    debug_decl(io_mkdtemp, SUDOERS_DEBUG_UTIL)
+
+    /* Parent directory ownership and mode. */
+    if (!set_intermediate) {
+       parent_mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+       parent_uid = ROOT_UID;
+       parent_gid = 0;
+    } else {
+       parent_mode = mode;
+       parent_uid = uid;
+       parent_gid = *gidp;
+    }
+
+    ok = io_mkdir_parents(path, parent_uid, &parent_gid, parent_mode);
+    if (ok) {
+       /* Use group ID if specified, else parent gid. */
+       gid_t gid = *gidp != (gid_t)-1 ? *gidp : parent_gid;
+
+       /* Create final path component. */
+       sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+           "mkdtemp %s", path);
+       if (mkdtemp(path) == NULL) {
+           log_warning(SLOG_SEND_MAIL, N_("unable to mkdir %s"), path);
+           ok = false;
+       } else {
+           ignore_result(chown(path, uid, gid));
        }
     }
-    if (gidp != NULL)
+
+    if (ok && *gidp == (gid_t)-1)
        *gidp = parent_gid;
     debug_return_bool(ok);
 }
@@ -195,6 +269,74 @@ cb_maxseq(const union sudo_defs_val *sd_un)
     debug_return_bool(true);
 }
 
+/*
+ * Sudoers callback for iolog_user Defaults setting.
+ */
+bool
+cb_iolog_user(const union sudo_defs_val *sd_un)
+{
+    struct passwd *pw;
+    debug_decl(cb_iolog_user, SUDOERS_DEBUG_UTIL)
+
+    if (sd_un->str != NULL) {
+       pw = sudo_getpwnam(sd_un->str);
+       if (pw != NULL) {
+           iolog_uid = pw->pw_uid;
+       } else {
+           log_warningx(SLOG_SEND_MAIL,
+               N_("unknown user: %s"), sd_un->str);
+       }
+    } else {
+       iolog_uid = ROOT_UID;
+    }
+
+    debug_return_bool(true);
+}
+
+/*
+ * Sudoers callback for iolog_group Defaults setting.
+ */
+bool
+cb_iolog_group(const union sudo_defs_val *sd_un)
+{
+    struct group *gr;
+    debug_decl(cb_iolog_group, SUDOERS_DEBUG_UTIL)
+
+    if (sd_un->str != NULL) {
+       gr = sudo_getgrnam(sd_un->str);
+       if (gr != NULL) {
+           iolog_gid = gr->gr_gid;
+       } else {
+           log_warningx(SLOG_SEND_MAIL,
+               N_("unknown group: %s"), sd_un->str);
+       }
+    } else {
+       iolog_gid = (mode_t)-1;
+    }
+
+    debug_return_bool(true);
+}
+
+/*
+ * Sudoers callback for iolog_mode Defaults setting.
+ */
+bool
+cb_iolog_mode(const union sudo_defs_val *sd_un)
+{
+    debug_decl(cb_iolog_mode, SUDOERS_DEBUG_UTIL)
+
+    /* Base directory mode on iolog_mode, adding in the X bit as needed */
+    iolog_dirmode = def_iolog_mode;
+    if (iolog_dirmode & (S_IRUSR|S_IWUSR))
+       iolog_dirmode |= S_IXUSR;
+    if (iolog_dirmode & (S_IRGRP|S_IWGRP))
+       iolog_dirmode |= S_IXGRP;
+    if (iolog_dirmode & (S_IROTH|S_IWOTH))
+       iolog_dirmode |= S_IXOTH;
+
+    debug_return_bool(true);
+}
+
 /*
  * Read the on-disk sequence number, set sessid to the next
  * number, and update the on-disk copy.
@@ -207,7 +349,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
     char buf[32], *ep;
     int i, len, fd = -1;
     unsigned long id = 0;
-    gid_t gid;
+    gid_t gid = iolog_gid;
     ssize_t nread;
     bool ret = false;
     char pathbuf[PATH_MAX];
@@ -216,8 +358,9 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
 
     /*
      * Create I/O log directory if it doesn't already exist.
+     * Avoid modifying iolog_gid at this point.
      */
-    if (!io_mkdirs(iolog_dir, S_IRWXU, &gid, false))
+    if (!io_mkdirs(iolog_dir, iolog_uid, &gid, iolog_dirmode, false))
        goto done;
 
     /*
@@ -229,13 +372,13 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
        log_warning(SLOG_SEND_MAIL, "%s/seq", pathbuf);
        goto done;
     }
-    fd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+    fd = open(pathbuf, O_RDWR|O_CREAT, def_iolog_mode);
     if (fd == -1) {
        log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), pathbuf);
        goto done;
     }
     sudo_lock_file(fd, SUDO_LOCK);
-    ignore_result(fchown(fd, (uid_t)-1, gid));
+    ignore_result(fchown(fd, iolog_uid, gid));
 
     /*
      * If there is no seq file in iolog_dir and a fallback dir was
@@ -249,9 +392,9 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
        len = snprintf(fallback, sizeof(fallback), "%s/seq",
            iolog_dir_fallback);
        if (len > 0 && (size_t)len < sizeof(fallback)) {
-           int fd2 = open(fallback, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+           int fd2 = open(fallback, O_RDWR|O_CREAT, def_iolog_mode);
            if (fd2 != -1) {
-               ignore_result(fchown(fd2, (uid_t)-1, gid));
+               ignore_result(fchown(fd2, iolog_uid, gid));
                nread = read(fd2, buf, sizeof(buf) - 1);
                if (nread > 0) {
                    if (buf[nread - 1] == '\n')
@@ -328,10 +471,10 @@ done:
  * Returns SIZE_MAX on error.
  */
 static size_t
-mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize, gid_t *gidp)
+mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
 {
     size_t len;
-    bool is_temp = false;
+    bool ok;
     debug_decl(mkdir_iopath, SUDOERS_DEBUG_UTIL)
 
     len = strlcpy(pathbuf, iolog_path, pathsize);
@@ -344,13 +487,14 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize, gid_t *gidp
     /*
      * Create path and intermediate subdirs as needed.
      * If path ends in at least 6 Xs (ala POSIX mktemp), use mkdtemp().
+     * Sets iolog_gid (if it is not already set) as a side effect.
      */
     if (len >= 6 && strcmp(&pathbuf[len - 6], "XXXXXX") == 0)
-       is_temp = true;
-    if (!io_mkdirs(pathbuf, S_IRWXU, gidp, is_temp))
-       len = (size_t)-1;
+       ok = io_mkdtemp(pathbuf, iolog_uid, &iolog_gid, iolog_dirmode, true);
+    else
+       ok = io_mkdirs(pathbuf, iolog_uid, &iolog_gid, iolog_dirmode, true);
 
-    debug_return_size_t(len);
+    debug_return_size_t(ok ? len : (size_t)-1);
 }
 
 /*
@@ -360,17 +504,16 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize, gid_t *gidp
  * Stores the open file handle which has the close-on-exec flag set.
  */
 static bool
-open_io_fd(char *pathbuf, size_t len, gid_t gid, struct io_log_file *iol,
-    bool docompress)
+open_io_fd(char *pathbuf, size_t len, struct io_log_file *iol, bool docompress)
 {
     debug_decl(open_io_fd, SUDOERS_DEBUG_UTIL)
 
     pathbuf[len] = '\0';
     strlcat(pathbuf, iol->suffix, PATH_MAX);
     if (iol->enabled) {
-       int fd = open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
+       int fd = open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, def_iolog_mode);
        if (fd != -1) {
-           ignore_result(fchown(fd, (uid_t)-1, gid));
+           ignore_result(fchown(fd, iolog_uid, iolog_gid));
            (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
 #ifdef HAVE_ZLIB_H
            if (docompress)
@@ -575,8 +718,8 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
  * Write the "/log" file that contains the user and command info.
  */
 static bool
-write_info_log(char *pathbuf, size_t len, gid_t gid,
-    struct iolog_details *details, char * const argv[], struct timeval *now)
+write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
+    char * const argv[], struct timeval *now)
 {
     char * const *av;
     FILE *fp;
@@ -586,12 +729,12 @@ write_info_log(char *pathbuf, size_t len, gid_t gid,
 
     pathbuf[len] = '\0';
     strlcat(pathbuf, "/log", PATH_MAX);
-    fd = open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
+    fd = open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, def_iolog_mode);
     if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
        log_warning(SLOG_SEND_MAIL, N_("unable to create %s"), pathbuf);
        debug_return_bool(false);
     }
-    ignore_result(fchown(fd, (uid_t)-1, gid));
+    ignore_result(fchown(fd, iolog_uid, iolog_gid));
 
     fprintf(fp, "%lld:%s:%s:%s:%s:%d:%d\n%s\n%s", (long long)now->tv_sec,
        details->user ? details->user : "unknown", details->runas_pw->pw_name,
@@ -624,7 +767,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     const char *cp, *plugin_path = NULL;
     size_t len;
     int i, ret = -1;
-    gid_t gid;
     debug_decl(sudoers_io_open, SUDOERS_DEBUG_PLUGIN)
 
     sudo_conv = conversation;
@@ -682,19 +824,18 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
      * Make local copy of I/O log path and create it, along with any
      * intermediate subdirs.  Calls mkdtemp() if iolog_path ends in XXXXXX.
      */
-    len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf),
-       &gid);
+    len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf));
     if (len >= sizeof(pathbuf))
        goto done;
 
     /* Write log file with user and command details. */
     if (gettimeofday(&last_time, NULL) == -1)
        goto done;
-    write_info_log(pathbuf, len, gid, &iolog_details, argv, &last_time);
+    write_info_log(pathbuf, len, &iolog_details, argv, &last_time);
 
     /* Create the timing and I/O log files. */
     for (i = 0; i < IOFD_MAX; i++) {
-       if (!open_io_fd(pathbuf, len, gid, &io_log_files[i], iolog_compress))
+       if (!open_io_fd(pathbuf, len, &io_log_files[i], iolog_compress))
            goto done;
     }
 
index c29c82ae032eff0675ed6205216eab51a8d648ca..3ae421ba30d277cb1d4a63795ae9fcda61541049 100644 (file)
@@ -723,6 +723,15 @@ init_vars(char * const envp[])
     /* Set maxseq callback. */
     sudo_defs_table[I_MAXSEQ].callback = cb_maxseq;
 
+    /* Set iolog_user callback. */
+    sudo_defs_table[I_IOLOG_USER].callback = cb_iolog_user;
+
+    /* Set iolog_group callback. */
+    sudo_defs_table[I_IOLOG_GROUP].callback = cb_iolog_group;
+
+    /* Set iolog_mode callback. */
+    sudo_defs_table[I_IOLOG_MODE].callback = cb_iolog_mode;
+
     /* It is now safe to use log_warningx() and set_perms() */
     if (unknown_user) {
        log_warningx(SLOG_SEND_MAIL, N_("unknown uid: %u"),
index 5ff7346a0ea3b66e79f184c76940f191f1ff270f..9baea0aee4bd8928fb339aed23568a0dd2f0c9cd 100644 (file)
@@ -328,6 +328,9 @@ bool get_boottime(struct timespec *);
 /* iolog.c */
 bool io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]);
 bool cb_maxseq(const union sudo_defs_val *sd_un);
+bool cb_iolog_user(const union sudo_defs_val *sd_un);
+bool cb_iolog_group(const union sudo_defs_val *sd_un);
+bool cb_iolog_mode(const union sudo_defs_val *sd_un);
 
 /* iolog_path.c */
 char *expand_iolog_path(const char *prefix, const char *dir, const char *file,