s4:server.c - use always "return" instead of "exit" in the "binary_smbd_main" function
[kai/samba.git] / source4 / smbd / server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Main SMB server routines
5
6    Copyright (C) Andrew Tridgell                1992-2005
7    Copyright (C) Martin Pool                    2002
8    Copyright (C) Jelmer Vernooij                2002
9    Copyright (C) James J Myers                  2003 <myersjj@samba.org>
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "version.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "system/dir.h"
30 #include "system/filesys.h"
31 #include "ntvfs/ntvfs.h"
32 #include "ntptr/ntptr.h"
33 #include "auth/gensec/gensec.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "smbd/process_model.h"
36 #include "param/secrets.h"
37 #include "smbd/pidfile.h"
38 #include "param/param.h"
39 #include "dsdb/samdb/samdb.h"
40 #include "auth/session.h"
41 #include "lib/messaging/irpc.h"
42 #include "librpc/gen_ndr/ndr_irpc.h"
43 #include "cluster/cluster.h"
44
45 /*
46   recursively delete a directory tree
47 */
48 static void recursive_delete(const char *path)
49 {
50         DIR *dir;
51         struct dirent *de;
52
53         dir = opendir(path);
54         if (!dir) {
55                 return;
56         }
57
58         for (de=readdir(dir);de;de=readdir(dir)) {
59                 char *fname;
60                 struct stat st;
61
62                 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) {
63                         continue;
64                 }
65
66                 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
67                 if (stat(fname, &st) != 0) {
68                         continue;
69                 }
70                 if (S_ISDIR(st.st_mode)) {
71                         recursive_delete(fname);
72                         talloc_free(fname);
73                         continue;
74                 }
75                 if (unlink(fname) != 0) {
76                         DEBUG(0,("Unabled to delete '%s' - %s\n", 
77                                  fname, strerror(errno)));
78                         smb_panic("unable to cleanup tmp files");
79                 }
80                 talloc_free(fname);
81         }
82         closedir(dir);
83 }
84
85 /*
86   cleanup temporary files. This is the new alternative to
87   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
88   efficient on unix systems due to the lack of scaling of the byte
89   range locking system. So instead of putting the burden on tdb to
90   cleanup tmp files, this function deletes them. 
91 */
92 static void cleanup_tmp_files(struct loadparm_context *lp_ctx)
93 {
94         char *path;
95         TALLOC_CTX *mem_ctx = talloc_new(NULL);
96
97         path = smbd_tmp_path(mem_ctx, lp_ctx, NULL);
98
99         recursive_delete(path);
100         talloc_free(mem_ctx);
101 }
102
103 static void sig_hup(int sig)
104 {
105         debug_schedule_reopen_logs();
106 }
107
108 static void sig_term(int sig)
109 {
110 #if HAVE_GETPGRP
111         static int done_sigterm;
112         if (done_sigterm == 0 && getpgrp() == getpid()) {
113                 DEBUG(0,("SIGTERM: killing children\n"));
114                 done_sigterm = 1;
115                 kill(-getpgrp(), SIGTERM);
116         }
117 #endif
118         DEBUG(0,("Exiting pid %d on SIGTERM\n", (int)getpid()));
119         exit(0);
120 }
121
122 /*
123   setup signal masks
124 */
125 static void setup_signals(void)
126 {
127         /* we are never interested in SIGPIPE */
128         BlockSignals(true,SIGPIPE);
129
130 #if defined(SIGFPE)
131         /* we are never interested in SIGFPE */
132         BlockSignals(true,SIGFPE);
133 #endif
134
135         /* We are no longer interested in USR1 */
136         BlockSignals(true, SIGUSR1);
137
138 #if defined(SIGUSR2)
139         /* We are no longer interested in USR2 */
140         BlockSignals(true,SIGUSR2);
141 #endif
142
143         /* POSIX demands that signals are inherited. If the invoking process has
144          * these signals masked, we will have problems, as we won't recieve them. */
145         BlockSignals(false, SIGHUP);
146         BlockSignals(false, SIGTERM);
147
148         CatchSignal(SIGHUP, sig_hup);
149         CatchSignal(SIGTERM, sig_term);
150 }
151
152 /*
153   handle io on stdin
154 */
155 static void server_stdin_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
156                                  uint16_t flags, void *private_data)
157 {
158         const char *binary_name = (const char *)private_data;
159         uint8_t c;
160         if (read(0, &c, 1) == 0) {
161                 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
162 #if HAVE_GETPGRP
163                 if (getpgrp() == getpid()) {
164                         DEBUG(0,("Sending SIGTERM from pid %d\n", (int)getpid()));
165                         kill(-getpgrp(), SIGTERM);
166                 }
167 #endif
168                 exit(0);
169         }
170 }
171
172 /*
173   die if the user selected maximum runtime is exceeded
174 */
175 _NORETURN_ static void max_runtime_handler(struct tevent_context *ev, 
176                                            struct tevent_timer *te, 
177                                            struct timeval t, void *private_data)
178 {
179         const char *binary_name = (const char *)private_data;
180         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
181         exit(0);
182 }
183
184 /*
185   pre-open the key databases. This saves a lot of time in child
186   processes
187  */
188 static void prime_ldb_databases(struct tevent_context *event_ctx)
189 {
190         TALLOC_CTX *db_context;
191         db_context = talloc_new(event_ctx);
192
193         samdb_connect(db_context, event_ctx, cmdline_lp_ctx, system_session(cmdline_lp_ctx));
194         privilege_connect(db_context, event_ctx, cmdline_lp_ctx);
195         schannel_db_connect(db_context, event_ctx, cmdline_lp_ctx);
196
197         /* we deliberately leave these open, which allows them to be
198          * re-used in ldb_wrap_connect() */
199 }
200
201
202 /*
203   called when a fatal condition occurs in a child task
204  */
205 static NTSTATUS samba_terminate(struct irpc_message *msg, 
206                                 struct samba_terminate *r)
207 {
208         DEBUG(0,("samba_terminate: %s\n", r->in.reason));
209         exit(1);
210 }
211
212 /*
213   setup messaging for the top level samba (parent) task
214  */
215 static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, 
216                                        struct loadparm_context *lp_ctx)
217 {
218         struct messaging_context *msg;
219         NTSTATUS status;
220
221         msg = messaging_init(talloc_autofree_context(), 
222                              lp_messaging_path(event_ctx, lp_ctx),
223                              cluster_id(0, SAMBA_PARENT_TASKID),
224                              lp_iconv_convenience(lp_ctx),
225                              event_ctx);
226         NT_STATUS_HAVE_NO_MEMORY(msg);
227
228         irpc_add_name(msg, "samba");
229
230         status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
231                                samba_terminate, NULL);
232
233         return status;
234 }
235
236
237
238 /*
239  main server.
240 */
241 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
242 {
243         bool opt_daemon = false;
244         bool opt_interactive = false;
245         int opt;
246         poptContext pc;
247         extern NTSTATUS server_service_wrepl_init(void);
248         extern NTSTATUS server_service_kdc_init(void);
249         extern NTSTATUS server_service_ldap_init(void);
250         extern NTSTATUS server_service_web_init(void);
251         extern NTSTATUS server_service_ldap_init(void);
252         extern NTSTATUS server_service_winbind_init(void);
253         extern NTSTATUS server_service_nbtd_init(void);
254         extern NTSTATUS server_service_auth_init(void);
255         extern NTSTATUS server_service_cldapd_init(void);
256         extern NTSTATUS server_service_smb_init(void);
257         extern NTSTATUS server_service_drepl_init(void);
258         extern NTSTATUS server_service_kcc_init(void);
259         extern NTSTATUS server_service_dnsupdate_init(void);
260         extern NTSTATUS server_service_rpc_init(void);
261         extern NTSTATUS server_service_ntp_signd_init(void);
262         extern NTSTATUS server_service_samba3_smb_init(void);
263         init_module_fn static_init[] = { STATIC_service_MODULES };
264         init_module_fn *shared_init;
265         struct tevent_context *event_ctx;
266         uint16_t stdin_event_flags;
267         NTSTATUS status;
268         const char *model = "standard";
269         int max_runtime = 0;
270         enum {
271                 OPT_DAEMON = 1000,
272                 OPT_INTERACTIVE,
273                 OPT_PROCESS_MODEL
274         };
275         struct poptOption long_options[] = {
276                 POPT_AUTOHELP
277                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
278                  "Become a daemon (default)", NULL },
279                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
280                  "Run interactive (not a daemon)", NULL},
281                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
282                  "Select process model", "MODEL"},
283                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
284                  "set maximum runtime of the server process, till autotermination", "seconds"},
285                 POPT_COMMON_SAMBA
286                 POPT_COMMON_VERSION
287                 { NULL }
288         };
289
290         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
291         while((opt = poptGetNextOpt(pc)) != -1) {
292                 switch(opt) {
293                 case OPT_DAEMON:
294                         opt_daemon = true;
295                         break;
296                 case OPT_INTERACTIVE:
297                         opt_interactive = true;
298                         break;
299                 case OPT_PROCESS_MODEL:
300                         model = poptGetOptArg(pc);
301                         break;
302                 default:
303                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
304                                   poptBadOption(pc, 0), poptStrerror(opt));
305                         poptPrintUsage(pc, stderr, 0);
306                         return 1;
307                 }
308         }
309
310         if (opt_daemon && opt_interactive) {
311                 fprintf(stderr,"\nERROR: "
312                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
313                 poptPrintUsage(pc, stderr, 0);
314                 return 1;
315         } else if (!opt_interactive) {
316                 /* default is --daemon */
317                 opt_daemon = true;
318         }
319
320         poptFreeContext(pc);
321
322         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
323         setup_signals();
324
325         /* we want total control over the permissions on created files,
326            so set our umask to 0 */
327         umask(0);
328
329         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
330         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2010\n"));
331
332         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
333                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
334                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
335                             (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
336                 return 1;
337         }
338
339         if (opt_daemon) {
340                 DEBUG(3,("Becoming a daemon.\n"));
341                 become_daemon(true, false);
342         }
343
344         cleanup_tmp_files(cmdline_lp_ctx);
345
346         if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
347                 mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
348         }
349
350         pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
351
352         /* Do *not* remove this, until you have removed
353          * passdb/secrets.c, and proved that Samba still builds... */
354         /* Setup the SECRETS subsystem */
355         if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) {
356                 return 1;
357         }
358
359         gensec_init(cmdline_lp_ctx); /* FIXME: */
360
361         ntptr_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization function 
362                                                 of the spoolss RPC server instead? */
363
364         ntvfs_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization functions 
365                                                 of the SMB[,2] server instead? */
366
367         process_model_init(cmdline_lp_ctx); 
368
369         shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
370
371         run_init_functions(static_init);
372         run_init_functions(shared_init);
373
374         talloc_free(shared_init);
375         
376         /* the event context is the top level structure in smbd. Everything else
377            should hang off that */
378         event_ctx = s4_event_context_init(talloc_autofree_context());
379
380         /* setup this as the default context */
381         s4_event_context_set_default(event_ctx);
382
383         if (event_ctx == NULL) {
384                 DEBUG(0,("Initializing event context failed\n"));
385                 return 1;
386         }
387
388         if (opt_interactive) {
389                 /* terminate when stdin goes away */
390                 stdin_event_flags = TEVENT_FD_READ;
391         } else {
392                 /* stay alive forever */
393                 stdin_event_flags = 0;
394         }
395
396         /* catch EOF on stdin */
397 #ifdef SIGTTIN
398         signal(SIGTTIN, SIG_IGN);
399 #endif
400         tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
401                       server_stdin_handler,
402                       discard_const(binary_name));
403
404         if (max_runtime) {
405                 tevent_add_timer(event_ctx, event_ctx,
406                                  timeval_current_ofs(max_runtime, 0),
407                                  max_runtime_handler,
408                                  discard_const(binary_name));
409         }
410
411         prime_ldb_databases(event_ctx);
412
413         status = setup_parent_messaging(event_ctx, cmdline_lp_ctx);
414         if (!NT_STATUS_IS_OK(status)) {
415                 DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status)));
416                 return 1;
417         }
418
419         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
420
421         status = server_service_startup(event_ctx, cmdline_lp_ctx, model, 
422                                         lp_server_services(cmdline_lp_ctx));
423         if (!NT_STATUS_IS_OK(status)) {
424                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
425                 return 1;
426         }
427
428         /* wait for events - this is where smbd sits for most of its
429            life */
430         tevent_loop_wait(event_ctx);
431
432         /* as everything hangs off this event context, freeing it
433            should initiate a clean shutdown of all services */
434         talloc_free(event_ctx);
435
436         return 0;
437 }
438
439 int main(int argc, const char *argv[])
440 {
441         return binary_smbd_main("samba", argc, argv);
442 }