summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2023-06-16 16:11:31 +0300
committerGitHub <noreply@github.com>2023-06-16 16:11:31 +0300
commit563ff0138d64864e85664d5d12b52d8f500cf446 (patch)
tree1a85c6788df9f07827ac8fed9d0ef40718449572 /daemon
parent221167141eaa04e67c1ad152abe4f4abbe082a80 (diff)
Fix file permissions under directory (#15208)
* Fix health crash * Revert "Fix health crash" This reverts commit 2057e6f4216c5a10b25dcf56276ecb7da88079ca. * Fix file permissions * Fix registry directory permissions * Recursively process directories as needed to fix permissions * Fix recursion properly. * Fix recursion properly (part 2) * Fix recursion properly (part 3) * Exclude www directories * Fix recursion properly (part 4) * Make systemd not touch directory permissions * Info message if running as root * Improve message * Set CAP_CHOWN capability
Diffstat (limited to 'daemon')
-rw-r--r--daemon/daemon.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 421511e27f..4b6679cdeb 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -43,10 +43,39 @@ static void chown_open_file(int fd, uid_t uid, gid_t gid) {
}
}
-void change_dir_ownership(const char *dir, uid_t uid, gid_t gid)
+static void fix_directory_file_permissions(const char *dirname, uid_t uid, gid_t gid, bool recursive)
+{
+ char filename[FILENAME_MAX + 1];
+
+ DIR *dir = opendir(dirname);
+ if (!dir)
+ return;
+
+ struct dirent *de = NULL;
+
+ while ((de = readdir(dir))) {
+ if (de->d_type == DT_DIR && (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")))
+ continue;
+
+ (void) snprintfz(filename, FILENAME_MAX, "%s/%s", dirname, de->d_name);
+ if (de->d_type == DT_REG || recursive) {
+ if (chown(filename, uid, gid) == -1)
+ error("Cannot chown %s '%s' to %u:%u", de->d_type == DT_DIR ? "directory" : "file", filename, (unsigned int)uid, (unsigned int)gid);
+ }
+
+ if (de->d_type == DT_DIR && recursive)
+ fix_directory_file_permissions(filename, uid, gid, recursive);
+ }
+
+ closedir(dir);
+}
+
+void change_dir_ownership(const char *dir, uid_t uid, gid_t gid, bool recursive)
{
if (chown(dir, uid, gid) == -1)
error("Cannot chown directory '%s' to %u:%u", dir, (unsigned int)uid, (unsigned int)gid);
+
+ fix_directory_file_permissions(dir, uid, gid, recursive);
}
void clean_directory(char *dirname)
@@ -66,11 +95,15 @@ void clean_directory(char *dirname)
}
void prepare_required_directories(uid_t uid, gid_t gid) {
- change_dir_ownership(netdata_configured_cache_dir, uid, gid);
- change_dir_ownership(netdata_configured_varlib_dir, uid, gid);
- change_dir_ownership(netdata_configured_lock_dir, uid, gid);
- change_dir_ownership(netdata_configured_log_dir, uid, gid);
- change_dir_ownership(claimingdirectory, uid, gid);
+ change_dir_ownership(netdata_configured_cache_dir, uid, gid, true);
+ change_dir_ownership(netdata_configured_varlib_dir, uid, gid, false);
+ change_dir_ownership(netdata_configured_lock_dir, uid, gid, false);
+ change_dir_ownership(netdata_configured_log_dir, uid, gid, false);
+ change_dir_ownership(claimingdirectory, uid, gid, false);
+
+ char filename[FILENAME_MAX + 1];
+ snprintfz(filename, FILENAME_MAX, "%s/registry", netdata_configured_varlib_dir);
+ change_dir_ownership(filename, uid, gid, false);
clean_directory(netdata_configured_lock_dir);
}
@@ -87,6 +120,9 @@ int become_user(const char *username, int pid_fd) {
uid_t uid = pw->pw_uid;
gid_t gid = pw->pw_gid;
+ if (am_i_root)
+ info("I am root, so checking permissions");
+
prepare_required_directories(uid, gid);
if(pidfile[0]) {