r13996: simplify ldb_async_wait() some more
[ira/wip.git] / source / 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 "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 "passdb/secrets.h"
40 #include "util/pidfile.h"
41
42 /*
43   recursively delete a directory tree
44 */
45 static void recursive_delete(const char *path)
46 {
47         DIR *dir;
48         struct dirent *de;
49
50         dir = opendir(path);
51         if (!dir) {
52                 return;
53         }
54
55         for (de=readdir(dir);de;de=readdir(dir)) {
56                 char *fname;
57                 struct stat st;
58
59                 if (strcmp(de->d_name, ".") == 0 ||
60                     strcmp(de->d_name, "..") == 0) {
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 /*
102   setup signal masks
103 */
104 static void setup_signals(void)
105 {
106         /* we are never interested in SIGPIPE */
107         BlockSignals(True,SIGPIPE);
108
109 #if defined(SIGFPE)
110         /* we are never interested in SIGFPE */
111         BlockSignals(True,SIGFPE);
112 #endif
113
114         /* We are no longer interested in USR1 */
115         BlockSignals(True, SIGUSR1);
116
117 #if defined(SIGUSR2)
118         /* We are no longer interested in USR2 */
119         BlockSignals(True,SIGUSR2);
120 #endif
121
122         /* POSIX demands that signals are inherited. If the invoking process has
123          * these signals masked, we will have problems, as we won't recieve them. */
124         BlockSignals(False, SIGHUP);
125         BlockSignals(False, SIGTERM);
126
127         /* as we don't handle on this signals yet, we need to ignore them,
128          * instead of terminating */
129         CatchSignal(SIGHUP, SIG_IGN);
130 }
131
132 /*
133   handle io on stdin
134 */
135 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
136                                  uint16_t flags, void *private)
137 {
138         const char *binary_name = private;
139         uint8_t c;
140         if (read(0, &c, 1) == 0) {
141                 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
142                 exit(0);
143         }
144 }
145
146 /*
147   die if the user selected maximum runtime is exceeded
148 */
149 static void max_runtime_handler(struct event_context *ev, struct timed_event *te, 
150                                 struct timeval t, void *private)
151 {
152         const char *binary_name = private;
153         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
154         exit(0);
155 }
156
157 /*
158  main server.
159 */
160 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
161 {
162         BOOL interactive = False;
163         int opt;
164         poptContext pc;
165         init_module_fn static_init[] = STATIC_SERVER_SERVICE_MODULES;
166         init_module_fn *shared_init;
167         struct event_context *event_ctx;
168         NTSTATUS status;
169         const char *model = "standard";
170         int max_runtime = 0;
171         struct poptOption long_options[] = {
172                 POPT_AUTOHELP
173                 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
174                  "Run interactive (not a daemon)", NULL},
175                 {"model", 'M', POPT_ARG_STRING, &model, True, 
176                  "Select process model", "MODEL"},
177                 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, True, 
178                  "set maximum runtime of the server process, till autotermination", "seconds"},
179                 POPT_COMMON_SAMBA
180                 POPT_COMMON_VERSION
181                 POPT_TABLEEND
182         };
183
184         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
185         
186         while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
187
188         poptFreeContext(pc);
189
190         setup_logging(binary_name, interactive?DEBUG_STDOUT:DEBUG_FILE);
191         setup_signals();
192
193         /* we want total control over the permissions on created files,
194            so set our umask to 0 */
195         umask(0);
196
197         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
198         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2006\n"));
199
200         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
201                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
202                 exit(1);
203         }
204
205         if (!interactive) {
206                 DEBUG(3,("Becoming a daemon.\n"));
207                 become_daemon(True);
208         }
209
210         cleanup_tmp_files();
211
212         if (!directory_exist(lp_lockdir())) {
213                 mkdir(lp_lockdir(), 0755);
214         }
215
216         pidfile_create(binary_name);
217
218         /* Do *not* remove this, until you have removed
219          * passdb/secrets.c, and proved that Samba still builds... */
220         /* Setup the SECRETS subsystem */
221         if (!secrets_init()) {
222                 exit(1);
223         }
224
225         gensec_init();
226
227         registry_init(); /* FIXME: maybe run this in the initialization function 
228                                                 of the winreg RPC server instead? */
229
230         ntptr_init();   /* FIXME: maybe run this in the initialization function 
231                                                 of the spoolss RPC server instead? */
232
233         ntvfs_init();   /* FIXME: maybe run this in the initialization functions 
234                                                 of the SMB[,2] server instead? */
235
236         process_model_init(); 
237
238         shared_init = load_samba_modules(NULL, "service");
239
240         run_init_functions(static_init);
241         run_init_functions(shared_init);
242
243         talloc_free(shared_init);
244         
245         /* the event context is the top level structure in smbd. Everything else
246            should hang off that */
247         event_ctx = event_context_init(NULL);
248
249         if (interactive) {
250                 /* catch EOF on stdin */
251 #ifdef SIGTTIN
252                 signal(SIGTTIN, SIG_IGN);
253 #endif
254                 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ, 
255                              server_stdin_handler,
256                              discard_const(binary_name));
257         }
258
259
260         if (max_runtime) {
261                 event_add_timed(event_ctx, event_ctx, 
262                                 timeval_current_ofs(max_runtime, 0), 
263                                 max_runtime_handler,
264                                 discard_const(binary_name));
265         }
266
267         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
268         status = server_service_startup(event_ctx, model, lp_server_services());
269         if (!NT_STATUS_IS_OK(status)) {
270                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
271                 return 1;
272         }
273
274         /* wait for events - this is where smbd sits for most of its
275            life */
276         event_loop_wait(event_ctx);
277
278         /* as everything hangs off this event context, freeing it
279            should initiate a clean shutdown of all services */
280         talloc_free(event_ctx);
281
282         return 0;
283 }
284
285  int main(int argc, const char *argv[])
286 {
287         return binary_smbd_main("smbd", argc, argv);
288 }