Convert remaining uses of sudo_mkdir_parents() to sudo_open_parent_dir().

This commit is contained in:
Todd C. Miller
2022-09-21 19:08:15 -06:00
parent 376d18b5da
commit 9d654482b2
6 changed files with 39 additions and 25 deletions

View File

@@ -143,7 +143,7 @@ void iolog_set_maxseq(unsigned int maxval);
void iolog_set_mode(mode_t mode);
void iolog_set_owner(uid_t uid, uid_t gid);
bool iolog_swapids(bool restore);
bool iolog_mkdirs(char *path);
bool iolog_mkdirs(const char *path);
/* iolog_filter.c */
void *iolog_pwfilt_alloc(void);

View File

@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws>
* Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -46,7 +46,7 @@
* Create directory and any parent directories as needed.
*/
bool
iolog_mkdirs(char *path)
iolog_mkdirs(const char *path)
{
const mode_t iolog_filemode = iolog_get_file_mode();
const mode_t iolog_dirmode = iolog_get_dir_mode();
@@ -96,29 +96,33 @@ iolog_mkdirs(char *path)
/* umask must not be more restrictive than the file modes. */
omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
if (!ok && errno == EACCES) {
ok = false;
if (dfd != -1)
close(dfd);
dfd = sudo_open_parent_dir(path, iolog_uid, iolog_gid, iolog_dirmode, true);
if (dfd == -1 && errno == EACCES) {
/* Try again as the I/O log owner (for NFS). */
uid_changed = iolog_swapids(false);
if (uid_changed)
ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
dfd = sudo_open_parent_dir(path, -1, -1, iolog_dirmode, false);
}
if (ok) {
if (dfd != -1) {
/* Create final path component. */
const char *base = sudo_basename(path);
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"mkdir %s, mode 0%o", path, (unsigned int) iolog_dirmode);
ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
ok = mkdirat(dfd, base, iolog_dirmode) == 0 || errno == EEXIST;
if (!ok) {
if (errno == EACCES && !uid_changed) {
/* Try again as the I/O log owner (for NFS). */
uid_changed = iolog_swapids(false);
if (uid_changed)
ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
ok = mkdirat(dfd, base, iolog_dirmode) == 0 || errno == EEXIST;
}
if (!ok)
sudo_warn(U_("unable to mkdir %s"), path);
} else {
if (chown(path, iolog_uid, iolog_gid) != 0) {
if (fchownat(dfd, base, iolog_uid, iolog_gid, AT_SYMLINK_NOFOLLOW) != 0) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"%s: unable to chown %d:%d %s", __func__,
(int)iolog_uid, (int)iolog_gid, path);

View File

@@ -52,28 +52,29 @@ iolog_mkdtemp(char *path)
const mode_t iolog_dirmode = iolog_get_dir_mode();
const uid_t iolog_uid = iolog_get_uid();
const gid_t iolog_gid = iolog_get_gid();
bool ok, uid_changed = false;
bool ok = false, uid_changed = false;
mode_t omask;
int dfd;
debug_decl(iolog_mkdtemp, SUDO_DEBUG_UTIL);
/* umask must not be more restrictive than the file modes. */
omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
if (!ok && errno == EACCES) {
dfd = sudo_open_parent_dir(path, iolog_uid, iolog_gid, iolog_dirmode, true);
if (dfd == -1 && errno == EACCES) {
/* Try again as the I/O log owner (for NFS). */
uid_changed = iolog_swapids(false);
if (uid_changed)
ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
dfd = sudo_open_parent_dir(path, -1, -1, iolog_dirmode, false);
}
if (ok) {
if (dfd != -1) {
/* Create final path component. */
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"mkdtemp %s", path);
/* We cannot retry mkdtemp() so always open as iolog user */
if (!uid_changed)
uid_changed = iolog_swapids(false);
if (mkdtemp(path) == NULL) {
if (mkdtempat(dfd, path) == NULL) {
sudo_warn(U_("unable to mkdir %s"), path);
ok = false;
} else {
@@ -82,6 +83,8 @@ iolog_mkdtemp(char *path)
path, (unsigned int)iolog_dirmode);
}
}
close(dfd);
ok = true;
}
umask(omask);

View File

@@ -182,6 +182,7 @@ bad:
/*
* Create any parent directories needed by path (but not path itself).
* Not currently used.
*/
bool
sudo_mkdir_parents_v1(const char *path, uid_t uid, gid_t gid, mode_t mode,

View File

@@ -1759,8 +1759,7 @@ static void
write_pidfile(void)
{
FILE *fp;
int fd;
bool success;
int dfd, fd;
mode_t oldmask;
const char *pid_file = logsrvd_conf_pid_file();
debug_decl(write_pidfile, SUDO_DEBUG_UTIL);
@@ -1771,10 +1770,11 @@ write_pidfile(void)
/* Default logsrvd umask is more restrictive (077). */
oldmask = umask(S_IWGRP|S_IWOTH);
success = sudo_mkdir_parents(pid_file, ROOT_UID, ROOT_GID,
dfd = sudo_open_parent_dir(pid_file, ROOT_UID, ROOT_GID,
S_IRWXU|S_IXGRP|S_IXOTH, false);
if (success) {
fd = open(pid_file, O_WRONLY|O_CREAT|O_NOFOLLOW, 0644);
if (dfd != -1) {
const char *base = sudo_basename(pid_file);
fd = openat(dfd, base, O_WRONLY|O_CREAT|O_NOFOLLOW, 0644);
if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
sudo_warn("%s", pid_file);
if (fd != -1)
@@ -1786,6 +1786,7 @@ write_pidfile(void)
sudo_warn("%s", pid_file);
fclose(fp);
}
close(dfd);
}
umask(oldmask);

View File

@@ -89,8 +89,9 @@ journal_fdopen(int fd, const char *journal_path,
static int
journal_mkstemp(const char *parent_dir, char *pathbuf, int pathlen)
{
int len, fd = -1;
int len, dfd = -1, fd = -1;
mode_t dirmode, oldmask;
char *template;
debug_decl(journal_mkstemp, SUDO_DEBUG_UTIL);
/* umask must not be more restrictive than the file modes. */
@@ -109,19 +110,23 @@ journal_mkstemp(const char *parent_dir, char *pathbuf, int pathlen)
RELAY_TEMPLATE);
goto done;
}
if (!sudo_mkdir_parents(pathbuf, logsrvd_conf_iolog_uid(),
logsrvd_conf_iolog_gid(), S_IRWXU|S_IXGRP|S_IXOTH, false)) {
dfd = sudo_open_parent_dir(pathbuf, logsrvd_conf_iolog_uid(),
logsrvd_conf_iolog_gid(), S_IRWXU|S_IXGRP|S_IXOTH, false);
if (dfd == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to create parent dir for %s", pathbuf);
goto done;
}
if ((fd = mkstemp(pathbuf)) == -1) {
template = pathbuf + (len - strlen(RELAY_TEMPLATE));
if ((fd = mkostempsat(dfd, template, 0, 0)) == -1) {
sudo_warn(U_("%s: %s"), "mkstemp", pathbuf);
goto done;
}
done:
umask(oldmask);
if (dfd != -1)
close(dfd);
debug_return_int(fd);
}