2 Unix SMB/CIFS implementation.
4 Main SMB server routines
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>
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.
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.
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/>.
26 #include "lib/events/events.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "system/dir.h"
30 #include "system/filesys.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"
45 recursively delete a directory tree
47 static void recursive_delete(const char *path)
57 for (de=readdir(dir);de;de=readdir(dir)) {
61 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) {
65 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
66 if (stat(fname, &st) != 0) {
69 if (S_ISDIR(st.st_mode)) {
70 recursive_delete(fname);
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");
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.
91 static void cleanup_tmp_files(struct loadparm_context *lp_ctx)
94 TALLOC_CTX *mem_ctx = talloc_new(NULL);
96 path = smbd_tmp_path(mem_ctx, lp_ctx, NULL);
98 recursive_delete(path);
102 static void sig_hup(int sig)
104 debug_schedule_reopen_logs();
107 static void sig_term(int sig)
110 static int done_sigterm;
111 if (done_sigterm == 0 && getpgrp() == getpid()) {
112 DEBUG(0,("SIGTERM: killing children\n"));
114 kill(-getpgrp(), SIGTERM);
123 static void setup_signals(void)
125 /* we are never interested in SIGPIPE */
126 BlockSignals(true,SIGPIPE);
129 /* we are never interested in SIGFPE */
130 BlockSignals(true,SIGFPE);
133 /* We are no longer interested in USR1 */
134 BlockSignals(true, SIGUSR1);
137 /* We are no longer interested in USR2 */
138 BlockSignals(true,SIGUSR2);
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);
146 CatchSignal(SIGHUP, sig_hup);
147 CatchSignal(SIGTERM, sig_term);
153 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde,
154 uint16_t flags, void *private)
156 const char *binary_name = (const char *)private;
158 if (read(0, &c, 1) == 0) {
159 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
161 if (getpgrp() == getpid()) {
162 kill(-getpgrp(), SIGTERM);
170 die if the user selected maximum runtime is exceeded
172 _NORETURN_ static void max_runtime_handler(struct event_context *ev,
173 struct timed_event *te,
174 struct timeval t, void *private)
176 const char *binary_name = (const char *)private;
177 DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
184 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
186 bool opt_daemon = false;
187 bool opt_interactive = false;
190 extern NTSTATUS server_service_wrepl_init(void);
191 extern NTSTATUS server_service_kdc_init(void);
192 extern NTSTATUS server_service_ldap_init(void);
193 extern NTSTATUS server_service_web_init(void);
194 extern NTSTATUS server_service_ldap_init(void);
195 extern NTSTATUS server_service_winbind_init(void);
196 extern NTSTATUS server_service_nbtd_init(void);
197 extern NTSTATUS server_service_auth_init(void);
198 extern NTSTATUS server_service_cldapd_init(void);
199 extern NTSTATUS server_service_smb_init(void);
200 extern NTSTATUS server_service_drepl_init(void);
201 extern NTSTATUS server_service_rpc_init(void);
202 init_module_fn static_init[] = { STATIC_service_MODULES };
203 init_module_fn *shared_init;
204 struct event_context *event_ctx;
206 const char *model = "standard";
213 struct poptOption long_options[] = {
215 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
216 "Become a daemon (default)", NULL },
217 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
218 "Run interactive (not a daemon)", NULL},
219 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL,
220 "Select process model", "MODEL"},
221 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0,
222 "set maximum runtime of the server process, till autotermination", "seconds"},
228 pc = poptGetContext(binary_name, argc, argv, long_options, 0);
229 while((opt = poptGetNextOpt(pc)) != -1) {
234 case OPT_INTERACTIVE:
235 opt_interactive = true;
237 case OPT_PROCESS_MODEL:
238 model = poptGetOptArg(pc);
241 fprintf(stderr, "\nInvalid option %s: %s\n\n",
242 poptBadOption(pc, 0), poptStrerror(opt));
243 poptPrintUsage(pc, stderr, 0);
248 if (opt_daemon && opt_interactive) {
249 fprintf(stderr,"\nERROR: "
250 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
251 poptPrintUsage(pc, stderr, 0);
253 } else if (!opt_interactive) {
254 /* default is --daemon */
260 setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
263 /* we want total control over the permissions on created files,
264 so set our umask to 0 */
267 DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
268 DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n"));
270 if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
271 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
272 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
273 (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
278 DEBUG(3,("Becoming a daemon.\n"));
282 cleanup_tmp_files(cmdline_lp_ctx);
284 if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
285 mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
288 pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
290 /* Do *not* remove this, until you have removed
291 * passdb/secrets.c, and proved that Samba still builds... */
292 /* Setup the SECRETS subsystem */
293 if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) {
297 gensec_init(cmdline_lp_ctx); /* FIXME: */
299 ntptr_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization function
300 of the spoolss RPC server instead? */
302 ntvfs_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization functions
303 of the SMB[,2] server instead? */
305 process_model_init(cmdline_lp_ctx);
307 shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
309 run_init_functions(static_init);
310 run_init_functions(shared_init);
312 talloc_free(shared_init);
314 /* the event context is the top level structure in smbd. Everything else
315 should hang off that */
316 event_ctx = event_context_init(talloc_autofree_context());
318 if (event_ctx == NULL) {
319 DEBUG(0,("Initializing event context failed\n"));
323 /* initialise clustering if needed */
324 cluster_ctdb_init(cmdline_lp_ctx, event_ctx, model);
326 if (opt_interactive) {
327 /* catch EOF on stdin */
329 signal(SIGTTIN, SIG_IGN);
331 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ,
332 server_stdin_handler,
333 discard_const(binary_name));
338 event_add_timed(event_ctx, event_ctx,
339 timeval_current_ofs(max_runtime, 0),
341 discard_const(binary_name));
344 DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
345 status = server_service_startup(event_ctx, cmdline_lp_ctx, model,
346 lp_server_services(cmdline_lp_ctx));
347 if (!NT_STATUS_IS_OK(status)) {
348 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
352 /* wait for events - this is where smbd sits for most of its
354 event_loop_wait(event_ctx);
356 /* as everything hangs off this event context, freeing it
357 should initiate a clean shutdown of all services */
358 talloc_free(event_ctx);
363 int main(int argc, const char *argv[])
365 return binary_smbd_main("smbd", argc, argv);