return -1;
}
- if(pidfile[0] && getuid() != pw->pw_uid) {
+ uid_t uid = pw->pw_uid;
+ gid_t gid = pw->pw_gid;
+
+ if(pidfile[0] && getuid() != uid) {
// we are dropping privileges
- if(chown(pidfile, pw->pw_uid, pw->pw_gid) != 0)
+ if(chown(pidfile, uid, gid) != 0)
error("Cannot chown pidfile '%s' to user '%s'", pidfile, username);
else if(pidfd != -1) {
pidfd = -1;
}
- if(setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
- error("Cannot switch to user's %s group (gid: %d).", username, pw->pw_gid);
+ if(setresgid(gid, gid, gid) != 0) {
+ error("Cannot switch to user's %s group (gid: %d).", username, gid);
return -1;
}
- if(setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
- error("Cannot switch to user %s (uid: %d).", username, pw->pw_uid);
+ if(setresuid(uid, uid, uid) != 0) {
+ error("Cannot switch to user %s (uid: %d).", username, uid);
return -1;
}
- if(setgid(pw->pw_gid) != 0) {
- error("Cannot switch to user's %s group (gid: %d).", username, pw->pw_gid);
+ if(setgid(gid) != 0) {
+ error("Cannot switch to user's %s group (gid: %d).", username, gid);
return -1;
}
- if(setegid(pw->pw_gid) != 0) {
- error("Cannot effectively switch to user's %s group (gid: %d).", username, pw->pw_gid);
+ if(setegid(gid) != 0) {
+ error("Cannot effectively switch to user's %s group (gid: %d).", username, gid);
return -1;
}
- if(setuid(pw->pw_uid) != 0) {
- error("Cannot switch to user %s (uid: %d).", username, pw->pw_uid);
+ if(setuid(uid) != 0) {
+ error("Cannot switch to user %s (uid: %d).", username, uid);
return -1;
}
- if(seteuid(pw->pw_uid) != 0) {
- error("Cannot effectively switch to user %s (uid: %d).", username, pw->pw_uid);
+ if(seteuid(uid) != 0) {
+ error("Cannot effectively switch to user %s (uid: %d).", username, uid);
return -1;
}
// --------------------------------------------------------------------
+ // get the user we should run
+ // IMPORTANT: this is required before web_files_uid()
user = config_get("global", "run as user" , (getuid() == 0)?NETDATA_USER:"");
- web_files_uid();
+
+ // IMPORTANT: these have to run once, while single threaded
+ web_files_uid(); // IMPORTANT: web_files_uid() before web_files_gid()
+ web_files_gid();
// --------------------------------------------------------------------
#include "rrd2json.h"
#include "web_client.h"
+#include "../config.h"
#define INITIAL_WEB_DATA_LENGTH 16384
#define WEB_REQUEST_LENGTH 16384
static uid_t owner_uid = 0;
if(unlikely(!web_owner)) {
- web_owner = config_get("global", "web files owner", NETDATA_USER);
+ web_owner = config_get("global", "web files owner", config_get("global", "run as user", ""));
if(!web_owner || !*web_owner)
owner_uid = geteuid();
else {
+ // getpwnam() is not thread safe,
+ // but we have called this function once
+ // while single threaded
struct passwd *pw = getpwnam(web_owner);
if(!pw) {
error("User %s is not present. Ignoring option.", web_owner);
static gid_t owner_gid = 0;
if(unlikely(!web_group)) {
- web_group = config_get("global", "web files group", config_get("global", "web files owner", NETDATA_USER));
+ web_group = config_get("global", "web files group", config_get("global", "web files owner", ""));
if(!web_group || !*web_group)
owner_gid = getegid();
else {
+ // getgrnam() is not thread safe,
+ // but we have called this function once
+ // while single threaded
struct group *gr = getgrnam(web_group);
if(!gr) {
error("Group %s is not present. Ignoring option.", web_group);