summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/fs-util.c16
-rw-r--r--src/basic/fs-util.h1
2 files changed, 17 insertions, 0 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 81d51bb66..1f2765737 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -239,6 +239,22 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
return 0;
}
+int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
+ /* Under the assumption that we are running privileged we
+ * first change the access mode and only then hand out
+ * ownership to avoid a window where access is too open. */
+
+ if (mode != MODE_INVALID)
+ if (fchmod(fd, mode) < 0)
+ return -errno;
+
+ if (uid != UID_INVALID || gid != GID_INVALID)
+ if (fchown(fd, uid, gid) < 0)
+ return -errno;
+
+ return 0;
+}
+
int fchmod_umask(int fd, mode_t m) {
mode_t u;
int r;
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 4b490078d..4e65fd238 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -37,6 +37,7 @@ int readlink_and_make_absolute(const char *p, char **r);
#endif // 0
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid);
int fchmod_umask(int fd, mode_t mode);
int fchmod_opath(int fd, mode_t m);