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