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