@cryptotaxi247 / netdata-1 / commits / 78df830a0

can now become another user

Costa Tsaousis (ktsaou) committed Mar 27, 2014 at 03:09 UTC 78df830a0a8aff0f3b95f37493066b9f22c53f9b
4 files changed +107 -79
netdata.c
+60 -7
@@ -6,6 +6,7 @@
6 #include <string.h>
7 #include <time.h>
8 #include <unistd.h>
9 +#include <pwd.h>
10 #include <sys/types.h>
11 #include <sys/time.h>
12
@@ -933,9 +934,15 @@ int mysendfile(struct web_client *w, char *filename)
934 return 400;
935 }
936
937 + // access the file in web/*
938 + char webfilename[FILENAME_MAX + 1];
939 + strcpy(webfilename, "web/");
940 + strncpy(&webfilename[4], filename, FILENAME_MAX - 4);
941 + webfilename[FILENAME_MAX] = '\0';
942 +
943 // check if the file exists
944 struct stat stat;
938 - if(lstat(filename, &stat) != 0) {
945 + if(lstat(webfilename, &stat) != 0) {
946 debug(D_WEB_CLIENT_ACCESS, "%llu: File '%s' is not found.", w->id, filename);
947 w->data->bytes = sprintf(w->data->buffer, "File '%s' does not exist, or is not accessible.", filename);
948 return 404;
@@ -949,7 +956,7 @@ int mysendfile(struct web_client *w, char *filename)
956 }
957
958 // open the file
952 - w->ifd = open(filename, O_NONBLOCK, O_RDONLY);
959 + w->ifd = open(webfilename, O_NONBLOCK, O_RDONLY);
960 if(w->ifd == -1) {
961 w->ifd = w->ofd;
962
@@ -2023,6 +2030,33 @@ void sig_handler(int signo)
2030 }
2031 }
2032
2033 +int become_user(const char *username)
2034 +{
2035 + struct passwd *pw = getpwnam(username);
2036 + if(!pw) {
2037 + fprintf(stderr, "User %s is not present. Error: %s\n", username, strerror(errno));
2038 + return -1;
2039 + }
2040 + if(setgid(pw->pw_gid) != 0) {
2041 + fprintf(stderr, "Cannot switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));
2042 + return -1;
2043 + }
2044 + if(setegid(pw->pw_gid) != 0) {
2045 + fprintf(stderr, "Cannot effectively switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));
2046 + return -1;
2047 + }
2048 + if(setuid(pw->pw_uid) != 0) {
2049 + fprintf(stderr, "Cannot switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));
2050 + return -1;
2051 + }
2052 + if(seteuid(pw->pw_uid) != 0) {
2053 + fprintf(stderr, "Cannot effectively switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));
2054 + return -1;
2055 + }
2056 +
2057 + return(0);
2058 +}
2059 +
2060 int main(int argc, char **argv)
2061 {
2062 int i, daemon = 0;
@@ -2032,7 +2066,7 @@ int main(int argc, char **argv)
2066 if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) {
2067 save_history = atoi(argv[i+1]);
2068 if(save_history < 5 || save_history > HISTORY_MAX) {
2035 - error("Invalid save lines %d given. Defaulting to %d.", save_history, HISTORY);
2069 + fprintf(stderr, "Invalid save lines %d given. Defaulting to %d.\n", save_history, HISTORY);
2070 save_history = HISTORY;
2071 }
2072 else {
@@ -2041,9 +2075,19 @@ int main(int argc, char **argv)
2075 i++;
2076 }
2077 else if(strcmp(argv[i], "-u") == 0 && (i+1) < argc) {
2078 + if(become_user(argv[i+1]) != 0) {
2079 + fprintf(stderr, "Cannot become user %s.\n", argv[i+1]);
2080 + exit(1);
2081 + }
2082 + else {
2083 + debug(D_OPTIONS, "Successfully became user %s.", argv[i+1]);
2084 + }
2085 + i++;
2086 + }
2087 + else if(strcmp(argv[i], "-t") == 0 && (i+1) < argc) {
2088 update_every = atoi(argv[i+1]);
2089 if(update_every < 1 || update_every > 600) {
2046 - error("Invalid update timer %d given. Defaulting to %d.", update_every, UPDATE_EVERY_MAX);
2090 + fprintf(stderr, "Invalid update timer %d given. Defaulting to %d.\n", update_every, UPDATE_EVERY_MAX);
2091 update_every = UPDATE_EVERY;
2092 }
2093 else {
@@ -2054,7 +2098,7 @@ int main(int argc, char **argv)
2098 else if(strcmp(argv[i], "-p") == 0 && (i+1) < argc) {
2099 listen_port = atoi(argv[i+1]);
2100 if(listen_port < 1 || listen_port > 65535) {
2057 - error("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT);
2101 + fprintf(stderr, "Invalid listen port %d given. Defaulting to %d.\n", listen_port, LISTEN_PORT);
2102 listen_port = LISTEN_PORT;
2103 }
2104 else {
@@ -2071,19 +2115,28 @@ int main(int argc, char **argv)
2115 fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT].\n\n", argv[0]);
2116 fprintf(stderr, " -d enable daemon mode (run in background).\n");
2117 fprintf(stderr, " -l LINES_TO_SAVE can be from 5 to %d lines in JSON data. Default: %d.\n", HISTORY_MAX, HISTORY);
2074 - fprintf(stderr, " -u UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);
2118 + fprintf(stderr, " -t UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);
2119 fprintf(stderr, " -p LISTEN_PORT can be from 1 to %d. Default: %d.\n", 65535, LISTEN_PORT);
2120 + fprintf(stderr, " -u USERNAME can be any system username to run as. Default: none.\n");
2121 exit(1);
2122 }
2123 }
2124
2125 + // never become a problem
2126 + if(nice(20) == -1) {
2127 + fprintf(stderr, "Cannot lower my CPU priority. Error %s.\n", strerror(errno));
2128 + }
2129 +
2130 if(daemon) {
2131 i = fork();
2132 if(i == -1) {
2133 perror("cannot fork");
2134 exit(1);
2135 }
2086 - if(i != 0) exit(0); // the parent
2136 + if(i != 0) {
2137 + fprintf(stderr, "Running in the background...\n");
2138 + exit(0); // the parent
2139 + }
2140 close(0);
2141 close(1);
2142 close(2);
netdata.start
+47 -72
@@ -2,7 +2,7 @@
2
3 base="`dirname "$0"`"
4
5 -if [ ! -d "$base" -o ! -f "$base/netdata.c" ]
5 +if [ ! -d "$base" -o ! -f "$base/netdata.c" -o ! -d "$base/web" ]
6 then
7 echo >&2 "Cannot find my home directory '${base}'."
8 exit 1
@@ -26,6 +26,16 @@ NETDATA_CONFIG_HISTORY_DATA=3600
26 # when refreshes graphs
27 NETDATA_CONFIG_RELOAD_EVERY=500
28
29 +# the user to run netdata under
30 +NETDATA_CONFIG_USER=nobody
31 +
32 +# set to 1, to enable debugging
33 +NETDATA_CONFIG_DEBUG=0
34 +
35 +# our port
36 +NETDATA_CONFIG_PORT=19999
37 +
38 +# get user configuration
39 if [ -f netdata.conf ]
40 then
41 source netdata.conf
@@ -34,75 +44,36 @@ fi
44 # how many history lines to keep in netdata
45 NETDATA_HISTORY_LINES=$[NETDATA_CONFIG_UPDATE_EVERY * NETDATA_CONFIG_HISTORY_POINTS / NETDATA_CONFIG_INTERNAL_UPDATE_EVERY]
46
37 -echo "Creating a directory for netdata..."
38 -data=
39 -for x in /run/netdata /var/run/netdata /tmp/netdata
40 -do
41 - echo " Trying '${x}'..."
42 - if [ ! -d "${x}" ]
43 - then
44 - mkdir "${x}" 2>/dev/null
45 - if [ $? -eq 0 ]
46 - then
47 - echo " OK. '${x}' works."
48 - data="${x}"
49 - break
50 - fi
51 - else
52 - echo " OK. '${x}' works."
53 - data="${x}"
54 - break
55 - fi
56 -done
57 -
58 -if [ -z "${data}" ]
59 -then
60 - echo >&2 "Cannot find where to put netdata files."
61 - exit 1
62 -fi
63 -
64 -if [ -h data ]
65 -then
66 - echo "Removing existing $base/data link"
67 - rm data || exit 1
68 -fi
69 -
70 -if [ ! -d data ]
71 -then
72 - echo "Linking '${data}' to $base/data"
73 - ln -s "${data}" data || exit 1
74 -else
75 - echo >&2 "Directory $base/data already exists. Not touching it, however it should be a link '${data}'."
76 -fi
77 -
78 -cp "${base}/all.xsl" "${data}/"
79 -cp "${base}/netdata.js" "${data}/"
80 -cp "${base}/tc-all.sh" "${data}/"
81 -chmod 700 "${data}/tc-all.sh"
82 -
83 -echo "Finding proper parameters for dashboard..."
84 -
47 echo "Stopping a (possibly) running netdata..."
48 killall netdata 2>/dev/null
49 killall tc-all.sh 2>/dev/null
88 -
50 sleep 2
51
52 echo "Compiling netdata"
92 -# gcc -Wall -O3 -o netdata netdata.c -lpthread || exit 1
93 -gcc -Wall -ggdb -o netdata netdata.c -lpthread || exit 1
53 +if [ $NETDATA_CONFIG_DEBUG -eq 1 ]
54 +then
55 + ulimit -c unlimited
56 + gcc -Wall -ggdb -o netdata netdata.c -lpthread || exit 1
57 +else
58 + gcc -Wall -O3 -o netdata netdata.c -lpthread || exit 1
59 +fi
60
61 echo "Starting netdata"
96 -p=`pwd`
97 -cd data
98 -ulimit -c unlimited
99 -$p/netdata -d -u $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES || exit 1
100 -cd "$p"
101 -
62 +if [ "$USER" = "root" ]
63 +then
64 + chown -R "$NETDATA_CONFIG_USER" web || exit 1
65 + chmod 0775 web || exit 1
66 + chmod -R 0664 web/* || exit 1
67 + ./netdata -d -u $NETDATA_CONFIG_USER -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
68 +else
69 + echo >&2 "WARNING: NOT RUNNING AS ROOT - CANNOT SWITCH TO USER $NETDATA_CONFIG_USER"
70 + echo >&2 "WARNING: MAKE SURE FILES IN web/ ARE OWNED BY $USER - or it will not work"
71 + ./netdata -d -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
72 +fi
73 sleep 2
74
75 # count all graphs
105 -all=`wget http://127.0.0.1:19999/list -O - 2>/dev/null`
76 +all=`wget http://127.0.0.1:$NETDATA_CONFIG_PORT/list -O - 2>/dev/null`
77 count=0
78 for x in $all
79 do
@@ -116,9 +87,9 @@ done
87
88 echo "We have $count graphs..."
89
119 -echo "Generating ${data}/index.html"
90 +echo "Generating web/index.html"
91 host="`hostname`"
121 -cat >${data}/index.html <<EOF
92 +cat >web/index.html <<EOF
93 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
94 <html xmlns="http://www.w3.org/1999/xhtml">
95 <style>
@@ -175,13 +146,13 @@ do
146 eval "p=\${NETDATA_PRIORITY_${y}}"
147 if [ ! "$p" = "IGNORE" ]
148 then
178 - cat >>${data}/index.html <<EOF2
149 + cat >>web/index.html <<EOF2
150 addChart('${x}', '${y}_div', 0, 0, "data/${x}/${NETDATA_CONFIG_HISTORY_POINTS}/${NETDATA_CONFIG_UPDATE_EVERY}/average/", "${title}${t} (${x})", "${vtitle}");
151 EOF2
152 fi
153 done
154
184 -cat >>${data}/index.html <<EOF3
155 +cat >>web/index.html <<EOF3
156 refreshCharts(999999);
157 }
158
@@ -225,25 +196,29 @@ done >"${tmp}"
196 for x in `cat "${tmp}" | sort`
197 do
198 n="`echo "$x" | cut -d '|' -f 2-`"
228 - cat >>${data}/index.html <<EOF4
199 + cat >>web/index.html <<EOF4
200 <div id="${n}_div"></div>
201 EOF4
202 done
203 rm -f "${tmp}"
204
234 -cat >>${data}/index.html <<EOF5
205 +cat >>web/index.html <<EOF5
206 </body>
207 </html>
208 EOF5
209
239 -set|grep ^NETDATA_ >netdata.conf
240 -
241 -if [ ! -h "${data}/data" ]
210 +if [ "$USER" = "root" ]
211 then
243 - cd "${data}"
244 - ln -s . data
212 + chown -R "$NETDATA_CONFIG_USER" web || exit 1
213 + chmod 0775 web || exit 1
214 + chmod -R 0664 web/* || exit 1
215 fi
216
247 -echo "All Done."
248 -echo "Just hit http://127.0.0.1:19999/ from your browser."
217 +# save config back
218 +set|grep ^NETDATA_ >netdata.conf
219
220 +echo "All Done."
221 +echo "Just hit http://127.0.0.1:$NETDATA_CONFIG_PORT/ from your browser."
222 +echo
223 +echo "You can edit config options in file netdata.conf"
224 +echo
web/all.xsl
web/netdata.js