passdb: Use dom_sid_str_buf
[amitay/samba.git] / source4 / kdc / kdc-heimdal.c
index d5c721b605691fc02512008a1d5bfa73489903fb..67c07c3d81a5e9dfe9ec0f33bf7c14ab7181b075 100644 (file)
@@ -78,8 +78,8 @@ static kdc_code kdc_process(struct kdc_server *kdc,
                return KDC_ERROR;
        }
 
-       DEBUG(10,("Received KDC packet of length %lu from %s\n",
-                               (long)input->length - 4, pa));
+       DBG_DEBUG("Received KDC packet of length %lu from %s\n",
+                 (long)input->length - 4, pa);
 
        ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context,
                                            kdc_config,
@@ -110,10 +110,11 @@ static kdc_code kdc_process(struct kdc_server *kdc,
 /*
   setup our listening sockets on the configured network interfaces
 */
-static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx,
-                                      struct interface *ifaces)
+static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc,
+                                      struct loadparm_context *lp_ctx,
+                                      struct interface *ifaces,
+                                      const struct model_ops *model_ops)
 {
-       const struct model_ops *model_ops;
        int num_interfaces;
        TALLOC_CTX *tmp_ctx = talloc_new(kdc);
        NTSTATUS status;
@@ -122,15 +123,6 @@ static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_c
        uint16_t kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
        bool done_wildcard = false;
 
-       /* within the kdc task we want to be a single process, so
-          ask for the single process model ops and pass these to the
-          stream_setup_socket() call. */
-       model_ops = process_model_startup("single");
-       if (!model_ops) {
-               DEBUG(0,("Can't find 'single' process model_ops\n"));
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
        num_interfaces = iface_list_count(ifaces);
 
        /* if we are allowing incoming packets from any address, then
@@ -269,26 +261,23 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 /*
   startup the kdc task
 */
-static void kdc_task_init(struct task_server *task)
+static NTSTATUS kdc_task_init(struct task_server *task)
 {
        struct kdc_server *kdc;
-       krb5_kdc_configuration *kdc_config = NULL;
        NTSTATUS status;
-       krb5_error_code ret;
        struct interface *ifaces;
-       int ldb_ret;
 
        switch (lpcfg_server_role(task->lp_ctx)) {
        case ROLE_STANDALONE:
                task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
-               return;
+               return NT_STATUS_INVALID_DOMAIN_ROLE;
        case ROLE_DOMAIN_MEMBER:
                task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
-               return;
+               return NT_STATUS_INVALID_DOMAIN_ROLE;
        case ROLE_DOMAIN_PDC:
        case ROLE_DOMAIN_BDC:
                task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
-               return;
+               return NT_STATUS_INVALID_DOMAIN_ROLE;
        case ROLE_ACTIVE_DIRECTORY_DC:
                /* Yes, we want a KDC */
                break;
@@ -298,7 +287,7 @@ static void kdc_task_init(struct task_server *task)
 
        if (iface_list_count(ifaces) == 0) {
                task_server_terminate(task, "kdc: no network interfaces configured", false);
-               return;
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
        task_server_set_title(task, "task[kdc]");
@@ -306,25 +295,63 @@ static void kdc_task_init(struct task_server *task)
        kdc = talloc_zero(task, struct kdc_server);
        if (kdc == NULL) {
                task_server_terminate(task, "kdc: out of memory", true);
-               return;
+               return NT_STATUS_NO_MEMORY;
        }
 
        kdc->task = task;
+       task->private_data = kdc;
+
+       /* start listening on the configured network interfaces */
+       status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces,
+                                       task->model_ops);
+       if (!NT_STATUS_IS_OK(status)) {
+               task_server_terminate(task, "kdc failed to setup interfaces", true);
+               return status;
+       }
 
 
+       return NT_STATUS_OK;
+}
+
+/*
+  initialise the kdc task after a fork
+*/
+static void kdc_post_fork(struct task_server *task, struct process_details *pd)
+{
+       struct kdc_server *kdc;
+       krb5_kdc_configuration *kdc_config = NULL;
+       NTSTATUS status;
+       krb5_error_code ret;
+       int ldb_ret;
+
+       if (task == NULL) {
+               task_server_terminate(task, "kdc: Null task", true);
+               return;
+       }
+       if (task->private_data == NULL) {
+               task_server_terminate(task, "kdc: No kdc_server info", true);
+               return;
+       }
+       kdc = talloc_get_type_abort(task->private_data, struct kdc_server);
+
        /* get a samdb connection */
-       kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
-                                  system_session(kdc->task->lp_ctx), 0);
+       kdc->samdb = samdb_connect(kdc,
+                                  kdc->task->event_ctx,
+                                  kdc->task->lp_ctx,
+                                  system_session(kdc->task->lp_ctx),
+                                  NULL,
+                                  0);
        if (!kdc->samdb) {
-               DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
+               DBG_WARNING("kdc_task_init: unable to connect to samdb\n");
                task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
                return;
        }
 
        ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
        if (ldb_ret != LDB_SUCCESS) {
-               DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
-                         ldb_errstring(kdc->samdb)));
+               DBG_WARNING("kdc_task_init: "
+                           "Cannot determine if we are an RODC: %s\n",
+                           ldb_errstring(kdc->samdb));
                task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
                return;
        }
@@ -335,8 +362,8 @@ static void kdc_task_init(struct task_server *task)
 
        ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context);
        if (ret) {
-               DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
-                        error_message(ret)));
+               DBG_WARNING("kdc_task_init: krb5_init_context failed (%s)\n",
+                           error_message(ret));
                task_server_terminate(task, "kdc: krb5_init_context failed", true);
                return;
        }
@@ -447,13 +474,6 @@ static void kdc_task_init(struct task_server *task)
        }
        kdc->private_data = kdc_config;
 
-       /* start listening on the configured network interfaces */
-       status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
-       if (!NT_STATUS_IS_OK(status)) {
-               task_server_terminate(task, "kdc failed to setup interfaces", true);
-               return;
-       }
-
        status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
                               kdc_check_generic_kerberos, kdc);
        if (!NT_STATUS_IS_OK(status)) {
@@ -468,5 +488,11 @@ static void kdc_task_init(struct task_server *task)
 /* called at smbd startup - register ourselves as a server service */
 NTSTATUS server_service_kdc_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "kdc", kdc_task_init);
+       static const struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = false,
+               .task_init = kdc_task_init,
+               .post_fork = kdc_post_fork
+       };
+       return register_server_service(ctx, "kdc", &details);
 }