lib/util Rename samba_init_module_fns_run -> samba_module_init_fns_run
[kai/samba.git] / source4 / smbd / server.c
index fd4b21b17f9b789b0187c068eb366dad6ec12b2f..6df55b88b609711b045e34ac213de9c441d07340 100644 (file)
 #include "lib/cmdline/popt_common.h"
 #include "system/dir.h"
 #include "system/filesys.h"
-#include "ldb/include/ldb.h"
-#include "registry/registry.h"
 #include "ntvfs/ntvfs.h"
 #include "ntptr/ntptr.h"
 #include "auth/gensec/gensec.h"
+#include "libcli/auth/schannel.h"
 #include "smbd/process_model.h"
-#include "smbd/service.h"
 #include "param/secrets.h"
 #include "smbd/pidfile.h"
-#include "cluster/ctdb/ctdb_cluster.h"
 #include "param/param.h"
+#include "dsdb/samdb/samdb.h"
+#include "auth/session.h"
+#include "lib/messaging/irpc.h"
+#include "librpc/gen_ndr/ndr_irpc.h"
+#include "cluster/cluster.h"
+#include "dynconfig/dynconfig.h"
+#include "lib/util/samba_module.h"
 
 /*
   recursively delete a directory tree
@@ -113,7 +117,8 @@ static void sig_term(int sig)
                kill(-getpgrp(), SIGTERM);
        }
 #endif
-       exit(0);
+       DEBUG(0,("Exiting pid %d on SIGTERM\n", (int)getpid()));
+       exit(127);
 }
 
 /*
@@ -138,7 +143,7 @@ static void setup_signals(void)
 #endif
 
        /* POSIX demands that signals are inherited. If the invoking process has
-        * these signals masked, we will have problems, as we won't recieve them. */
+        * these signals masked, we will have problems, as we won't receive them. */
        BlockSignals(false, SIGHUP);
        BlockSignals(false, SIGTERM);
 
@@ -149,15 +154,16 @@ static void setup_signals(void)
 /*
   handle io on stdin
 */
-static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
-                                uint16_t flags, void *private)
+static void server_stdin_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
+                                uint16_t flags, void *private_data)
 {
-       const char *binary_name = (const char *)private;
+       const char *binary_name = (const char *)private_data;
        uint8_t c;
        if (read(0, &c, 1) == 0) {
                DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
 #if HAVE_GETPGRP
                if (getpgrp() == getpid()) {
+                       DEBUG(0,("Sending SIGTERM from pid %d\n", (int)getpid()));
                        kill(-getpgrp(), SIGTERM);
                }
 #endif
@@ -168,12 +174,110 @@ static void server_stdin_handler(struct event_context *event_ctx, struct fd_even
 /*
   die if the user selected maximum runtime is exceeded
 */
-_NORETURN_ static void max_runtime_handler(struct event_context *ev, 
-                                          struct timed_event *te, 
-                                          struct timeval t, void *private)
+_NORETURN_ static void max_runtime_handler(struct tevent_context *ev, 
+                                          struct tevent_timer *te, 
+                                          struct timeval t, void *private_data)
 {
-       const char *binary_name = (const char *)private;
-       DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
+       const char *binary_name = (const char *)private_data;
+       DEBUG(0,("%s: maximum runtime exceeded - terminating, current ts: %llu\n",
+             binary_name, (unsigned long long) time(NULL)));
+       exit(0);
+}
+
+/*
+  pre-open the key databases. This saves a lot of time in child
+  processes
+ */
+static void prime_ldb_databases(struct tevent_context *event_ctx)
+{
+       TALLOC_CTX *db_context;
+       db_context = talloc_new(event_ctx);
+
+       samdb_connect(db_context, event_ctx, cmdline_lp_ctx, system_session(cmdline_lp_ctx), 0);
+       privilege_connect(db_context, cmdline_lp_ctx);
+
+       /* we deliberately leave these open, which allows them to be
+        * re-used in ldb_wrap_connect() */
+}
+
+
+/*
+  called when a fatal condition occurs in a child task
+ */
+static NTSTATUS samba_terminate(struct irpc_message *msg, 
+                               struct samba_terminate *r)
+{
+       DEBUG(0,("samba_terminate: %s\n", r->in.reason));
+       exit(1);
+}
+
+/*
+  setup messaging for the top level samba (parent) task
+ */
+static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, 
+                                      struct loadparm_context *lp_ctx)
+{
+       struct imessaging_context *msg;
+       NTSTATUS status;
+
+       msg = imessaging_init(talloc_autofree_context(),
+                             lp_ctx,
+                             cluster_id(0, SAMBA_PARENT_TASKID), event_ctx, false);
+       NT_STATUS_HAVE_NO_MEMORY(msg);
+
+       irpc_add_name(msg, "samba");
+
+       status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
+                              samba_terminate, NULL);
+
+       return status;
+}
+
+
+/*
+  show build info
+ */
+static void show_build(void)
+{
+#define CONFIG_OPTION(n) { #n, dyn_ ## n }
+       struct {
+               const char *name;
+               const char *value;
+       } config_options[] = {
+               CONFIG_OPTION(BINDIR),
+               CONFIG_OPTION(SBINDIR),
+               CONFIG_OPTION(CONFIGFILE),
+               CONFIG_OPTION(NCALRPCDIR),
+               CONFIG_OPTION(LOGFILEBASE),
+               CONFIG_OPTION(LMHOSTSFILE),
+               CONFIG_OPTION(DATADIR),
+               CONFIG_OPTION(MODULESDIR),
+               CONFIG_OPTION(LOCKDIR),
+               CONFIG_OPTION(STATEDIR),
+               CONFIG_OPTION(CACHEDIR),
+               CONFIG_OPTION(PIDDIR),
+               CONFIG_OPTION(PRIVATE_DIR),
+               CONFIG_OPTION(SWATDIR),
+               CONFIG_OPTION(CODEPAGEDIR),
+               CONFIG_OPTION(SETUPDIR),
+               CONFIG_OPTION(WINBINDD_SOCKET_DIR),
+               CONFIG_OPTION(WINBINDD_PRIVILEGED_SOCKET_DIR),
+               CONFIG_OPTION(NTP_SIGND_SOCKET_DIR),
+               { NULL, NULL}
+       };
+       int i;
+
+       printf("Samba version: %s\n", SAMBA_VERSION_STRING);
+       printf("Build environment:\n");
+#ifdef BUILD_SYSTEM
+       printf("   Build host:  %s\n", BUILD_SYSTEM);
+#endif
+
+       printf("Paths:\n");
+       for (i=0; config_options[i].name; i++) {
+               printf("   %s: %s\n", config_options[i].name, config_options[i].value);
+       }
+
        exit(0);
 }
 
@@ -186,23 +290,11 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        bool opt_interactive = false;
        int opt;
        poptContext pc;
-       extern NTSTATUS server_service_wrepl_init(void);
-       extern NTSTATUS server_service_kdc_init(void);
-       extern NTSTATUS server_service_ldap_init(void);
-       extern NTSTATUS server_service_web_init(void);
-       extern NTSTATUS server_service_ldap_init(void);
-       extern NTSTATUS server_service_winbind_init(void);
-       extern NTSTATUS server_service_nbtd_init(void);
-       extern NTSTATUS server_service_auth_init(void);
-       extern NTSTATUS server_service_cldapd_init(void);
-       extern NTSTATUS server_service_smb_init(void);
-       extern NTSTATUS server_service_drepl_init(void);
-       extern NTSTATUS server_service_rpc_init(void);
-       extern NTSTATUS server_service_ntp_signd_init(void);
-       extern NTSTATUS server_service_samba3_smb_init(void);
-       init_module_fn static_init[] = { STATIC_samba_MODULES };
-       init_module_fn *shared_init;
-       struct event_context *event_ctx;
+#define _MODULE_PROTO(init) extern NTSTATUS init(void);
+       STATIC_service_MODULES_PROTO;
+       samba_module_init_fn static_init[] = { STATIC_service_MODULES };
+       samba_module_init_fn *shared_init;
+       struct tevent_context *event_ctx;
        uint16_t stdin_event_flags;
        NTSTATUS status;
        const char *model = "standard";
@@ -210,7 +302,8 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        enum {
                OPT_DAEMON = 1000,
                OPT_INTERACTIVE,
-               OPT_PROCESS_MODEL
+               OPT_PROCESS_MODEL,
+               OPT_SHOW_BUILD
        };
        struct poptOption long_options[] = {
                POPT_AUTOHELP
@@ -222,6 +315,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
                 "Select process model", "MODEL"},
                {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
                 "set maximum runtime of the server process, till autotermination", "seconds"},
+               {"show-build", 'b', POPT_ARG_NONE, NULL, OPT_SHOW_BUILD, "show build info", NULL },
                POPT_COMMON_SAMBA
                POPT_COMMON_VERSION
                { NULL }
@@ -239,11 +333,14 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
                case OPT_PROCESS_MODEL:
                        model = poptGetOptArg(pc);
                        break;
+               case OPT_SHOW_BUILD:
+                       show_build();
+                       break;
                default:
                        fprintf(stderr, "\nInvalid option %s: %s\n\n",
                                  poptBadOption(pc, 0), poptStrerror(opt));
                        poptPrintUsage(pc, stderr, 0);
-                       exit(1);
+                       return 1;
                }
        }
 
@@ -251,7 +348,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
                fprintf(stderr,"\nERROR: "
                          "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
                poptPrintUsage(pc, stderr, 0);
-               exit(1);
+               return 1;
        } else if (!opt_interactive) {
                /* default is --daemon */
                opt_daemon = true;
@@ -267,38 +364,44 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        umask(0);
 
        DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
-       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n"));
+       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2011\n"));
 
        if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
                DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
                            (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
-               exit(1);
+               return 1;
        }
 
        if (opt_daemon) {
                DEBUG(3,("Becoming a daemon.\n"));
-               become_daemon(true);
+               become_daemon(true, false, false);
        }
 
        cleanup_tmp_files(cmdline_lp_ctx);
 
-       if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
-               mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
+       if (!directory_exist(lpcfg_lockdir(cmdline_lp_ctx))) {
+               mkdir(lpcfg_lockdir(cmdline_lp_ctx), 0755);
        }
 
-       pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
+       pidfile_create(lpcfg_piddir(cmdline_lp_ctx), binary_name);
 
-       /* Do *not* remove this, until you have removed
-        * passdb/secrets.c, and proved that Samba still builds... */
-       /* Setup the SECRETS subsystem */
-       if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) {
-               exit(1);
+       /* Set up a database to hold a random seed, in case we don't
+        * have /dev/urandom */
+       if (!randseed_init(talloc_autofree_context(), cmdline_lp_ctx)) {
+               return 1;
+       }
+
+       if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
+               if (!open_schannel_session_store(talloc_autofree_context(), cmdline_lp_ctx)) {
+                       DEBUG(0,("ERROR: Samba cannot open schannel store for secured NETLOGON operations.\n"));
+                       exit(1);
+               }
        }
 
-       gensec_init(cmdline_lp_ctx); /* FIXME: */
+       gensec_init(); /* FIXME: */
 
-       ntptr_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization function 
+       ntptr_init();   /* FIXME: maybe run this in the initialization function 
                                                of the spoolss RPC server instead? */
 
        ntvfs_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization functions 
@@ -306,10 +409,10 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 
        process_model_init(cmdline_lp_ctx); 
 
-       shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
+       shared_init = samba_modules_load(NULL, "service");
 
-       run_init_functions(static_init);
-       run_init_functions(shared_init);
+       samba_module_init_fns_run(static_init);
+       samba_module_init_fns_run(shared_init);
 
        talloc_free(shared_init);
        
@@ -322,12 +425,9 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
                return 1;
        }
 
-       /* initialise clustering if needed */
-       cluster_ctdb_init(cmdline_lp_ctx, event_ctx, model);
-
        if (opt_interactive) {
                /* terminate when stdin goes away */
-               stdin_event_flags = EVENT_FD_READ;
+               stdin_event_flags = TEVENT_FD_READ;
        } else {
                /* stay alive forever */
                stdin_event_flags = 0;
@@ -337,20 +437,31 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 #ifdef SIGTTIN
        signal(SIGTTIN, SIG_IGN);
 #endif
-       event_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
-                    server_stdin_handler,
-                    discard_const(binary_name));
+       tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
+                     server_stdin_handler,
+                     discard_const(binary_name));
 
        if (max_runtime) {
-               event_add_timed(event_ctx, event_ctx, 
-                               timeval_current_ofs(max_runtime, 0), 
-                               max_runtime_handler,
-                               discard_const(binary_name));
+               DEBUG(0,("Called with maxruntime %d - current ts %llu\n",
+                     max_runtime, (unsigned long long) time(NULL)));
+               tevent_add_timer(event_ctx, event_ctx,
+                                timeval_current_ofs(max_runtime, 0),
+                                max_runtime_handler,
+                                discard_const(binary_name));
+       }
+
+       prime_ldb_databases(event_ctx);
+
+       status = setup_parent_messaging(event_ctx, cmdline_lp_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status)));
+               return 1;
        }
 
        DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
+
        status = server_service_startup(event_ctx, cmdline_lp_ctx, model, 
-                                       lp_server_services(cmdline_lp_ctx));
+                                       lpcfg_server_services(cmdline_lp_ctx));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
                return 1;
@@ -358,7 +469,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 
        /* wait for events - this is where smbd sits for most of its
           life */
-       event_loop_wait(event_ctx);
+       tevent_loop_wait(event_ctx);
 
        /* as everything hangs off this event context, freeing it
           should initiate a clean shutdown of all services */
@@ -367,7 +478,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        return 0;
 }
 
- int main(int argc, const char *argv[])
+int main(int argc, const char *argv[])
 {
-       return binary_smbd_main("smbd", argc, argv);
+       return binary_smbd_main("samba", argc, argv);
 }