* If is_temp is set, use mkdtemp() for the final directory.
*/
static bool
-io_mkdirs(char *path, mode_t mode, bool is_temp)
+io_mkdirs(char *path, mode_t mode, gid_t *gidp, bool is_temp)
{
struct stat sb;
gid_t parent_gid = 0;
path, (unsigned int) sb.st_mode);
ok = false;
}
+ if (gidp != NULL)
+ *gidp = sb.st_gid;
debug_return_bool(ok);
}
}
}
}
+ if (gidp != NULL)
+ *gidp = parent_gid;
debug_return_bool(ok);
}
char buf[32], *ep;
int i, len, fd = -1;
unsigned long id = 0;
+ gid_t gid;
ssize_t nread;
bool ret = false;
char pathbuf[PATH_MAX];
/*
* Create I/O log directory if it doesn't already exist.
*/
- if (!io_mkdirs(iolog_dir, S_IRWXU, false))
+ if (!io_mkdirs(iolog_dir, S_IRWXU, &gid, false))
goto done;
/*
goto done;
}
sudo_lock_file(fd, SUDO_LOCK);
+ ignore_result(fchown(fd, (uid_t)-1, gid));
/*
* If there is no seq file in iolog_dir and a fallback dir was
if (len > 0 && (size_t)len < sizeof(fallback)) {
int fd2 = open(fallback, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if (fd2 != -1) {
+ ignore_result(fchown(fd2, (uid_t)-1, gid));
nread = read(fd2, buf, sizeof(buf) - 1);
if (nread > 0) {
if (buf[nread - 1] == '\n')
* Returns SIZE_MAX on error.
*/
static size_t
-mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
+mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize, gid_t *gidp)
{
size_t len;
bool is_temp = false;
*/
if (len >= 6 && strcmp(&pathbuf[len - 6], "XXXXXX") == 0)
is_temp = true;
- if (!io_mkdirs(pathbuf, S_IRWXU, is_temp))
+ if (!io_mkdirs(pathbuf, S_IRWXU, gidp, is_temp))
len = (size_t)-1;
debug_return_size_t(len);
* Stores the open file handle which has the close-on-exec flag set.
*/
static bool
-open_io_fd(char *pathbuf, size_t len, struct io_log_file *iol, bool docompress)
+open_io_fd(char *pathbuf, size_t len, gid_t gid, struct io_log_file *iol,
+ bool docompress)
{
debug_decl(open_io_fd, SUDOERS_DEBUG_UTIL)
if (iol->enabled) {
int fd = open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
if (fd != -1) {
+ ignore_result(fchown(fd, (uid_t)-1, gid));
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
#ifdef HAVE_ZLIB_H
if (docompress)
* Write the "/log" file that contains the user and command info.
*/
static bool
-write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
- char * const argv[], struct timeval *now)
+write_info_log(char *pathbuf, size_t len, gid_t gid,
+ struct iolog_details *details, char * const argv[], struct timeval *now)
{
char * const *av;
FILE *fp;
log_warning(SLOG_SEND_MAIL, N_("unable to create %s"), pathbuf);
debug_return_bool(false);
}
+ ignore_result(fchown(fd, (uid_t)-1, 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,
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;
* 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));
+ len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf),
+ &gid);
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, &iolog_details, argv, &last_time);
+ write_info_log(pathbuf, len, gid, &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, &io_log_files[i], iolog_compress))
+ if (!open_io_fd(pathbuf, len, gid, &io_log_files[i], iolog_compress))
goto done;
}