s4:schannel merge code with s3
[ira/wip.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 receive 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 key databases. This saves a lot of time in child
185   processes
186  */
187 static void prime_ldb_databases(struct tevent_context *event_ctx)
188 {
189         TALLOC_CTX *db_context;
190         db_context = talloc_new(event_ctx);
191
192         samdb_connect(db_context, event_ctx, cmdline_lp_ctx, system_session(cmdline_lp_ctx));
193         privilege_connect(db_context, event_ctx, cmdline_lp_ctx);
194
195         /* we deliberately leave these open, which allows them to be
196          * re-used in ldb_wrap_connect() */
197 }
198
199
200 /*
201   called when a fatal condition occurs in a child task
202  */
203 static NTSTATUS samba_terminate(struct irpc_message *msg, 
204                                 struct samba_terminate *r)
205 {
206         DEBUG(0,("samba_terminate: %s\n", r->in.reason));
207         exit(1);
208 }
209
210 /*
211   setup messaging for the top level samba (parent) task
212  */
213 static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, 
214                                        struct loadparm_context *lp_ctx)
215 {
216         struct messaging_context *msg;
217         NTSTATUS status;
218
219         msg = messaging_init(talloc_autofree_context(), 
220                              lp_messaging_path(event_ctx, lp_ctx),
221                              cluster_id(0, SAMBA_PARENT_TASKID),
222                              lp_iconv_convenience(lp_ctx),
223                              event_ctx);
224         NT_STATUS_HAVE_NO_MEMORY(msg);
225
226         irpc_add_name(msg, "samba");
227
228         status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
229                                samba_terminate, NULL);
230
231         return status;
232 }
233
234
235
236 /*
237  main server.
238 */
239 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
240 {
241         bool opt_daemon = false;
242         bool opt_interactive = false;
243         int opt;
244         poptContext pc;
245         extern NTSTATUS server_service_wrepl_init(void);
246         extern NTSTATUS server_service_kdc_init(void);
247         extern NTSTATUS server_service_ldap_init(void);
248         extern NTSTATUS server_service_web_init(void);
249         extern NTSTATUS server_service_ldap_init(void);
250         extern NTSTATUS server_service_winbind_init(void);
251         extern NTSTATUS server_service_nbtd_init(void);
252         extern NTSTATUS server_service_auth_init(void);
253         extern NTSTATUS server_service_cldapd_init(void);
254         extern NTSTATUS server_service_smb_init(void);
255         extern NTSTATUS server_service_drepl_init(void);
256         extern NTSTATUS server_service_kcc_init(void);
257         extern NTSTATUS server_service_dnsupdate_init(void);
258         extern NTSTATUS server_service_rpc_init(void);
259         extern NTSTATUS server_service_ntp_signd_init(void);
260         extern NTSTATUS server_service_samba3_smb_init(void);
261         init_module_fn static_init[] = { STATIC_service_MODULES };
262         init_module_fn *shared_init;
263         struct tevent_context *event_ctx;
264         uint16_t stdin_event_flags;
265         NTSTATUS status;
266         const char *model = "standard";
267         int max_runtime = 0;
268         enum {
269                 OPT_DAEMON = 1000,
270                 OPT_INTERACTIVE,
271                 OPT_PROCESS_MODEL
272         };
273         struct poptOption long_options[] = {
274                 POPT_AUTOHELP
275                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
276                  "Become a daemon (default)", NULL },
277                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
278                  "Run interactive (not a daemon)", NULL},
279                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
280                  "Select process model", "MODEL"},
281                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
282                  "set maximum runtime of the server process, till autotermination", "seconds"},
283                 POPT_COMMON_SAMBA
284                 POPT_COMMON_VERSION
285                 { NULL }
286         };
287
288         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
289         while((opt = poptGetNextOpt(pc)) != -1) {
290                 switch(opt) {
291                 case OPT_DAEMON:
292                         opt_daemon = true;
293                         break;
294                 case OPT_INTERACTIVE:
295                         opt_interactive = true;
296                         break;
297                 case OPT_PROCESS_MODEL:
298                         model = poptGetOptArg(pc);
299                         break;
300                 default:
301                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
302                                   poptBadOption(pc, 0), poptStrerror(opt));
303                         poptPrintUsage(pc, stderr, 0);
304                         return 1;
305                 }
306         }
307
308         if (opt_daemon && opt_interactive) {
309                 fprintf(stderr,"\nERROR: "
310                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
311                 poptPrintUsage(pc, stderr, 0);
312                 return 1;
313         } else if (!opt_interactive) {
314                 /* default is --daemon */
315                 opt_daemon = true;
316         }
317
318         poptFreeContext(pc);
319
320         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
321         setup_signals();
322
323         /* we want total control over the permissions on created files,
324            so set our umask to 0 */
325         umask(0);
326
327         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
328         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2010\n"));
329
330         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
331                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
332                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
333                             (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
334                 return 1;
335         }
336
337         if (opt_daemon) {
338                 DEBUG(3,("Becoming a daemon.\n"));
339                 become_daemon(true, false);
340         }
341
342         cleanup_tmp_files(cmdline_lp_ctx);
343
344         if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
345                 mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
346         }
347
348         pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
349
350         /* Do *not* remove this, until you have removed
351          * passdb/secrets.c, and proved that Samba still builds... */
352         /* Setup the SECRETS subsystem */
353         if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) {
354                 return 1;
355         }
356
357         gensec_init(cmdline_lp_ctx); /* FIXME: */
358
359         ntptr_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization function 
360                                                 of the spoolss RPC server instead? */
361
362         ntvfs_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization functions 
363                                                 of the SMB[,2] server instead? */
364
365         process_model_init(cmdline_lp_ctx); 
366
367         shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
368
369         run_init_functions(static_init);
370         run_init_functions(shared_init);
371
372         talloc_free(shared_init);
373         
374         /* the event context is the top level structure in smbd. Everything else
375            should hang off that */
376         event_ctx = s4_event_context_init(talloc_autofree_context());
377
378         /* setup this as the default context */
379         s4_event_context_set_default(event_ctx);
380
381         if (event_ctx == NULL) {
382                 DEBUG(0,("Initializing event context failed\n"));
383                 return 1;
384         }
385
386         if (opt_interactive) {
387                 /* terminate when stdin goes away */
388                 stdin_event_flags = TEVENT_FD_READ;
389         } else {
390                 /* stay alive forever */
391                 stdin_event_flags = 0;
392         }
393
394         /* catch EOF on stdin */
395 #ifdef SIGTTIN
396         signal(SIGTTIN, SIG_IGN);
397 #endif
398         tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
399                       server_stdin_handler,
400                       discard_const(binary_name));
401
402         if (max_runtime) {
403                 tevent_add_timer(event_ctx, event_ctx,
404                                  timeval_current_ofs(max_runtime, 0),
405                                  max_runtime_handler,
406                                  discard_const(binary_name));
407         }
408
409         prime_ldb_databases(event_ctx);
410
411         status = setup_parent_messaging(event_ctx, cmdline_lp_ctx);
412         if (!NT_STATUS_IS_OK(status)) {
413                 DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status)));
414                 return 1;
415         }
416
417         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
418
419         status = server_service_startup(event_ctx, cmdline_lp_ctx, model, 
420                                         lp_server_services(cmdline_lp_ctx));
421         if (!NT_STATUS_IS_OK(status)) {
422                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
423                 return 1;
424         }
425
426         /* wait for events - this is where smbd sits for most of its
427            life */
428         tevent_loop_wait(event_ctx);
429
430         /* as everything hangs off this event context, freeing it
431            should initiate a clean shutdown of all services */
432         talloc_free(event_ctx);
433
434         return 0;
435 }
436
437 int main(int argc, const char *argv[])
438 {
439         return binary_smbd_main("samba", argc, argv);
440 }