r17206: Add a modular API for share configuration.
[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 2 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, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27 #include "lib/events/events.h"
28 #include "version.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "system/dir.h"
31 #include "system/filesys.h"
32 #include "build.h"
33 #include "ldb/include/ldb.h"
34 #include "registry/registry.h"
35 #include "ntvfs/ntvfs.h"
36 #include "ntptr/ntptr.h"
37 #include "auth/gensec/gensec.h"
38 #include "smbd/process_model.h"
39 #include "smbd/service.h"
40 #include "passdb/secrets.h"
41 #include "lib/util/pidfile.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 /*
107   setup signal masks
108 */
109 static void setup_signals(void)
110 {
111         /* we are never interested in SIGPIPE */
112         BlockSignals(True,SIGPIPE);
113
114 #if defined(SIGFPE)
115         /* we are never interested in SIGFPE */
116         BlockSignals(True,SIGFPE);
117 #endif
118
119         /* We are no longer interested in USR1 */
120         BlockSignals(True, SIGUSR1);
121
122 #if defined(SIGUSR2)
123         /* We are no longer interested in USR2 */
124         BlockSignals(True,SIGUSR2);
125 #endif
126
127         /* POSIX demands that signals are inherited. If the invoking process has
128          * these signals masked, we will have problems, as we won't recieve them. */
129         BlockSignals(False, SIGHUP);
130         BlockSignals(False, SIGTERM);
131
132         CatchSignal(SIGHUP, sig_hup);
133 }
134
135 /*
136   handle io on stdin
137 */
138 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
139                                  uint16_t flags, void *private)
140 {
141         const char *binary_name = private;
142         uint8_t c;
143         if (read(0, &c, 1) == 0) {
144                 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
145                 exit(0);
146         }
147 }
148
149 /*
150   die if the user selected maximum runtime is exceeded
151 */
152 static void max_runtime_handler(struct event_context *ev, struct timed_event *te, 
153                                 struct timeval t, void *private)
154 {
155         const char *binary_name = private;
156         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
157         exit(0);
158 }
159
160 /*
161  main server.
162 */
163 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
164 {
165         BOOL interactive = False;
166         int opt;
167         poptContext pc;
168         init_module_fn static_init[] = STATIC_service_MODULES;
169         init_module_fn *shared_init;
170         struct event_context *event_ctx;
171         NTSTATUS status;
172         const char *model = "standard";
173         int max_runtime = 0;
174         enum {
175                 OPT_INTERACTIVE         = 1000,
176                 OPT_PROCESS_MODEL
177         };
178         struct poptOption long_options[] = {
179                 POPT_AUTOHELP
180                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
181                  "Run interactive (not a daemon)", NULL},
182                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
183                  "Select process model", "MODEL"},
184                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
185                  "set maximum runtime of the server process, till autotermination", "seconds"},
186                 POPT_COMMON_SAMBA
187                 POPT_COMMON_VERSION
188                 POPT_TABLEEND
189         };
190
191         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
192         
193         while((opt = poptGetNextOpt(pc)) != -1) {
194                 switch(opt) {
195                 case OPT_INTERACTIVE:
196                         interactive = True;
197                         break;
198                 case OPT_PROCESS_MODEL:
199                         model = poptGetOptArg(pc);
200                         break;
201                 }
202         }
203         poptFreeContext(pc);
204
205         setup_logging(binary_name, interactive?DEBUG_STDOUT:DEBUG_FILE);
206         setup_signals();
207
208         /* we want total control over the permissions on created files,
209            so set our umask to 0 */
210         umask(0);
211
212         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
213         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2006\n"));
214
215         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
216                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
217                 exit(1);
218         }
219
220         if (!interactive) {
221                 DEBUG(3,("Becoming a daemon.\n"));
222                 become_daemon(True);
223         }
224
225         cleanup_tmp_files();
226
227         if (!directory_exist(lp_lockdir())) {
228                 mkdir(lp_lockdir(), 0755);
229         }
230
231         pidfile_create(binary_name);
232
233         /* Do *not* remove this, until you have removed
234          * passdb/secrets.c, and proved that Samba still builds... */
235         /* Setup the SECRETS subsystem */
236         if (!secrets_init()) {
237                 exit(1);
238         }
239
240         ldb_global_init(); /* FIXME: */
241
242         share_init();
243
244         gensec_init(); /* FIXME: */
245
246         registry_init(); /* FIXME: maybe run this in the initialization function 
247                                                 of the winreg RPC server instead? */
248
249         ntptr_init();   /* FIXME: maybe run this in the initialization function 
250                                                 of the spoolss RPC server instead? */
251
252         ntvfs_init();   /* FIXME: maybe run this in the initialization functions 
253                                                 of the SMB[,2] server instead? */
254
255         process_model_init(); 
256
257         shared_init = load_samba_modules(NULL, "service");
258
259         run_init_functions(static_init);
260         run_init_functions(shared_init);
261
262         talloc_free(shared_init);
263         
264         /* the event context is the top level structure in smbd. Everything else
265            should hang off that */
266         event_ctx = event_context_init(NULL);
267
268         if (interactive) {
269                 /* catch EOF on stdin */
270 #ifdef SIGTTIN
271                 signal(SIGTTIN, SIG_IGN);
272 #endif
273                 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ, 
274                              server_stdin_handler,
275                              discard_const(binary_name));
276         }
277
278
279         if (max_runtime) {
280                 event_add_timed(event_ctx, event_ctx, 
281                                 timeval_current_ofs(max_runtime, 0), 
282                                 max_runtime_handler,
283                                 discard_const(binary_name));
284         }
285
286         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
287         status = server_service_startup(event_ctx, model, lp_server_services());
288         if (!NT_STATUS_IS_OK(status)) {
289                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
290                 return 1;
291         }
292
293         /* wait for events - this is where smbd sits for most of its
294            life */
295         event_loop_wait(event_ctx);
296
297         /* as everything hangs off this event context, freeing it
298            should initiate a clean shutdown of all services */
299         talloc_free(event_ctx);
300
301         return 0;
302 }
303
304  int main(int argc, const char *argv[])
305 {
306         return binary_smbd_main("smbd", argc, argv);
307 }