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
Stelios Fragkakis committed
Jun 16, 2023 at 16:11 UTC
563ff0138d64864e85664d5d12b52d8f500cf446
3 files changed
+44
-14
daemon/daemon.c
+42
-6
@@ -43,10 +43,39 @@ static void chown_open_file(int fd, uid_t uid, gid_t gid) {
43
}
44
}
45
46
-void change_dir_ownership(const char *dir, uid_t uid, gid_t gid)
46
+static void fix_directory_file_permissions(const char *dirname, uid_t uid, gid_t gid, bool recursive)
47
+{
48
+ char filename[FILENAME_MAX + 1];
49
+
50
+ DIR *dir = opendir(dirname);
51
+ if (!dir)
52
+ return;
53
+
54
+ struct dirent *de = NULL;
55
+
56
+ while ((de = readdir(dir))) {
57
+ if (de->d_type == DT_DIR && (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")))
58
+ continue;
59
+
60
+ (void) snprintfz(filename, FILENAME_MAX, "%s/%s", dirname, de->d_name);
61
+ if (de->d_type == DT_REG || recursive) {
62
+ if (chown(filename, uid, gid) == -1)
63
+ error("Cannot chown %s '%s' to %u:%u", de->d_type == DT_DIR ? "directory" : "file", filename, (unsigned int)uid, (unsigned int)gid);
64
+ }
65
+
66
+ if (de->d_type == DT_DIR && recursive)
67
+ fix_directory_file_permissions(filename, uid, gid, recursive);
68
+ }
69
+
70
+ closedir(dir);
71
+}
72
+
73
+void change_dir_ownership(const char *dir, uid_t uid, gid_t gid, bool recursive)
74
{
75
if (chown(dir, uid, gid) == -1)
76
error("Cannot chown directory '%s' to %u:%u", dir, (unsigned int)uid, (unsigned int)gid);
77
+
78
+ fix_directory_file_permissions(dir, uid, gid, recursive);
79
}
80
81
void clean_directory(char *dirname)
@@ -66,11 +95,15 @@ void clean_directory(char *dirname)
95
}
96
97
void prepare_required_directories(uid_t uid, gid_t gid) {
69
- change_dir_ownership(netdata_configured_cache_dir, uid, gid);
70
- change_dir_ownership(netdata_configured_varlib_dir, uid, gid);
71
- change_dir_ownership(netdata_configured_lock_dir, uid, gid);
72
- change_dir_ownership(netdata_configured_log_dir, uid, gid);
73
- change_dir_ownership(claimingdirectory, uid, gid);
98
+ change_dir_ownership(netdata_configured_cache_dir, uid, gid, true);
99
+ change_dir_ownership(netdata_configured_varlib_dir, uid, gid, false);
100
+ change_dir_ownership(netdata_configured_lock_dir, uid, gid, false);
101
+ change_dir_ownership(netdata_configured_log_dir, uid, gid, false);
102
+ change_dir_ownership(claimingdirectory, uid, gid, false);
103
+
104
+ char filename[FILENAME_MAX + 1];
105
+ snprintfz(filename, FILENAME_MAX, "%s/registry", netdata_configured_varlib_dir);
106
+ change_dir_ownership(filename, uid, gid, false);
107
108
clean_directory(netdata_configured_lock_dir);
109
}
@@ -87,6 +120,9 @@ int become_user(const char *username, int pid_fd) {
120
uid_t uid = pw->pw_uid;
121
gid_t gid = pw->pw_gid;
122
123
+ if (am_i_root)
124
+ info("I am root, so checking permissions");
125
+
126
prepare_required_directories(uid, gid);
127
128
if(pidfile[0]) {
system/systemd/netdata.service.in
+2
@@ -59,6 +59,8 @@ CapabilityBoundingSet=CAP_SYS_CHROOT
59
CapabilityBoundingSet=CAP_NET_ADMIN
60
# is required for plugins that use sudo
61
CapabilityBoundingSet=CAP_SETGID CAP_SETUID
62
+# is required to change file ownership
63
+CapabilityBoundingSet=CAP_CHOWN
64
65
# Sandboxing
66
ProtectSystem=full
system/systemd/netdata.service.v235.in
-8
@@ -8,14 +8,6 @@ After=network.target httpd.service squid.service nfs-server.service mysqld.servi
8
[Service]
9
Type=simple
10
User=root
11
-RuntimeDirectory=netdata
12
-CacheDirectory=netdata
13
-StateDirectory=netdata
14
-LogsDirectory=netdata
15
-RuntimeDirectoryMode=0775
16
-StateDirectoryMode=0755
17
-CacheDirectoryMode=0755
18
-LogsDirectoryMode=2750
11
EnvironmentFile=-/etc/default/netdata
12
ExecStart=@sbindir_POST@/netdata -D $EXTRA_OPTS
13