s4:samba: Allow samba daemon to run in foreground
[garming/samba-autobuild/.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 "auth/gensec/gensec.h"
32 #include "libcli/auth/schannel.h"
33 #include "smbd/process_model.h"
34 #include "param/secrets.h"
35 #include "lib/util/pidfile.h"
36 #include "param/param.h"
37 #include "dsdb/samdb/samdb.h"
38 #include "auth/session.h"
39 #include "lib/messaging/irpc.h"
40 #include "librpc/gen_ndr/ndr_irpc.h"
41 #include "cluster/cluster.h"
42 #include "dynconfig/dynconfig.h"
43 #include "lib/util/samba_modules.h"
44 #include "nsswitch/winbind_client.h"
45 #include "libds/common/roles.h"
46 #include "lib/util/tfork.h"
47
48 #ifdef HAVE_PTHREAD
49 #include <pthread.h>
50 #endif
51
52 struct server_state {
53         struct tevent_context *event_ctx;
54         const char *binary_name;
55 };
56
57 /*
58   recursively delete a directory tree
59 */
60 static void recursive_delete(const char *path)
61 {
62         DIR *dir;
63         struct dirent *de;
64
65         dir = opendir(path);
66         if (!dir) {
67                 return;
68         }
69
70         for (de=readdir(dir);de;de=readdir(dir)) {
71                 char *fname;
72                 struct stat st;
73
74                 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) {
75                         continue;
76                 }
77
78                 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
79                 if (stat(fname, &st) != 0) {
80                         continue;
81                 }
82                 if (S_ISDIR(st.st_mode)) {
83                         recursive_delete(fname);
84                         talloc_free(fname);
85                         continue;
86                 }
87                 if (unlink(fname) != 0) {
88                         DBG_ERR("Unabled to delete '%s' - %s\n",
89                                  fname, strerror(errno));
90                         smb_panic("unable to cleanup tmp files");
91                 }
92                 talloc_free(fname);
93         }
94         closedir(dir);
95 }
96
97 /*
98   cleanup temporary files. This is the new alternative to
99   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
100   efficient on unix systems due to the lack of scaling of the byte
101   range locking system. So instead of putting the burden on tdb to
102   cleanup tmp files, this function deletes them.
103 */
104 static void cleanup_tmp_files(struct loadparm_context *lp_ctx)
105 {
106         char *path;
107         TALLOC_CTX *mem_ctx = talloc_new(NULL);
108         if (mem_ctx == NULL) {
109                 exit_daemon("Failed to create memory context",
110                             ENOMEM);
111         }
112
113         path = smbd_tmp_path(mem_ctx, lp_ctx, NULL);
114         if (path == NULL) {
115                 exit_daemon("Failed to cleanup temporary files",
116                             EINVAL);
117         }
118
119         recursive_delete(path);
120         talloc_free(mem_ctx);
121 }
122
123 static void sig_hup(int sig)
124 {
125         debug_schedule_reopen_logs();
126 }
127
128 static void sig_term(int sig)
129 {
130 #if HAVE_GETPGRP
131         if (getpgrp() == getpid()) {
132                 /*
133                  * We're the process group leader, send
134                  * SIGTERM to our process group.
135                  */
136                 DBG_ERR("SIGTERM: killing children\n");
137                 kill(-getpgrp(), SIGTERM);
138         }
139 #endif
140         DBG_ERR("Exiting pid %d on SIGTERM\n", (int)getpid());
141         exit(127);
142 }
143
144 static void sigterm_signal_handler(struct tevent_context *ev,
145                                 struct tevent_signal *se,
146                                 int signum, int count, void *siginfo,
147                                 void *private_data)
148 {
149         struct server_state *state = talloc_get_type_abort(
150                 private_data, struct server_state);
151
152         DBG_DEBUG("Process %s got SIGTERM\n", state->binary_name);
153         TALLOC_FREE(state);
154         sig_term(SIGTERM);
155 }
156
157 /*
158   setup signal masks
159 */
160 static void setup_signals(void)
161 {
162         /* we are never interested in SIGPIPE */
163         BlockSignals(true,SIGPIPE);
164
165 #if defined(SIGFPE)
166         /* we are never interested in SIGFPE */
167         BlockSignals(true,SIGFPE);
168 #endif
169
170         /* We are no longer interested in USR1 */
171         BlockSignals(true, SIGUSR1);
172
173 #if defined(SIGUSR2)
174         /* We are no longer interested in USR2 */
175         BlockSignals(true,SIGUSR2);
176 #endif
177
178         /* POSIX demands that signals are inherited. If the invoking process has
179          * these signals masked, we will have problems,
180          * as we won't receive them. */
181         BlockSignals(false, SIGHUP);
182         BlockSignals(false, SIGTERM);
183
184         CatchSignal(SIGHUP, sig_hup);
185         CatchSignal(SIGTERM, sig_term);
186 }
187
188 /*
189   handle io on stdin
190 */
191 static void server_stdin_handler(struct tevent_context *event_ctx,
192                                 struct tevent_fd *fde,
193                                 uint16_t flags,
194                                 void *private_data)
195 {
196         struct server_state *state = talloc_get_type_abort(
197                 private_data, struct server_state);
198         uint8_t c;
199         if (read(0, &c, 1) == 0) {
200                 DBG_ERR("%s: EOF on stdin - PID %d terminating\n",
201                         state->binary_name, (int)getpid());
202 #if HAVE_GETPGRP
203                 if (getpgrp() == getpid()) {
204                         DBG_ERR("Sending SIGTERM from pid %d\n",
205                                 (int)getpid());
206                         kill(-getpgrp(), SIGTERM);
207                 }
208 #endif
209                 TALLOC_FREE(state);
210                 exit(0);
211         }
212 }
213
214 /*
215   die if the user selected maximum runtime is exceeded
216 */
217 _NORETURN_ static void max_runtime_handler(struct tevent_context *ev,
218                                            struct tevent_timer *te,
219                                            struct timeval t, void *private_data)
220 {
221         struct server_state *state = talloc_get_type_abort(
222                 private_data, struct server_state);
223         DBG_ERR("%s: maximum runtime exceeded - "
224                 "terminating PID %d at %llu, current ts: %llu\n",
225                  state->binary_name,
226                 (int)getpid(),
227                 (unsigned long long)t.tv_sec,
228                 (unsigned long long)time(NULL));
229         TALLOC_FREE(state);
230         exit(0);
231 }
232
233 /*
234   pre-open the key databases. This saves a lot of time in child
235   processes
236  */
237 static void prime_ldb_databases(struct tevent_context *event_ctx)
238 {
239         TALLOC_CTX *db_context;
240         db_context = talloc_new(event_ctx);
241
242         samdb_connect(db_context,
243                         event_ctx,
244                         cmdline_lp_ctx,
245                         system_session(cmdline_lp_ctx),
246                         0);
247         privilege_connect(db_context, cmdline_lp_ctx);
248
249         /* we deliberately leave these open, which allows them to be
250          * re-used in ldb_wrap_connect() */
251 }
252
253
254 /*
255   called when a fatal condition occurs in a child task
256  */
257 static NTSTATUS samba_terminate(struct irpc_message *msg,
258                                 struct samba_terminate *r)
259 {
260         struct server_state *state = talloc_get_type(msg->private_data,
261                                         struct server_state);
262         DBG_ERR("samba_terminate of %s %d: %s\n",
263                 state->binary_name, (int)getpid(), r->in.reason);
264         TALLOC_FREE(state);
265         exit(1);
266 }
267
268 /*
269   setup messaging for the top level samba (parent) task
270  */
271 static NTSTATUS setup_parent_messaging(struct server_state *state,
272                                        struct loadparm_context *lp_ctx)
273 {
274         struct imessaging_context *msg;
275         NTSTATUS status;
276
277         msg = imessaging_init(state->event_ctx,
278                               lp_ctx,
279                               cluster_id(0, SAMBA_PARENT_TASKID),
280                               state->event_ctx);
281         NT_STATUS_HAVE_NO_MEMORY(msg);
282
283         status = irpc_add_name(msg, "samba");
284         if (!NT_STATUS_IS_OK(status)) {
285                 return status;
286         }
287
288         status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
289                                samba_terminate, state);
290
291         return status;
292 }
293
294
295 /*
296   show build info
297  */
298 static void show_build(void)
299 {
300 #define CONFIG_OPTION(n) { #n, dyn_ ## n }
301         struct {
302                 const char *name;
303                 const char *value;
304         } config_options[] = {
305                 CONFIG_OPTION(BINDIR),
306                 CONFIG_OPTION(SBINDIR),
307                 CONFIG_OPTION(CONFIGFILE),
308                 CONFIG_OPTION(NCALRPCDIR),
309                 CONFIG_OPTION(LOGFILEBASE),
310                 CONFIG_OPTION(LMHOSTSFILE),
311                 CONFIG_OPTION(DATADIR),
312                 CONFIG_OPTION(MODULESDIR),
313                 CONFIG_OPTION(LOCKDIR),
314                 CONFIG_OPTION(STATEDIR),
315                 CONFIG_OPTION(CACHEDIR),
316                 CONFIG_OPTION(PIDDIR),
317                 CONFIG_OPTION(PRIVATE_DIR),
318                 CONFIG_OPTION(CODEPAGEDIR),
319                 CONFIG_OPTION(SETUPDIR),
320                 CONFIG_OPTION(WINBINDD_SOCKET_DIR),
321                 CONFIG_OPTION(NTP_SIGND_SOCKET_DIR),
322                 { NULL, NULL}
323         };
324         int i;
325
326         printf("Samba version: %s\n", SAMBA_VERSION_STRING);
327         printf("Build environment:\n");
328 #ifdef BUILD_SYSTEM
329         printf("   Build host:  %s\n", BUILD_SYSTEM);
330 #endif
331
332         printf("Paths:\n");
333         for (i=0; config_options[i].name; i++) {
334                 printf("   %s: %s\n",
335                         config_options[i].name,
336                         config_options[i].value);
337         }
338
339         exit(0);
340 }
341
342 static int event_ctx_destructor(struct tevent_context *event_ctx)
343 {
344         imessaging_dgm_unref_ev(event_ctx);
345         return 0;
346 }
347
348 #ifdef HAVE_PTHREAD
349 static int to_children_fd = -1;
350 static void atfork_prepare(void) {
351 }
352 static void atfork_parent(void) {
353 }
354 static void atfork_child(void) {
355         if (to_children_fd != -1) {
356                 close(to_children_fd);
357                 to_children_fd = -1;
358         }
359 }
360 #endif
361
362 /*
363  main server.
364 */
365 static int binary_smbd_main(const char *binary_name,
366                                 int argc,
367                                 const char *argv[])
368 {
369         bool opt_daemon = false;
370         bool opt_fork = true;
371         bool opt_interactive = false;
372         bool opt_no_process_group = false;
373         int opt;
374         poptContext pc;
375 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
376         STATIC_service_MODULES_PROTO;
377         init_module_fn static_init[] = { STATIC_service_MODULES };
378         init_module_fn *shared_init;
379         uint16_t stdin_event_flags;
380         NTSTATUS status;
381         const char *model = "standard";
382         int max_runtime = 0;
383         struct stat st;
384         enum {
385                 OPT_DAEMON = 1000,
386                 OPT_FOREGROUND,
387                 OPT_INTERACTIVE,
388                 OPT_PROCESS_MODEL,
389                 OPT_SHOW_BUILD,
390                 OPT_NO_PROCESS_GROUP,
391         };
392         struct poptOption long_options[] = {
393                 POPT_AUTOHELP
394                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
395                  "Become a daemon (default)", NULL },
396                 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FOREGROUND,
397                  "Run the daemon in foreground", NULL },
398                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
399                  "Run interactive (not a daemon)", NULL},
400                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL,
401                  "Select process model", "MODEL"},
402                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0,
403                  "set maximum runtime of the server process, "
404                         "till autotermination", "seconds"},
405                 {"show-build", 'b', POPT_ARG_NONE, NULL, OPT_SHOW_BUILD,
406                         "show build info", NULL },
407                 {"no-process-group", '\0', POPT_ARG_NONE, NULL,
408                   OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
409                 POPT_COMMON_SAMBA
410                 POPT_COMMON_VERSION
411                 { NULL }
412         };
413         struct server_state *state = NULL;
414         struct tevent_signal *se = NULL;
415
416         setproctitle("root process");
417
418         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
419         while((opt = poptGetNextOpt(pc)) != -1) {
420                 switch(opt) {
421                 case OPT_DAEMON:
422                         opt_daemon = true;
423                         break;
424                 case OPT_FOREGROUND:
425                         opt_fork = false;
426                         break;
427                 case OPT_INTERACTIVE:
428                         opt_interactive = true;
429                         break;
430                 case OPT_PROCESS_MODEL:
431                         model = poptGetOptArg(pc);
432                         break;
433                 case OPT_SHOW_BUILD:
434                         show_build();
435                         break;
436                 case OPT_NO_PROCESS_GROUP:
437                         opt_no_process_group = true;
438                         break;
439                 default:
440                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
441                                   poptBadOption(pc, 0), poptStrerror(opt));
442                         poptPrintUsage(pc, stderr, 0);
443                         return 1;
444                 }
445         }
446
447         if (opt_daemon && opt_interactive) {
448                 fprintf(stderr,"\nERROR: "
449                         "Option -i|--interactive is "
450                         "not allowed together with -D|--daemon\n\n");
451                 poptPrintUsage(pc, stderr, 0);
452                 return 1;
453         } else if (!opt_interactive && !opt_fork) {
454                 /* default is --daemon */
455                 opt_daemon = true;
456         }
457
458         poptFreeContext(pc);
459
460         talloc_enable_null_tracking();
461
462         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
463         setup_signals();
464
465         /* we want total control over the permissions on created files,
466            so set our umask to 0 */
467         umask(0);
468
469         DEBUG(0,("%s version %s started.\n",
470                 binary_name,
471                 SAMBA_VERSION_STRING));
472         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team"
473                 " 1992-2017\n"));
474
475         if (sizeof(uint16_t) < 2 ||
476                         sizeof(uint32_t) < 4 ||
477                         sizeof(uint64_t) < 8) {
478                 DEBUG(0,("ERROR: Samba is not configured correctly "
479                         "for the word size on your machine\n"));
480                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, "
481                         "sizeof(uint64_t) = %u\n",
482                         (unsigned int)sizeof(uint16_t),
483                         (unsigned int)sizeof(uint32_t),
484                         (unsigned int)sizeof(uint64_t)));
485                 return 1;
486         }
487
488         if (opt_daemon) {
489                 DBG_NOTICE("Becoming a daemon.\n");
490                 become_daemon(opt_fork, opt_no_process_group, false);
491         }
492
493         /* Create the memory context to hang everything off. */
494         state = talloc_zero(NULL, struct server_state);
495         if (state == NULL) {
496                 exit_daemon("Samba cannot create server state", ENOMEM);
497         };
498         state->binary_name = binary_name;
499
500         cleanup_tmp_files(cmdline_lp_ctx);
501
502         if (!directory_exist(lpcfg_lock_directory(cmdline_lp_ctx))) {
503                 mkdir(lpcfg_lock_directory(cmdline_lp_ctx), 0755);
504         }
505
506         pidfile_create(lpcfg_pid_directory(cmdline_lp_ctx), binary_name);
507
508         if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
509                 if (!open_schannel_session_store(state,
510                                 cmdline_lp_ctx)) {
511                         TALLOC_FREE(state);
512                         exit_daemon("Samba cannot open schannel store "
513                                 "for secured NETLOGON operations.", EACCES);
514                 }
515         }
516
517         /* make sure we won't go through nss_winbind */
518         if (!winbind_off()) {
519                 TALLOC_FREE(state);
520                 exit_daemon("Samba failed to disable recusive "
521                         "winbindd calls.", EACCES);
522         }
523
524         gensec_init(); /* FIXME: */
525
526         process_model_init(cmdline_lp_ctx);
527
528         shared_init = load_samba_modules(NULL, "service");
529
530         run_init_functions(NULL, static_init);
531         run_init_functions(NULL, shared_init);
532
533         talloc_free(shared_init);
534
535         /* the event context is the top level structure in smbd. Everything else
536            should hang off that */
537         state->event_ctx = s4_event_context_init(state);
538
539         if (state->event_ctx == NULL) {
540                 TALLOC_FREE(state);
541                 exit_daemon("Initializing event context failed", EACCES);
542         }
543
544         talloc_set_destructor(state->event_ctx, event_ctx_destructor);
545
546         if (opt_interactive) {
547                 /* terminate when stdin goes away */
548                 stdin_event_flags = TEVENT_FD_READ;
549         } else {
550                 /* stay alive forever */
551                 stdin_event_flags = 0;
552         }
553
554 #if HAVE_SETPGID
555         /*
556          * If we're interactive we want to set our own process group for
557          * signal management, unless --no-process-group specified.
558          */
559         if (opt_interactive && !opt_no_process_group)
560                 setpgid((pid_t)0, (pid_t)0);
561 #endif
562
563         /* catch EOF on stdin */
564 #ifdef SIGTTIN
565         signal(SIGTTIN, SIG_IGN);
566 #endif
567
568         if (fstat(0, &st) != 0) {
569                 TALLOC_FREE(state);
570                 exit_daemon("Samba failed to set standard input handler",
571                                 ENOTTY);
572         }
573
574         if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
575                 struct tevent_fd *fde = tevent_add_fd(state->event_ctx,
576                                 state->event_ctx,
577                                 0,
578                                 stdin_event_flags,
579                                 server_stdin_handler,
580                                 state);
581                 if (fde == NULL) {
582                         TALLOC_FREE(state);
583                         exit_daemon("Initializing stdin failed", ENOMEM);
584                 }
585         }
586
587         if (max_runtime) {
588                 struct tevent_timer *te;
589                 DBG_ERR("%s PID %d was called with maxruntime %d - "
590                         "current ts %llu\n",
591                         binary_name, (int)getpid(),
592                         max_runtime, (unsigned long long) time(NULL));
593                 te = tevent_add_timer(state->event_ctx, state->event_ctx,
594                                  timeval_current_ofs(max_runtime, 0),
595                                  max_runtime_handler,
596                                  state);
597                 if (te == NULL) {
598                         TALLOC_FREE(state);
599                         exit_daemon("Maxruntime handler failed", ENOMEM);
600                 }
601         }
602
603         se = tevent_add_signal(state->event_ctx,
604                                 state->event_ctx,
605                                 SIGTERM,
606                                 0,
607                                 sigterm_signal_handler,
608                                 state);
609         if (se == NULL) {
610                 TALLOC_FREE(state);
611                 exit_daemon("Initialize SIGTERM handler failed", ENOMEM);
612         }
613
614         if (lpcfg_server_role(cmdline_lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
615             && !lpcfg_parm_bool(cmdline_lp_ctx, NULL,
616                         "server role check", "inhibit", false)
617             && !str_list_check_ci(lpcfg_server_services(cmdline_lp_ctx), "smb")
618             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx),
619                         "remote")
620             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx),
621                         "mapiproxy")) {
622                 DEBUG(0, ("At this time the 'samba' binary should only be used "
623                         "for either:\n"));
624                 DEBUGADD(0, ("'server role = active directory domain "
625                         "controller' or to access the ntvfs file server "
626                         "with 'server services = +smb' or the rpc proxy "
627                         "with 'dcerpc endpoint servers = remote'\n"));
628                 DEBUGADD(0, ("You should start smbd/nmbd/winbindd instead for "
629                         "domain member and standalone file server tasks\n"));
630                 exit_daemon("Samba detected misconfigured 'server role' "
631                         "and exited. Check logs for details", EINVAL);
632         };
633
634         prime_ldb_databases(state->event_ctx);
635
636         status = setup_parent_messaging(state, cmdline_lp_ctx);
637         if (!NT_STATUS_IS_OK(status)) {
638                 TALLOC_FREE(state);
639                 exit_daemon("Samba failed to setup parent messaging",
640                         NT_STATUS_V(status));
641         }
642
643         DBG_ERR("%s: using '%s' process model\n", binary_name, model);
644
645         {
646                 int child_pipe[2];
647                 int rc;
648                 bool start_services = false;
649
650                 rc = pipe(child_pipe);
651                 if (rc < 0) {
652                         TALLOC_FREE(state);
653                         exit_daemon("Samba failed to open process control pipe",
654                                     errno);
655                 }
656                 smb_set_close_on_exec(child_pipe[0]);
657                 smb_set_close_on_exec(child_pipe[1]);
658
659 #ifdef HAVE_PTHREAD
660                 to_children_fd = child_pipe[1];
661                 pthread_atfork(atfork_prepare, atfork_parent,
662                                atfork_child);
663                 start_services = true;
664 #else
665                 pid_t pid;
666                 struct tfork *t = NULL;
667                 t = tfork_create();
668                 if (t == NULL) {
669                         exit_daemon(
670                                 "Samba unable to fork master process",
671                                 0);
672                 }
673                 pid = tfork_child_pid(t);
674                 if (pid == 0) {
675                         start_services = false;
676                 } else {
677                         /* In the child process */
678                         start_services = true;
679                         close(child_pipe[1]);
680                 }
681 #endif
682                 if (start_services) {
683                         status = server_service_startup(
684                                 state->event_ctx, cmdline_lp_ctx, model,
685                                 lpcfg_server_services(cmdline_lp_ctx),
686                                 child_pipe[0]);
687                         if (!NT_STATUS_IS_OK(status)) {
688                                 TALLOC_FREE(state);
689                                 exit_daemon("Samba failed to start services",
690                                 NT_STATUS_V(status));
691                         }
692                 }
693         }
694
695         if (opt_daemon) {
696                 daemon_ready("samba");
697         }
698
699         /* wait for events - this is where smbd sits for most of its
700            life */
701         tevent_loop_wait(state->event_ctx);
702
703         /* as everything hangs off this state->event context, freeing state
704            will initiate a clean shutdown of all services */
705         TALLOC_FREE(state);
706
707         return 0;
708 }
709
710 int main(int argc, const char *argv[])
711 {
712         setproctitle_init(argc, discard_const(argv), environ);
713
714         return binary_smbd_main("samba", argc, argv);
715 }