Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-trivial
[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 #include "param/param.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         exit(0);
118 }
119
120 /*
121   setup signal masks
122 */
123 static void setup_signals(void)
124 {
125         /* we are never interested in SIGPIPE */
126         BlockSignals(true,SIGPIPE);
127
128 #if defined(SIGFPE)
129         /* we are never interested in SIGFPE */
130         BlockSignals(true,SIGFPE);
131 #endif
132
133         /* We are no longer interested in USR1 */
134         BlockSignals(true, SIGUSR1);
135
136 #if defined(SIGUSR2)
137         /* We are no longer interested in USR2 */
138         BlockSignals(true,SIGUSR2);
139 #endif
140
141         /* POSIX demands that signals are inherited. If the invoking process has
142          * these signals masked, we will have problems, as we won't recieve them. */
143         BlockSignals(false, SIGHUP);
144         BlockSignals(false, SIGTERM);
145
146         CatchSignal(SIGHUP, sig_hup);
147         CatchSignal(SIGTERM, sig_term);
148 }
149
150 /*
151   handle io on stdin
152 */
153 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
154                                  uint16_t flags, void *private)
155 {
156         const char *binary_name = (const char *)private;
157         uint8_t c;
158         if (read(0, &c, 1) == 0) {
159                 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
160 #if HAVE_GETPGRP
161                 if (getpgrp() == getpid()) {
162                         kill(-getpgrp(), SIGTERM);
163                 }
164 #endif
165                 exit(0);
166         }
167 }
168
169 /*
170   die if the user selected maximum runtime is exceeded
171 */
172 _NORETURN_ static void max_runtime_handler(struct event_context *ev, 
173                                            struct timed_event *te, 
174                                            struct timeval t, void *private)
175 {
176         const char *binary_name = (const char *)private;
177         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
178         exit(0);
179 }
180
181 /*
182  main server.
183 */
184 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
185 {
186         bool opt_daemon = false;
187         bool opt_interactive = false;
188         int opt;
189         poptContext pc;
190         init_module_fn static_init[] = { STATIC_service_MODULES };
191         init_module_fn *shared_init;
192         struct event_context *event_ctx;
193         NTSTATUS status;
194         const char *model = "standard";
195         int max_runtime = 0;
196         enum {
197                 OPT_DAEMON = 1000,
198                 OPT_INTERACTIVE,
199                 OPT_PROCESS_MODEL
200         };
201         struct poptOption long_options[] = {
202                 POPT_AUTOHELP
203                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
204                  "Become a daemon (default)", NULL },
205                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
206                  "Run interactive (not a daemon)", NULL},
207                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
208                  "Select process model", "MODEL"},
209                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
210                  "set maximum runtime of the server process, till autotermination", "seconds"},
211                 POPT_COMMON_SAMBA
212                 POPT_COMMON_VERSION
213                 { NULL }
214         };
215
216         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
217         while((opt = poptGetNextOpt(pc)) != -1) {
218                 switch(opt) {
219                 case OPT_DAEMON:
220                         opt_daemon = true;
221                         break;
222                 case OPT_INTERACTIVE:
223                         opt_interactive = true;
224                         break;
225                 case OPT_PROCESS_MODEL:
226                         model = poptGetOptArg(pc);
227                         break;
228                 default:
229                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
230                                   poptBadOption(pc, 0), poptStrerror(opt));
231                         poptPrintUsage(pc, stderr, 0);
232                         exit(1);
233                 }
234         }
235
236         if (opt_daemon && opt_interactive) {
237                 fprintf(stderr,"\nERROR: "
238                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
239                 poptPrintUsage(pc, stderr, 0);
240                 exit(1);
241         } else if (!opt_interactive) {
242                 /* default is --daemon */
243                 opt_daemon = true;
244         }
245
246         poptFreeContext(pc);
247
248         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
249         setup_signals();
250
251         /* we want total control over the permissions on created files,
252            so set our umask to 0 */
253         umask(0);
254
255         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
256         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n"));
257
258         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
259                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
260                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
261                             (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
262                 exit(1);
263         }
264
265         if (opt_daemon) {
266                 DEBUG(3,("Becoming a daemon.\n"));
267                 become_daemon(true);
268         }
269
270         cleanup_tmp_files(cmdline_lp_ctx);
271
272         if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
273                 mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
274         }
275
276         pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
277
278         /* Do *not* remove this, until you have removed
279          * passdb/secrets.c, and proved that Samba still builds... */
280         /* Setup the SECRETS subsystem */
281         if (!secrets_init(cmdline_lp_ctx)) {
282                 exit(1);
283         }
284
285         gensec_init(cmdline_lp_ctx); /* FIXME: */
286
287         ntptr_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization function 
288                                                 of the spoolss RPC server instead? */
289
290         ntvfs_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization functions 
291                                                 of the SMB[,2] server instead? */
292
293         process_model_init(cmdline_lp_ctx); 
294
295         shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
296
297         run_init_functions(static_init);
298         run_init_functions(shared_init);
299
300         talloc_free(shared_init);
301         
302         /* the event context is the top level structure in smbd. Everything else
303            should hang off that */
304         event_ctx = event_context_init(talloc_autofree_context());
305
306         if (event_ctx == NULL) {
307                 DEBUG(0,("Initializing event context failed\n"));
308                 return 1;
309         }
310
311         /* initialise clustering if needed */
312         cluster_ctdb_init(cmdline_lp_ctx, 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, cmdline_lp_ctx, model, 
334                                         lp_server_services(cmdline_lp_ctx));
335         if (!NT_STATUS_IS_OK(status)) {
336                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
337                 return 1;
338         }
339
340         /* wait for events - this is where smbd sits for most of its
341            life */
342         event_loop_wait(event_ctx);
343
344         /* as everything hangs off this event context, freeing it
345            should initiate a clean shutdown of all services */
346         talloc_free(event_ctx);
347
348         return 0;
349 }
350
351  int main(int argc, const char *argv[])
352 {
353         return binary_smbd_main("smbd", argc, argv);
354 }