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/pblock.h"
49 #include "../util/util.h"
50
51 #include <cx/utils.h>
52 #include <cx/printf.h>
53 #include <cx/compare.h>
54
55 #include "../safs/common.h"
56
57 #include "func.h"
58 #include "config.h"
59 #include "configmanager.h"
60 #include "httplistener.h"
61 #include "webserver.h"
62 #include "auth.h"
63 #include "srvctrl.h"
64 #include "resourcepool.h"
65 #include "ldap_resource.h"
66
67 extern struct FuncStruct webserver_funcs[];
68
69 static RestartCallback *atrestart;
70
71 int webserver_init() {
72
73 systhread_init(
"webserver");
74
75 log_ereport(
LOG_VERBOSE,
"webserver_init");
76
77
78 if(ws_init_ssl()) {
79 log_ereport(
LOG_FAILURE,
"ssl init failed");
80 return -
1;
81 }
82
83
84 if(http_listener_global_init()) {
85 log_ereport(
LOG_FAILURE,
"listener global init failed");
86 return -
1;
87 }
88
89
90 pblock_init_default_keys();
91 atexit(pblock_free_default_keys);
92 func_init();
93 add_functions(webserver_funcs);
94
95
96 if(init_resource_pools()) {
97 log_ereport(
LOG_FAILURE,
"resource pool init failed");
98 return -
1;
99 }
100 if(resourcepool_register_type(
"ldap", ldap_get_resource_type())) {
101 log_ereport(
LOG_FAILURE,
"webserver-init: Cannot register ldap resourcepool type");
102 return -
1;
103 }
104
105
106 InitConfig *init_config = load_init_conf(
"config/init.conf");
107 if(!init_config) {
108 return -
1;
109 }
110
111
112
113
114
115 init_configuration_manager();
116 CfgManager mgr;
117 if(cfgmgr_load_config(&mgr) !=
0) {
118 return 1;
119 }
120 log_ereport(
LOG_VERBOSE,
"cfgmgr_load_config stage 1 successful");
121 ServerConfiguration *cfg = mgr.cfg;
122
123
124 conf_global_vars_s *vars = conf_getglobals();
125
126 WSBool changeuid =
FALSE;
127 uid_t ws_uid = geteuid();
128 setpwent();
129 char *pwbuf = malloc(
DEF_PWBUF);
130 vars->Vuserpw = malloc(
sizeof(
struct passwd));
131 if(cfg->user.ptr) {
132 if(!util_getpwnam(cfg->user.ptr, vars->Vuserpw, pwbuf,
DEF_PWBUF)) {
133 log_ereport(
134 LOG_MISCONFIG,
135 "user %s does not exist!",
136 cfg->user.ptr);
137 free(vars->Vuserpw);
138 vars->Vuserpw =
NULL;
139 }
else {
140 changeuid =
TRUE;
141 }
142 }
else {
143 if(!util_getpwuid(ws_uid, vars->Vuserpw, pwbuf,
DEF_PWBUF)) {
144 log_ereport(
LOG_FAILURE,
"webserver_init: cannot get passwd data");
145 free(vars->Vuserpw);
146 vars->Vuserpw =
NULL;
147 }
148 }
149 if(!vars->Vuserpw) {
150 log_ereport(
LOG_VERBOSE,
"globalvars->Vuserpw is null");
151 }
152
153
154 if(changeuid && ws_uid ==
0) {
155
156 log_ereport(
LOG_VERBOSE,
"setgid(%d)", vars->Vuserpw->pw_gid);
157 if(setgid(vars->Vuserpw->pw_gid) !=
0) {
158 log_ereport(
159 LOG_FAILURE,
160 "setgid(%d) failed",
161 vars->Vuserpw->pw_gid);
162 return -
1;
163 }
else {
164
165
166 if(initgroups(vars->Vuserpw->pw_name, vars->Vuserpw->pw_gid)!=
0) {
167 log_ereport(
LOG_FAILURE,
"initgroups failed");
168 return -
1;
169 }
170 }
171
172
173 log_ereport(
LOG_VERBOSE,
"setuid(%d)", vars->Vuserpw->pw_uid);
174 if(setuid(vars->Vuserpw->pw_uid)) {
175 log_ereport(
176 LOG_FAILURE,
177 "setuid(%d) failed",
178 vars->Vuserpw->pw_uid);
179 return -
1;
180 }
181 }
else if(vars->Vuserpw) {
182 log_ereport(
183 LOG_WARN,
184 "server must be started as root to change uid");
185 }
186
187
188
189 int err = apply_init_conf(init_config);
190 free_init_conf(init_config);
191 if(err) {
192 log_ereport(
LOG_FAILURE,
"server init failed");
193 return 1;
194 }
195
196
197 auth_cache_init();
198
199
200 common_saf_init();
201
202
203
204
205 if(cfgmgr_apply_config(&mgr)) {
206 log_ereport(
LOG_FAILURE,
"load config stage 2 failed");
207 return -
1;
208 }
209
210
211
212 char *mkdir_cmd =
NULL;
213 asprintf(&mkdir_cmd,
"mkdir -p %s", cfg->tmp.ptr);
214 system(mkdir_cmd);
215 free(mkdir_cmd);
216
217 char *pid_file_path =
NULL;
218 asprintf(&pid_file_path,
"%s/pid", cfg->tmp.ptr);
219 FILE *pidfile = fopen(pid_file_path,
"w");
220 if(!pidfile) {
221 log_ereport(
LOG_FAILURE,
"cannot open pid file %s: %s", pid_file_path, strerror(errno));
222 return -
1;
223 }
224 pid_t pid = getpid();
225 fprintf(pidfile,
"%d", pid);
226 fclose(pidfile);
227 free(pid_file_path);
228
229
230 cxmutstr tmp_priv = cx_asprintf(
"%s/private", cfg->tmp.ptr);
231
232 if(mkdir(tmp_priv.ptr,
S_IRWXU)) {
233 if(errno ==
EEXIST) {
234 if(chmod(tmp_priv.ptr,
S_IRWXU)) {
235 log_ereport(
236 LOG_CATASTROPHE,
237 "cannot change permissions of tmp dir %s:",
238 tmp_priv.ptr,
239 strerror(errno));
240 return -
1;
241 }
242 }
else {
243 log_ereport(
244 LOG_CATASTROPHE,
245 "cannot create tmp dir %s:",
246 tmp_priv.ptr,
247 strerror(errno));
248 return -
1;
249 }
250 }
251 free(tmp_priv.ptr);
252
253
254
255
256 if(srvctrl_init(cfg)) {
257 return -
1;
258 }
259
260
261
262
263 return 0;
264 }
265
266 int webserver_run() {
267 log_ereport(
LOG_VERBOSE,
"webserver_run");
268
269
270 if(start_all_listener() !=
0) {
271 fprintf(stderr,
"Error: Cannot start http listener\n");
272 }
273
274 log_ereport(
LOG_INFORM,
"webserver started");
275
276 return 0;
277 }
278
279 void webserver_shutdown() {
280 log_ereport(
LOG_INFORM,
"webserver shutdown");
281
282 srvctrl_shutdown();
283 }
284
285 void webserver_end() {
286
287 RestartCallback *re = atrestart;
288 while(re) {
289 re->func(re->data);
290 re = re->next;
291 }
292
293 shutdown_threadpools();
294
295 shutdown_eventhandlers_wait();
296
297 webserver_destroy();
298 }
299
300 int webserver_reconfig() {
301 CfgManager mgr;
302 if(cfgmgr_load_config(&mgr) !=
0) {
303 log_ereport(
LOG_FAILURE,
"cannot reload server.conf");
304 return 1;
305 }
else {
306 if(cfgmgr_apply_config(&mgr)) {
307 log_ereport(
LOG_FAILURE,
"cannot reload config");
308 return 1;
309 }
310 }
311
312
313 start_all_listener();
314
315 return 0;
316 }
317
318 void webserver_atrestart(
void (*fn)(
void *),
void *data) {
319 RestartCallback *cb = malloc(
sizeof(RestartCallback));
320 cb->func = fn;
321 cb->data = data;
322 cb->next =
NULL;
323
324 if(atrestart) {
325 RestartCallback *elm = atrestart;
326 while(elm) {
327 if(!elm->next) {
328 elm->next = cb;
329 break;
330 }
331 elm = elm->next;
332 }
333 }
else {
334 atrestart = cb;
335 }
336 }
337
338 void webserver_destroy() {
339
340
341
342
343 pool_destroy(cfg_get_init_pool());
344 }
345
346 int nsapi_runtime_version() {
347 return 303;
348 }
349
350
351 int ws_init_ssl() {
352
353 SSL_load_error_strings();
354 SSL_library_init();
355 OpenSSL_add_all_algorithms();
356 return 0;
357 }
358