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