1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #ifdef __gnu_linux__
31 #define _GNU_SOURCE
32 #endif
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <dlfcn.h>
37 #include <grp.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40
41 #include <openssl/bio.h>
42 #include <openssl/ssl.h>
43 #include <openssl/err.h>
44
45 #include "../public/nsapi.h"
46 #include "../public/auth.h"
47 #include "../util/systhr.h"
48 #include "../util/io.h"
49 #include "../util/util.h"
50
51 #include "../../ucx/utils.h"
52
53 #include "../safs/common.h"
54
55 #include "func.h"
56 #include "config.h"
57 #include "configmanager.h"
58 #include "httplistener.h"
59 #include "webserver.h"
60 #include "log.h"
61 #include "auth.h"
62 #include "srvctrl.h"
63
64 extern struct FuncStruct webserver_funcs[];
65
66 static RestartCallback *atrestart;
67
68 int webserver_init() {
69
70 systhread_init(
"webserver");
71
72
73 if(ws_init_ssl()) {
74 return -
1;
75 }
76
77
78 func_init();
79 add_functions(webserver_funcs);
80
81
82 if(load_init_conf(
"config/init.conf")) {
83 return -
1;
84 }
85
86
87 init_configuration_manager();
88 ServerConfiguration *cfg;
89 if(cfgmgr_load_config(&cfg) !=
0) {
90 fprintf(stderr,
"Cannot load configuration\n");
91 return -
1;
92 }
93
94
95 auth_cache_init();
96
97
98 common_saf_init();
99
100
101 conf_global_vars_s *vars = conf_getglobals();
102
103 WSBool changeuid =
FALSE;
104 uid_t ws_uid = geteuid();
105 setpwent();
106 char *pwbuf = malloc(
DEF_PWBUF);
107 vars->Vuserpw = malloc(
sizeof(
struct passwd));
108 if(cfg->user.ptr) {
109 if(!util_getpwnam(cfg->user.ptr, vars->Vuserpw, pwbuf,
DEF_PWBUF)) {
110 log_ereport(
111 LOG_MISCONFIG,
112 "user %s does not exist!",
113 cfg->user.ptr);
114 free(vars->Vuserpw);
115 vars->Vuserpw =
NULL;
116 }
else {
117 changeuid =
TRUE;
118 }
119 }
else {
120 if(!util_getpwuid(ws_uid, vars->Vuserpw, pwbuf,
DEF_PWBUF)) {
121 log_ereport(
LOG_FAILURE,
"webserver_init: cannot get passwd data");
122 free(vars->Vuserpw);
123 vars->Vuserpw =
NULL;
124 }
125 }
126 if(!vars->Vuserpw) {
127 log_ereport(
LOG_WARN,
"globalvars->Vuserpw is null");
128 }
129
130
131 if(changeuid && ws_uid ==
0) {
132
133
134 if(setgid(vars->Vuserpw->pw_gid) !=
0) {
135 log_ereport(
136 LOG_FAILURE,
137 "setgid(%d) failed",
138 vars->Vuserpw->pw_gid);
139 }
else {
140
141
142 if(initgroups(vars->Vuserpw->pw_name, vars->Vuserpw->pw_gid)!=
0) {
143 log_ereport(
LOG_FAILURE,
"initgroups failed");
144 }
145 }
146
147
148 if(setuid(vars->Vuserpw->pw_uid)) {
149 log_ereport(
150 LOG_FAILURE,
151 "setuid(%d) failed",
152 vars->Vuserpw->pw_uid);
153 }
154 }
else if(vars->Vuserpw) {
155 log_ereport(
156 LOG_WARN,
157 "server must be started as root to change uid");
158 }
159
160
161 char *mkdir_cmd =
NULL;
162 asprintf(&mkdir_cmd,
"mkdir -p %s", cfg->tmp.ptr);
163 system(mkdir_cmd);
164 free(mkdir_cmd);
165
166 char *pid_file_path =
NULL;
167 asprintf(&pid_file_path,
"%s/pid", cfg->tmp.ptr);
168 FILE *pidfile = fopen(pid_file_path,
"w");
169 pid_t pid = getpid();
170 fprintf(pidfile,
"%d", pid);
171 fclose(pidfile);
172 free(pid_file_path);
173
174
175 sstr_t tmp_priv = ucx_sprintf(
"%s/private", cfg->tmp.ptr);
176
177 if(mkdir(tmp_priv.ptr,
S_IRWXU)) {
178 if(errno ==
EEXIST) {
179 if(chmod(tmp_priv.ptr,
S_IRWXU)) {
180 log_ereport(
181 LOG_CATASTROPHE,
182 "cannot change permissions of tmp dir %s:",
183 tmp_priv.ptr,
184 strerror(errno));
185 return 0;
186 }
187 }
else {
188 log_ereport(
189 LOG_CATASTROPHE,
190 "cannot create tmp dir %s:",
191 tmp_priv.ptr,
192 strerror(errno));
193 return -
1;
194 }
195 }
196
197
198
199
200 if(srvctrl_init(cfg)) {
201 return -
1;
202 }
203
204
205
206
207 return 0;
208 }
209
210 int webserver_run() {
211 log_ereport(
LOG_VERBOSE,
"webserver_run");
212
213
214 if(start_all_listener() !=
0) {
215 fprintf(stderr,
"Error: Cannot start http listener\n");
216 }
217
218 log_ereport(
LOG_INFORM,
"webserver started");
219
220 return 0;
221 }
222
223 void webserver_shutdown() {
224 log_ereport(
LOG_INFORM,
"webserver shutdown");
225
226 srvctrl_shutdown();
227
228
229 RestartCallback *re = atrestart;
230 while(re) {
231 re->func(re->data);
232 re = re->next;
233 }
234 }
235
236 int webserver_reconfig() {
237 if(cfgmgr_load_config(
NULL) !=
0) {
238 return -
1;
239 }
240
241 start_all_listener();
242
243 return 0;
244 }
245
246 void webserver_atrestart(
void (*fn)(
void *),
void *data) {
247 RestartCallback *cb = malloc(
sizeof(RestartCallback));
248 cb->func = fn;
249 cb->data = data;
250 cb->next =
NULL;
251
252 if(atrestart) {
253 RestartCallback *elm = atrestart;
254 while(elm) {
255 if(!elm->next) {
256 elm->next = cb;
257 break;
258 }
259 elm = elm->next;
260 }
261 }
else {
262 atrestart = cb;
263 }
264 }
265
266 int nsapi_runtime_version() {
267 return 303;
268 }
269
270
271 int ws_init_ssl() {
272
273 SSL_load_error_strings();
274 SSL_library_init();
275 OpenSSL_add_all_algorithms();
276 return 0;
277 }
278