]> arthur.barton.de Git - netdata.git/commitdiff
can now become another user
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 27 Mar 2014 01:09:46 +0000 (03:09 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 27 Mar 2014 01:09:46 +0000 (03:09 +0200)
netdata.c
netdata.start
web/all.xsl [changed mode: 0755->0644]
web/netdata.js [changed mode: 0755->0644]

index b0c9a3648cf14ef685aa6a6ad9126508e860959a..bcb81c4ec9bd232691016d8cd30050808a0b3cec 100755 (executable)
--- a/netdata.c
+++ b/netdata.c
@@ -6,6 +6,7 @@
 #include <string.h>\r
 #include <time.h>\r
 #include <unistd.h>\r
+#include <pwd.h>\r
 #include <sys/types.h>\r
 #include <sys/time.h>\r
 \r
@@ -933,9 +934,15 @@ int mysendfile(struct web_client *w, char *filename)
                return 400;\r
        }\r
 \r
+       // access the file in web/*\r
+       char webfilename[FILENAME_MAX + 1];\r
+       strcpy(webfilename, "web/");\r
+       strncpy(&webfilename[4], filename, FILENAME_MAX - 4);\r
+       webfilename[FILENAME_MAX] = '\0';\r
+\r
        // check if the file exists\r
        struct stat stat;\r
-       if(lstat(filename, &stat) != 0) {\r
+       if(lstat(webfilename, &stat) != 0) {\r
                debug(D_WEB_CLIENT_ACCESS, "%llu: File '%s' is not found.", w->id, filename);\r
                w->data->bytes = sprintf(w->data->buffer, "File '%s' does not exist, or is not accessible.", filename);\r
                return 404;\r
@@ -949,7 +956,7 @@ int mysendfile(struct web_client *w, char *filename)
        }\r
 \r
        // open the file\r
-       w->ifd = open(filename, O_NONBLOCK, O_RDONLY);\r
+       w->ifd = open(webfilename, O_NONBLOCK, O_RDONLY);\r
        if(w->ifd == -1) {\r
                w->ifd = w->ofd;\r
 \r
@@ -2023,6 +2030,33 @@ void sig_handler(int signo)
        }\r
 }\r
 \r
+int become_user(const char *username)\r
+{\r
+       struct passwd *pw = getpwnam(username);\r
+       if(!pw) {\r
+               fprintf(stderr, "User %s is not present. Error: %s\n", username, strerror(errno));\r
+               return -1;\r
+       }\r
+       if(setgid(pw->pw_gid) != 0) {\r
+               fprintf(stderr, "Cannot switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));\r
+               return -1;\r
+       }\r
+       if(setegid(pw->pw_gid) != 0) {\r
+               fprintf(stderr, "Cannot effectively switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));\r
+               return -1;\r
+       }\r
+       if(setuid(pw->pw_uid) != 0) {\r
+               fprintf(stderr, "Cannot switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));\r
+               return -1;\r
+       }\r
+       if(seteuid(pw->pw_uid) != 0) {\r
+               fprintf(stderr, "Cannot effectively switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));\r
+               return -1;\r
+       }\r
+\r
+       return(0);\r
+}\r
+\r
 int main(int argc, char **argv)\r
 {\r
        int i, daemon = 0;\r
@@ -2032,7 +2066,7 @@ int main(int argc, char **argv)
                if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) {\r
                        save_history = atoi(argv[i+1]);\r
                        if(save_history < 5 || save_history > HISTORY_MAX) {\r
-                               error("Invalid save lines %d given. Defaulting to %d.", save_history, HISTORY);\r
+                               fprintf(stderr, "Invalid save lines %d given. Defaulting to %d.\n", save_history, HISTORY);\r
                                save_history = HISTORY;\r
                        }\r
                        else {\r
@@ -2041,9 +2075,19 @@ int main(int argc, char **argv)
                        i++;\r
                }\r
                else if(strcmp(argv[i], "-u") == 0 && (i+1) < argc) {\r
+                       if(become_user(argv[i+1]) != 0) {\r
+                               fprintf(stderr, "Cannot become user %s.\n", argv[i+1]);\r
+                               exit(1);\r
+                       }\r
+                       else {\r
+                               debug(D_OPTIONS, "Successfully became user %s.", argv[i+1]);\r
+                       }\r
+                       i++;\r
+               }\r
+               else if(strcmp(argv[i], "-t") == 0 && (i+1) < argc) {\r
                        update_every = atoi(argv[i+1]);\r
                        if(update_every < 1 || update_every > 600) {\r
-                               error("Invalid update timer %d given. Defaulting to %d.", update_every, UPDATE_EVERY_MAX);\r
+                               fprintf(stderr, "Invalid update timer %d given. Defaulting to %d.\n", update_every, UPDATE_EVERY_MAX);\r
                                update_every = UPDATE_EVERY;\r
                        }\r
                        else {\r
@@ -2054,7 +2098,7 @@ int main(int argc, char **argv)
                else if(strcmp(argv[i], "-p") == 0 && (i+1) < argc) {\r
                        listen_port = atoi(argv[i+1]);\r
                        if(listen_port < 1 || listen_port > 65535) {\r
-                               error("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT);\r
+                               fprintf(stderr, "Invalid listen port %d given. Defaulting to %d.\n", listen_port, LISTEN_PORT);\r
                                listen_port = LISTEN_PORT;\r
                        }\r
                        else {\r
@@ -2071,19 +2115,28 @@ int main(int argc, char **argv)
                        fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT].\n\n", argv[0]);\r
                        fprintf(stderr, "  -d enable daemon mode (run in background).\n");\r
                        fprintf(stderr, "  -l LINES_TO_SAVE can be from 5 to %d lines in JSON data. Default: %d.\n", HISTORY_MAX, HISTORY);\r
-                       fprintf(stderr, "  -u UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);\r
+                       fprintf(stderr, "  -t UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);\r
                        fprintf(stderr, "  -p LISTEN_PORT can be from 1 to %d. Default: %d.\n", 65535, LISTEN_PORT);\r
+                       fprintf(stderr, "  -u USERNAME can be any system username to run as. Default: none.\n");\r
                        exit(1);\r
                }\r
        }\r
 \r
+       // never become a problem\r
+       if(nice(20) == -1) {\r
+               fprintf(stderr, "Cannot lower my CPU priority. Error %s.\n", strerror(errno));\r
+       }\r
+\r
        if(daemon) {\r
                i = fork();\r
                if(i == -1) {\r
                        perror("cannot fork");\r
                        exit(1);\r
                }\r
-               if(i != 0) exit(0); // the parent\r
+               if(i != 0) {\r
+                       fprintf(stderr, "Running in the background...\n");\r
+                       exit(0); // the parent\r
+               }\r
                close(0);\r
                close(1);\r
                close(2);\r
index e1eeecf7afd7d2a8e7d354282d98cb5d6463ce33..59dd23c2c2eff8e7e1b4740c01804fa139780fc6 100755 (executable)
@@ -2,7 +2,7 @@
 
 base="`dirname "$0"`"
 
-if [ ! -d "$base" -o ! -f "$base/netdata.c" ]
+if [ ! -d "$base" -o ! -f "$base/netdata.c" -o ! -d "$base/web" ]
 then
        echo >&2 "Cannot find my home directory '${base}'."
        exit 1
@@ -26,6 +26,16 @@ NETDATA_CONFIG_HISTORY_DATA=3600
 # when refreshes graphs
 NETDATA_CONFIG_RELOAD_EVERY=500
 
+# the user to run netdata under
+NETDATA_CONFIG_USER=nobody
+
+# set to 1, to enable debugging
+NETDATA_CONFIG_DEBUG=0
+
+# our port
+NETDATA_CONFIG_PORT=19999
+
+# get user configuration
 if [ -f netdata.conf ]
 then
        source netdata.conf
@@ -34,75 +44,36 @@ fi
 # how many history lines to keep in netdata
 NETDATA_HISTORY_LINES=$[NETDATA_CONFIG_UPDATE_EVERY * NETDATA_CONFIG_HISTORY_POINTS / NETDATA_CONFIG_INTERNAL_UPDATE_EVERY]
 
-echo "Creating a directory for netdata..."
-data=
-for x in /run/netdata /var/run/netdata /tmp/netdata
-do
-       echo "  Trying '${x}'..."
-       if [ ! -d "${x}" ]
-       then
-               mkdir "${x}" 2>/dev/null
-               if [ $? -eq 0 ]
-               then
-                       echo "  OK. '${x}' works."
-                       data="${x}"
-                       break
-               fi
-       else
-               echo "  OK. '${x}' works."
-               data="${x}"
-               break
-       fi
-done
-
-if [ -z "${data}" ]
-then
-       echo >&2 "Cannot find where to put netdata files."
-       exit 1
-fi
-
-if [ -h data ]
-then
-       echo "Removing existing $base/data link"
-       rm data || exit 1
-fi
-
-if [ ! -d data ]
-then
-       echo "Linking '${data}' to $base/data"
-       ln -s "${data}" data || exit 1
-else
-       echo >&2 "Directory $base/data already exists. Not touching it, however it should be a link '${data}'."
-fi
-
-cp "${base}/all.xsl" "${data}/"
-cp "${base}/netdata.js" "${data}/"
-cp "${base}/tc-all.sh" "${data}/"
-chmod 700 "${data}/tc-all.sh"
-
-echo "Finding proper parameters for dashboard..."
-
 echo "Stopping a (possibly) running netdata..."
 killall netdata 2>/dev/null
 killall tc-all.sh 2>/dev/null
-
 sleep 2
 
 echo "Compiling netdata"
-# gcc -Wall -O3 -o netdata netdata.c -lpthread || exit 1
-gcc -Wall -ggdb -o netdata netdata.c -lpthread || exit 1
+if [ $NETDATA_CONFIG_DEBUG -eq 1 ]
+then
+       ulimit -c unlimited
+       gcc -Wall -ggdb -o netdata netdata.c -lpthread || exit 1
+else
+       gcc -Wall -O3 -o netdata netdata.c -lpthread || exit 1
+fi
 
 echo "Starting netdata"
-p=`pwd`
-cd data
-ulimit -c unlimited
-$p/netdata -d -u $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES || exit 1
-cd "$p"
-
+if [ "$USER" = "root" ]
+then
+       chown -R "$NETDATA_CONFIG_USER" web || exit 1
+       chmod    0775 web   || exit 1
+       chmod -R 0664 web/* || exit 1
+       ./netdata -d -u $NETDATA_CONFIG_USER -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
+else
+       echo >&2 "WARNING: NOT RUNNING AS ROOT - CANNOT SWITCH TO USER $NETDATA_CONFIG_USER"
+       echo >&2 "WARNING: MAKE SURE FILES IN web/ ARE OWNED BY $USER - or it will not work"
+       ./netdata -d -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
+fi
 sleep 2
 
 # count all graphs
-all=`wget http://127.0.0.1:19999/list -O - 2>/dev/null`
+all=`wget http://127.0.0.1:$NETDATA_CONFIG_PORT/list -O - 2>/dev/null`
 count=0
 for x in $all
 do
@@ -116,9 +87,9 @@ done
 
 echo "We have $count graphs..."
 
-echo "Generating ${data}/index.html"
+echo "Generating web/index.html"
 host="`hostname`"
-cat >${data}/index.html <<EOF
+cat >web/index.html <<EOF
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <style>
@@ -175,13 +146,13 @@ do
        eval "p=\${NETDATA_PRIORITY_${y}}"
        if [ ! "$p" = "IGNORE" ]
        then
-               cat >>${data}/index.html <<EOF2
+               cat >>web/index.html <<EOF2
                addChart('${x}', '${y}_div', 0, 0, "data/${x}/${NETDATA_CONFIG_HISTORY_POINTS}/${NETDATA_CONFIG_UPDATE_EVERY}/average/", "${title}${t} (${x})", "${vtitle}");
 EOF2
        fi
 done
 
-cat >>${data}/index.html <<EOF3
+cat >>web/index.html <<EOF3
                refreshCharts(999999);
        }
        
@@ -225,25 +196,29 @@ done >"${tmp}"
 for x in `cat "${tmp}" | sort`
 do
        n="`echo "$x" | cut -d '|' -f 2-`"
-       cat >>${data}/index.html <<EOF4
+       cat >>web/index.html <<EOF4
        <div id="${n}_div"></div>
 EOF4
 done
 rm -f "${tmp}"
 
-cat >>${data}/index.html <<EOF5
+cat >>web/index.html <<EOF5
  </body>
 </html>
 EOF5
 
-set|grep ^NETDATA_ >netdata.conf
-
-if [ ! -h "${data}/data" ]
+if [ "$USER" = "root" ]
 then
-       cd "${data}"
-       ln -s . data
+       chown -R "$NETDATA_CONFIG_USER" web || exit 1
+       chmod    0775 web   || exit 1
+       chmod -R 0664 web/* || exit 1
 fi
 
-echo "All Done."
-echo "Just hit http://127.0.0.1:19999/ from your browser."
+# save config back
+set|grep ^NETDATA_ >netdata.conf
 
+echo "All Done."
+echo "Just hit http://127.0.0.1:$NETDATA_CONFIG_PORT/ from your browser."
+echo
+echo "You can edit config options in file netdata.conf"
+echo
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)