r24623: add back '-D' option to smbd
[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 "build.h"
32 #include "ldb/include/ldb.h"
33 #include "registry/registry.h"
34 #include "ntvfs/ntvfs.h"
35 #include "ntptr/ntptr.h"
36 #include "auth/gensec/gensec.h"
37 #include "smbd/process_model.h"
38 #include "smbd/service.h"
39 #include "param/secrets.h"
40 #include "smbd/pidfile.h"
41 #include "cluster/ctdb/ctdb_cluster.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(void)
91 {
92         char *path;
93         TALLOC_CTX *mem_ctx = talloc_new(NULL);
94
95         path = smbd_tmp_path(mem_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 = 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 static void max_runtime_handler(struct event_context *ev, struct timed_event *te, 
172                                 struct timeval t, void *private)
173 {
174         const char *binary_name = private;
175         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
176         exit(0);
177 }
178
179 /*
180  main server.
181 */
182 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
183 {
184         bool opt_daemon = false;
185         bool opt_interactive = false;
186         int opt;
187         poptContext pc;
188         init_module_fn static_init[] = STATIC_service_MODULES;
189         init_module_fn *shared_init;
190         struct event_context *event_ctx;
191         NTSTATUS status;
192         const char *model = "standard";
193         int max_runtime = 0;
194         enum {
195                 OPT_DAEMON = 1000,
196                 OPT_INTERACTIVE,
197                 OPT_PROCESS_MODEL
198         };
199         struct poptOption long_options[] = {
200                 POPT_AUTOHELP
201                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
202                  "Become a daemon (default)", NULL },
203                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
204                  "Run interactive (not a daemon)", NULL},
205                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
206                  "Select process model", "MODEL"},
207                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
208                  "set maximum runtime of the server process, till autotermination", "seconds"},
209                 POPT_COMMON_SAMBA
210                 POPT_COMMON_VERSION
211                 { NULL }
212         };
213
214         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
215         while((opt = poptGetNextOpt(pc)) != -1) {
216                 switch(opt) {
217                 case OPT_DAEMON:
218                         opt_daemon = true;
219                         break;
220                 case OPT_INTERACTIVE:
221                         opt_interactive = true;
222                         break;
223                 case OPT_PROCESS_MODEL:
224                         model = poptGetOptArg(pc);
225                         break;
226                 default:
227                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
228                                   poptBadOption(pc, 0), poptStrerror(opt));
229                         poptPrintUsage(pc, stderr, 0);
230                         exit(1);
231                 }
232         }
233
234         if (opt_daemon && opt_interactive) {
235                 d_fprintf(stderr,"\nERROR: "
236                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
237                 poptPrintUsage(pc, stderr, 0);
238                 exit(1);
239         } else if (!opt_interactive) {
240                 /* default is --daemon */
241                 opt_daemon = true;
242         }
243
244         poptFreeContext(pc);
245
246         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
247         setup_signals();
248
249         /* we want total control over the permissions on created files,
250            so set our umask to 0 */
251         umask(0);
252
253         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
254         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2007\n"));
255
256         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
257                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
258                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
259                         sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t)));
260                 exit(1);
261         }
262
263         if (opt_daemon) {
264                 DEBUG(3,("Becoming a daemon.\n"));
265                 become_daemon(True);
266         }
267
268         cleanup_tmp_files();
269
270         if (!directory_exist(lp_lockdir())) {
271                 mkdir(lp_lockdir(), 0755);
272         }
273
274         pidfile_create(binary_name);
275
276         /* Do *not* remove this, until you have removed
277          * passdb/secrets.c, and proved that Samba still builds... */
278         /* Setup the SECRETS subsystem */
279         if (!secrets_init()) {
280                 exit(1);
281         }
282
283         ldb_global_init(); /* FIXME: */
284
285         share_init();
286
287         gensec_init(); /* FIXME: */
288
289         registry_init(); /* FIXME: maybe run this in the initialization function 
290                                                 of the winreg RPC server instead? */
291
292         ntptr_init();   /* FIXME: maybe run this in the initialization function 
293                                                 of the spoolss RPC server instead? */
294
295         ntvfs_init();   /* FIXME: maybe run this in the initialization functions 
296                                                 of the SMB[,2] server instead? */
297
298         process_model_init(); 
299
300         shared_init = load_samba_modules(NULL, "service");
301
302         run_init_functions(static_init);
303         run_init_functions(shared_init);
304
305         talloc_free(shared_init);
306         
307         /* the event context is the top level structure in smbd. Everything else
308            should hang off that */
309         event_ctx = event_context_init(talloc_autofree_context());
310
311         /* initialise clustering if needed */
312         cluster_ctdb_init(event_ctx, model);
313
314         if (opt_interactive) {
315                 /* catch EOF on stdin */
316 #ifdef SIGTTIN
317                 signal(SIGTTIN, SIG_IGN);
318 #endif
319                 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ, 
320                              server_stdin_handler,
321                              discard_const(binary_name));
322         }
323
324
325         if (max_runtime) {
326                 event_add_timed(event_ctx, event_ctx, 
327                                 timeval_current_ofs(max_runtime, 0), 
328                                 max_runtime_handler,
329                                 discard_const(binary_name));
330         }
331
332         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
333         status = server_service_startup(event_ctx, model, lp_server_services());
334         if (!NT_STATUS_IS_OK(status)) {
335                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
336                 return 1;
337         }
338
339         /* wait for events - this is where smbd sits for most of its
340            life */
341         event_loop_wait(event_ctx);
342
343         /* as everything hangs off this event context, freeing it
344            should initiate a clean shutdown of all services */
345         talloc_free(event_ctx);
346
347         return 0;
348 }
349
350  int main(int argc, const char *argv[])
351 {
352         return binary_smbd_main("smbd", argc, argv);
353 }