source4/smbd: refactor the process model for prefork
authorGary Lockyer <gary@catalyst.net.nz>
Thu, 14 Sep 2017 19:09:23 +0000 (07:09 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 19 Oct 2017 03:33:09 +0000 (05:33 +0200)
    Refactor the process model code to allow the addition of a prefork
    process model.

    - Add a process context to contain process model specific state
    - Add a service details structure to allow service to indicate which
      process model options they can support.

    In the new code the services advertise the features they support to the
    process model.  The process model context is plumbed through to allow the
    process model to keep track of the supported options, and any state
    the process model may require.

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
35 files changed:
file_server/file_server.c
source4/cldap_server/cldap_server.c
source4/dns_server/dns_server.c
source4/dsdb/dns/dns_update.c
source4/dsdb/kcc/kcc_service.c
source4/dsdb/repl/drepl_service.c
source4/echo_server/echo_server.c
source4/kdc/kdc-heimdal.c
source4/kdc/kdc-server.c
source4/kdc/kdc-service-mit.c
source4/ldap_server/ldap_server.c
source4/nbt_server/nbt_server.c
source4/ntp_signd/ntp_signd.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h
source4/rpc_server/service_rpc.c
source4/smb_server/service_smb.c
source4/smb_server/smb_server.c
source4/smb_server/smb_server.h
source4/smbd/process_model.h
source4/smbd/process_single.c
source4/smbd/process_standard.c
source4/smbd/service.c
source4/smbd/service.h
source4/smbd/service_named_pipe.c
source4/smbd/service_stream.c
source4/smbd/service_stream.h
source4/smbd/service_task.c
source4/smbd/service_task.h
source4/torture/rpc/spoolss_notify.c
source4/web_server/web_server.c
source4/winbind/winbindd.c
source4/wrepl_server/wrepl_in_connection.c
source4/wrepl_server/wrepl_out_helpers.c
source4/wrepl_server/wrepl_server.c

index 83641f8..20fa577 100644 (file)
@@ -97,5 +97,9 @@ NTSTATUS server_service_s3fs_init(TALLOC_CTX *);
 
 NTSTATUS server_service_s3fs_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "s3fs", s3fs_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "s3fs", s3fs_task_init, &details);
 }
index 35a2b99..3f845c7 100644 (file)
@@ -243,5 +243,10 @@ static void cldapd_task_init(struct task_server *task)
 */
 NTSTATUS server_service_cldapd_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "cldap", cldapd_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "cldap", cldapd_task_init,
+                                      &details);
 }
index d4f5f27..6a90e30 100644 (file)
@@ -642,7 +642,8 @@ static NTSTATUS dns_add_socket(struct dns_server *dns,
                                     &dns_tcp_stream_ops,
                                     "ip", address, &port,
                                     lpcfg_socket_options(dns->task->lp_ctx),
-                                    dns_socket);
+                                    dns_socket,
+                                    dns->task->process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
                         address, port, nt_errstr(status)));
@@ -929,5 +930,9 @@ static void dns_task_init(struct task_server *task)
 
 NTSTATUS server_service_dns_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "dns", dns_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true,
+       };
+       return register_server_service(ctx, "dns", dns_task_init, &details);
 }
index ba8431a..10be7ce 100644 (file)
@@ -707,5 +707,10 @@ static void dnsupdate_task_init(struct task_server *task)
 */
 NTSTATUS server_service_dnsupdate_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "dnsupdate", dnsupdate_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true,
+       };
+       return register_server_service(ctx, "dnsupdate", dnsupdate_task_init,
+                                      &details);
 }
index 946a8fe..a5508af 100644 (file)
@@ -347,5 +347,9 @@ static void kccsrv_task_init(struct task_server *task)
 */
 NTSTATUS server_service_kcc_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "kcc", kccsrv_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "kcc", kccsrv_task_init, &details);
 }
index 0951a0f..8f16a2e 100644 (file)
@@ -528,5 +528,10 @@ static void dreplsrv_task_init(struct task_server *task)
 */
 NTSTATUS server_service_drepl_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "drepl", dreplsrv_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true,
+       };
+       return register_server_service(ctx, "drepl",  dreplsrv_task_init,
+                                      &details);
 }
index e610232..9a66211 100644 (file)
@@ -343,5 +343,9 @@ static void echo_task_init(struct task_server *task)
  */
 NTSTATUS server_service_echo_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "echo", echo_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "echo", echo_task_init, &details);
 }
index d5c721b..788959a 100644 (file)
@@ -468,5 +468,20 @@ 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);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               /* 
+                * Need to prevent pre-forking on kdc.
+                * The task_init function is run on the master process only
+                * and the irpc process name is registered in it's event loop.
+                * The child worker processes initialise their event loops on
+                * fork, so are not listening for the irpc event.
+                *
+                * The master process does not wait on that event context
+                * the master process is responsible for managing the worker
+                * processes not performing work.
+                */
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "kdc", kdc_task_init, &details);
 }
index 13e338d..00b5c74 100644 (file)
@@ -578,7 +578,8 @@ NTSTATUS kdc_add_socket(struct kdc_server *kdc,
                                             &kdc_tcp_stream_ops,
                                             "ip", address, &port,
                                             lpcfg_socket_options(kdc->task->lp_ctx),
-                                            kdc_socket);
+                                            kdc_socket,
+                                            kdc->task->process_context);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
                                 address, port, nt_errstr(status)));
index 7febf15..d48b032 100644 (file)
@@ -358,5 +358,21 @@ NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx);
 
 NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx)
 {
-       return register_server_service(mem_ctx, "kdc", mitkdc_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               /* 
+                * Need to prevent pre-forking on kdc.
+                * The task_init function is run on the master process only
+                * and the irpc process name is registered in it's event loop.
+                * The child worker processes initialise their event loops on
+                * fork, so are not listening for the irpc event.
+                *
+                * The master process does not wait on that event context
+                * the master process is responsible for managing the worker
+                * processes not performing work.
+                */
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(mem_ctx, "kdc", mitkdc_task_init,
+                                      &details);
 }
index 7730ff9..d12c4e7 100644 (file)
@@ -1030,7 +1030,7 @@ static NTSTATUS add_socket(struct task_server *task,
                                     model_ops, &ldap_stream_nonpriv_ops,
                                     "ip", address, &port,
                                     lpcfg_socket_options(lp_ctx),
-                                    ldap_service);
+                                    ldap_service, task->process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
                         address, port, nt_errstr(status)));
@@ -1045,7 +1045,8 @@ static NTSTATUS add_socket(struct task_server *task,
                                             &ldap_stream_nonpriv_ops,
                                             "ip", address, &port,
                                             lpcfg_socket_options(lp_ctx),
-                                            ldap_service);
+                                            ldap_service,
+                                            task->process_context);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
                                 address, port, nt_errstr(status)));
@@ -1067,7 +1068,8 @@ static NTSTATUS add_socket(struct task_server *task,
                                             &ldap_stream_nonpriv_ops,
                                             "ip", address, &port,
                                             lpcfg_socket_options(lp_ctx),
-                                            ldap_service);
+                                            ldap_service,
+                                            task->process_context);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
                                 address, port, nt_errstr(status)));
@@ -1081,7 +1083,8 @@ static NTSTATUS add_socket(struct task_server *task,
                                                     &ldap_stream_nonpriv_ops,
                                                     "ip", address, &port,
                                                     lpcfg_socket_options(lp_ctx),
-                                                    ldap_service);
+                                                    ldap_service,
+                                                    task->process_context);
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
                                         address, port, nt_errstr(status)));
@@ -1210,7 +1213,7 @@ static void ldapsrv_task_init(struct task_server *task)
                                     model_ops, &ldap_stream_nonpriv_ops,
                                     "unix", ldapi_path, NULL, 
                                     lpcfg_socket_options(task->lp_ctx),
-                                    ldap_service);
+                                    ldap_service, task->process_context);
        talloc_free(ldapi_path);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
@@ -1241,7 +1244,8 @@ static void ldapsrv_task_init(struct task_server *task)
                                     model_ops, &ldap_stream_priv_ops,
                                     "unix", ldapi_path, NULL,
                                     lpcfg_socket_options(task->lp_ctx),
-                                    ldap_service);
+                                    ldap_service,
+                                    task->process_context);
        talloc_free(ldapi_path);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
@@ -1261,5 +1265,10 @@ failed:
 
 NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "ldap", ldapsrv_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = false,
+               .inhibit_pre_fork = false
+       };
+       return register_server_service(ctx, "ldap", ldapsrv_task_init,
+                                      &details);
 }
index 2196bb0..834c72f 100644 (file)
@@ -100,5 +100,9 @@ static void nbtd_task_init(struct task_server *task)
 */
 NTSTATUS server_service_nbtd_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "nbt", nbtd_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "nbt", nbtd_task_init, &details);
 }
index 7949dc2..0884d2f 100644 (file)
@@ -541,7 +541,8 @@ static void ntp_signd_task_init(struct task_server *task)
                                     &ntp_signd_stream_ops, 
                                     "unix", address, NULL,
                                     lpcfg_socket_options(ntp_signd->task->lp_ctx),
-                                    ntp_signd);
+                                    ntp_signd,
+                                    ntp_signd->task->process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to bind to %s - %s\n",
                         address, nt_errstr(status)));
@@ -554,5 +555,10 @@ static void ntp_signd_task_init(struct task_server *task)
 /* called at smbd startup - register ourselves as a server service */
 NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "ntp_signd", ntp_signd_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "ntp_signd", ntp_signd_task_init,
+                                      &details);
 }
index 6a985c5..24eaa65 100644 (file)
@@ -2870,7 +2870,9 @@ static const struct stream_server_ops dcesrv_stream_ops = {
 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
                                   struct loadparm_context *lp_ctx,
                                   struct dcesrv_endpoint *e,
-                           struct tevent_context *event_ctx, const struct model_ops *model_ops)
+                                  struct tevent_context *event_ctx,
+                                  const struct model_ops *model_ops,
+                                  void *process_context)
 {
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 1;
@@ -2890,7 +2892,7 @@ static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
                                     model_ops, &dcesrv_stream_ops, 
                                     "unix", endpoint, &port,
                                     lpcfg_socket_options(lp_ctx),
-                                    dcesrv_sock);
+                                    dcesrv_sock, process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
                         endpoint, nt_errstr(status)));
@@ -2902,7 +2904,9 @@ static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
                                      struct loadparm_context *lp_ctx,
                                      struct dcesrv_endpoint *e,
-                                     struct tevent_context *event_ctx, const struct model_ops *model_ops)
+                                     struct tevent_context *event_ctx,
+                                     const struct model_ops *model_ops,
+                                     void *process_context)
 {
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 1;
@@ -2944,7 +2948,7 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
                                     model_ops, &dcesrv_stream_ops, 
                                     "unix", full_path, &port, 
                                     lpcfg_socket_options(lp_ctx),
-                                    dcesrv_sock);
+                                    dcesrv_sock, process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
                         endpoint, full_path, nt_errstr(status)));
@@ -2955,7 +2959,9 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
                                 struct loadparm_context *lp_ctx,
                                 struct dcesrv_endpoint *e,
-                                struct tevent_context *event_ctx, const struct model_ops *model_ops)
+                                struct tevent_context *event_ctx,
+                                const struct model_ops *model_ops,
+                                void *process_context)
 {
        struct dcesrv_socket_context *dcesrv_sock;
        NTSTATUS status;
@@ -2977,7 +2983,7 @@ static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
        status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
                                          model_ops, &dcesrv_stream_ops,
                                          endpoint,
-                                         dcesrv_sock);
+                                         dcesrv_sock, process_context);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
                         endpoint, nt_errstr(status)));
@@ -2990,9 +2996,12 @@ static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
 /*
   add a socket address to the list of events, one event per dcerpc endpoint
 */
-static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
-                                        struct tevent_context *event_ctx, const struct model_ops *model_ops,
-                                        const char *address)
+static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
+                                        struct dcesrv_endpoint *e,
+                                        struct tevent_context *event_ctx,
+                                        const struct model_ops *model_ops,
+                                        const char *address,
+                                        void *process_context)
 {
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 0;
@@ -3016,7 +3025,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
                                     model_ops, &dcesrv_stream_ops, 
                                     "ip", address, &port,
                                     lpcfg_socket_options(dce_ctx->lp_ctx),
-                                    dcesrv_sock);
+                                    dcesrv_sock, process_context);
        if (!NT_STATUS_IS_OK(status)) {
                struct dcesrv_if_list *iface;
                DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
@@ -3055,7 +3064,9 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
                                  struct loadparm_context *lp_ctx,
                                  struct dcesrv_endpoint *e,
-                                 struct tevent_context *event_ctx, const struct model_ops *model_ops)
+                                 struct tevent_context *event_ctx,
+                                 const struct model_ops *model_ops,
+                                 void *process_context)
 {
        NTSTATUS status;
 
@@ -3070,7 +3081,9 @@ static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
                num_interfaces = iface_list_count(ifaces);
                for(i = 0; i < num_interfaces; i++) {
                        const char *address = iface_list_n_ip(ifaces, i);
-                       status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
+                       status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
+                                                         model_ops, address,
+                                                         process_context);
                        NT_STATUS_NOT_OK_RETURN(status);
                }
        } else {
@@ -3080,7 +3093,9 @@ static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
                wcard = iface_list_wildcard(dce_ctx);
                NT_STATUS_HAVE_NO_MEMORY(wcard);
                for (i=0; wcard[i]; i++) {
-                       status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
+                       status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
+                                                         model_ops, wcard[i],
+                                                         process_context);
                        if (NT_STATUS_IS_OK(status)) {
                                num_binds++;
                        }
@@ -3098,23 +3113,28 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
                       struct loadparm_context *lp_ctx,
                       struct dcesrv_endpoint *e,
                       struct tevent_context *event_ctx,
-                      const struct model_ops *model_ops)
+                      const struct model_ops *model_ops,
+                      void *process_context)
 {
        enum dcerpc_transport_t transport =
                dcerpc_binding_get_transport(e->ep_description);
 
        switch (transport) {
        case NCACN_UNIX_STREAM:
-               return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
+               return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
+                                         model_ops, process_context);
 
        case NCALRPC:
-               return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
+               return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
+                                            model_ops, process_context);
 
        case NCACN_IP_TCP:
-               return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
+               return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
+                                        model_ops, process_context);
 
        case NCACN_NP:
-               return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
+               return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
+                                       model_ops, process_context);
 
        default:
                return NT_STATUS_NOT_SUPPORTED;
index c038075..f2fb0f6 100644 (file)
@@ -467,7 +467,8 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
                       struct loadparm_context *lp_ctx,
                       struct dcesrv_endpoint *e,
                       struct tevent_context *event_ctx,
-                      const struct model_ops *model_ops);
+                      const struct model_ops *model_ops,
+                      void *process_context);
 
 /**
  * retrieve credentials from a dce_call
index 3ff9f6f..eb75184 100644 (file)
@@ -116,7 +116,7 @@ static void dcesrv_task_init(struct task_server *task)
                }
 
                status = dcesrv_add_ep(dce_ctx, task->lp_ctx, e, task->event_ctx,
-                                      this_model_ops);
+                                      this_model_ops, task->process_context);
                if (!NT_STATUS_IS_OK(status)) {
                        goto failed;
                }
@@ -142,5 +142,16 @@ failed:
 
 NTSTATUS server_service_rpc_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "rpc", dcesrv_task_init);
+       struct service_details details = {
+               /* 
+                * This is a SNOWFLAKE, but sadly one that we
+                * will have to keep for now.  The RPC server
+                * code above overstamps the SINGLE process model
+                * most of the time, but we need to be in forking
+                * mode by defult to get a forking NETLOGON server
+                */
+               .inhibit_fork_on_accept = false,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "rpc", dcesrv_task_init, &details);
 }
index a607861..ddf24a9 100644 (file)
@@ -60,7 +60,11 @@ static void smbsrv_task_init(struct task_server *task)
                */
                for(i = 0; i < num_interfaces; i++) {
                        const char *address = iface_list_n_ip(ifaces, i);
-                       status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, address);
+                       status = smbsrv_add_socket(task, task->event_ctx,
+                                                  task->lp_ctx,
+                                                  task->model_ops,
+                                                  address,
+                                                  task->process_context);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
        } else {
@@ -72,7 +76,11 @@ static void smbsrv_task_init(struct task_server *task)
                        goto failed;
                }
                for (i=0; wcard[i]; i++) {
-                       status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, wcard[i]);
+                       status = smbsrv_add_socket(task, task->event_ctx,
+                                                  task->lp_ctx,
+                                                  task->model_ops,
+                                                  wcard[i],
+                                                  task->process_context);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
                talloc_free(wcard);
@@ -87,7 +95,11 @@ failed:
 /* called at smbd startup - register ourselves as a server service */
 NTSTATUS server_service_smb_init(TALLOC_CTX *ctx)
 {
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
        ntvfs_init(cmdline_lp_ctx);
        share_init();
-       return register_server_service(ctx, "smb", smbsrv_task_init);
+       return register_server_service(ctx, "smb", smbsrv_task_init, &details);
 }
index 7e4c032..45641a4 100644 (file)
@@ -179,7 +179,8 @@ _PUBLIC_ NTSTATUS smbsrv_add_socket(TALLOC_CTX *mem_ctx,
                                    struct tevent_context *event_context,
                                    struct loadparm_context *lp_ctx,
                                    const struct model_ops *model_ops,
-                                   const char *address)
+                                   const char *address,
+                                   void *process_context)
 {
        const char **ports = lpcfg_smb_ports(lp_ctx);
        int i;
@@ -192,7 +193,7 @@ _PUBLIC_ NTSTATUS smbsrv_add_socket(TALLOC_CTX *mem_ctx,
                                             model_ops, &smb_stream_ops, 
                                             "ip", address, &port,
                                             lpcfg_socket_options(lp_ctx),
-                                            NULL);
+                                            NULL, process_context);
                NT_STATUS_NOT_OK_RETURN(status);
        }
 
index 40af4a6..5ddfe78 100644 (file)
@@ -397,7 +397,8 @@ NTSTATUS smbsrv_add_socket(TALLOC_CTX *mem_ctx,
                           struct tevent_context *event_context,
                           struct loadparm_context *lp_ctx,
                           const struct model_ops *model_ops,
-                          const char *address);
+                          const char *address,
+                          void *process_context);
 
 struct loadparm_context;
 
index d7bf3c8..656a7f2 100644 (file)
@@ -51,8 +51,8 @@ struct model_ops {
                                  void (*)(struct tevent_context *, 
                                           struct loadparm_context *,
                                           struct socket_context *, 
-                                          struct server_id , void *), 
-                                 void *);
+                                          struct server_id , void *, void *),
+                                 void *, void *);
 
        /* function to create a task */
        void (*new_task)(struct tevent_context *, 
@@ -60,13 +60,16 @@ struct model_ops {
                         const char *service_name,
                         void (*)(struct tevent_context *, 
                                  struct loadparm_context *, struct server_id, 
-                                 void *),
+                                 void *, void *),
                         void *,
-                        int);
+                        const struct service_details*,
+                        const int);
 
        /* function to terminate a connection or task */
-       void (*terminate)(struct tevent_context *, struct loadparm_context *lp_ctx,
-                         const char *reason);
+       void (*terminate)(struct tevent_context *,
+                         struct loadparm_context *lp_ctx,
+                         const char *reason,
+                         void * process_context);
 
        /* function to set a title for the connection or task */
        void (*set_title)(struct tevent_context *, const char *title);
index 54169e9..1027415 100644 (file)
@@ -44,8 +44,10 @@ static void single_accept_connection(struct tevent_context *ev,
                                     void (*new_conn)(struct tevent_context *, 
                                                      struct loadparm_context *,
                                                      struct socket_context *, 
-                                                     struct server_id , void *), 
-                                    void *private_data)
+                                                     struct server_id, void *,
+                                                     void *),
+                                    void *private_data,
+                                    void *process_context)
 {
        NTSTATUS status;
        struct socket_context *connected_socket;
@@ -79,7 +81,8 @@ static void single_accept_connection(struct tevent_context *ev,
         * combination of pid/fd should be unique system-wide
         */
        new_conn(ev, lp_ctx, connected_socket,
-                cluster_id(pid, socket_get_fd(connected_socket)), private_data);
+                cluster_id(pid, socket_get_fd(connected_socket)), private_data,
+                           process_context);
 }
 
 /*
@@ -88,8 +91,11 @@ static void single_accept_connection(struct tevent_context *ev,
 static void single_new_task(struct tevent_context *ev,
                            struct loadparm_context *lp_ctx,
                            const char *service_name,
-                           void (*new_task)(struct tevent_context *, struct loadparm_context *, struct server_id, void *),
+                           void (*new_task)(struct tevent_context *,
+                                            struct loadparm_context *,
+                                            struct server_id, void *, void *),
                            void *private_data,
+                           const struct service_details *service_details,
                            int from_parent_fd)
 {
        pid_t pid = getpid();
@@ -105,12 +111,15 @@ static void single_new_task(struct tevent_context *ev,
         * Using the pid unaltered makes debugging of which process
         * owns the messaging socket easier.
         */
-       new_task(ev, lp_ctx, cluster_id(pid, taskid++), private_data);
+       new_task(ev, lp_ctx, cluster_id(pid, taskid++), private_data, NULL);
 }
 
 
 /* called when a task goes down */
-static void single_terminate(struct tevent_context *ev, struct loadparm_context *lp_ctx, const char *reason)
+static void single_terminate(struct tevent_context *ev,
+                            struct loadparm_context *lp_ctx,
+                            const char *reason,
+                            void *process_context)
 {
        DEBUG(3,("single_terminate: reason[%s]\n",reason));
 }
index c6cbfc2..431134e 100644 (file)
@@ -222,13 +222,18 @@ static struct standard_child_state *setup_standard_child_pipe(struct tevent_cont
 /*
   called when a listening socket becomes readable. 
 */
-static void standard_accept_connection(struct tevent_context *ev, 
-                                      struct loadparm_context *lp_ctx,
-                                      struct socket_context *sock, 
-                                      void (*new_conn)(struct tevent_context *,
-                                                       struct loadparm_context *, struct socket_context *, 
-                                                       struct server_id , void *), 
-                                      void *private_data)
+static void standard_accept_connection(
+               struct tevent_context *ev,
+               struct loadparm_context *lp_ctx,
+               struct socket_context *sock,
+               void (*new_conn)(struct tevent_context *,
+                               struct loadparm_context *,
+                               struct socket_context *,
+                               struct server_id,
+                               void *,
+                               void *),
+               void *private_data,
+               void *process_context)
 {
        NTSTATUS status;
        struct socket_context *sock2;
@@ -340,7 +345,8 @@ static void standard_accept_connection(struct tevent_context *ev,
        talloc_free(s);
 
        /* setup this new connection.  Cluster ID is PID based for this process model */
-       new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data);
+       new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data,
+                NULL);
 
        /* we can't return to the top level here, as that event context is gone,
           so we now process events in the new event context until there are no
@@ -357,8 +363,9 @@ static void standard_accept_connection(struct tevent_context *ev,
 static void standard_new_task(struct tevent_context *ev,
                              struct loadparm_context *lp_ctx,
                              const char *service_name,
-                             void (*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *),
+                             void (*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *),
                              void *private_data,
+                             const struct service_details *service_details,
                              int new_from_parent_fd)
 {
        pid_t pid;
@@ -438,11 +445,11 @@ static void standard_new_task(struct tevent_context *ev,
        setproctitle("task %s server_id[%d]", service_name, (int)pid);
 
        /* setup this new task.  Cluster ID is PID based for this process model */
-       new_task(ev, lp_ctx, cluster_id(pid, 0), private_data);
+       new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, NULL);
 
        /* we can't return to the top level here, as that event context is gone,
           so we now process events in the new event context until there are no
-          more to process */      
+          more to process */
        tevent_loop_wait(ev);
 
        talloc_free(ev);
@@ -452,7 +459,8 @@ static void standard_new_task(struct tevent_context *ev,
 
 /* called when a task goes down */
 _NORETURN_ static void standard_terminate(struct tevent_context *ev, struct loadparm_context *lp_ctx,
-                                         const char *reason) 
+                                         const char *reason,
+                                         void *process_context) 
 {
        DEBUG(2,("standard_terminate: reason[%s]\n",reason));
 
index 61ed684..9a77ca8 100644 (file)
@@ -30,6 +30,7 @@
 static struct registered_server {
        struct registered_server *next, *prev;
        const char *service_name;
+       struct service_details *service_details;
        void (*task_init)(struct task_server *);
 } *registered_servers;
 
@@ -38,13 +39,17 @@ static struct registered_server {
 */
 NTSTATUS register_server_service(TALLOC_CTX *ctx,
                                const char *name,
-                               void (*task_init)(struct task_server *))
+                               void (*task_init) (struct task_server *),
+                               struct service_details *details)
 {
        struct registered_server *srv;
        srv = talloc(ctx, struct registered_server);
        NT_STATUS_HAVE_NO_MEMORY(srv);
        srv->service_name = name;
        srv->task_init = task_init;
+       srv->service_details =
+               talloc_memdup(ctx, details, sizeof(struct service_details));
+       NT_STATUS_HAVE_NO_MEMORY(srv->service_details);
        DLIST_ADD_END(registered_servers, srv);
        return NT_STATUS_OK;
 }
@@ -64,7 +69,9 @@ static NTSTATUS server_service_init(const char *name,
                if (strcasecmp(name, srv->service_name) == 0) {
                        return task_server_startup(event_context, lp_ctx,
                                                   srv->service_name,
-                                                  model_ops, srv->task_init,
+                                                  model_ops,
+                                                  srv->task_init,
+                                                  srv->service_details,
                                                   from_parent_fd);
                }
        }
index 23a9e63..2d11f14 100644 (file)
 #ifndef __SERVICE_H__
 #define __SERVICE_H__
 
+
 #include "smbd/service_stream.h"
 #include "smbd/service_task.h"
+
+struct service_details {
+       /*
+        * Prevent the standard process model from forking a new worker
+        * process when accepting a new connection.  Do this when the service
+        * relies on shared state, or the over-head of forking would be a
+        * significant part of the response time
+        */
+       bool inhibit_fork_on_accept;
+       /*
+        * Prevent the pre-fork process model from pre-forking any worker
+        * processes. In this mode pre-fork is equivalent to standard with
+        * inhibit_fork_on_accept set.
+        */
+        bool inhibit_pre_fork;
+};
+
 #include "smbd/service_proto.h"
 
 #endif /* __SERVICE_H__ */
index c7e31bc..744f942 100644 (file)
@@ -188,7 +188,8 @@ NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx,
                                  const struct model_ops *model_ops,
                                  const struct stream_server_ops *stream_ops,
                                  const char *pipe_name,
-                                 void *private_data)
+                                 void *private_data,
+                                 void *process_context)
 {
        char *dirname;
        struct named_pipe_socket *pipe_sock;
@@ -248,7 +249,8 @@ NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx,
                                     pipe_sock->pipe_path,
                                     NULL,
                                     NULL,
-                                    pipe_sock);
+                                    pipe_sock,
+                                    process_context);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }
index 917a187..3f4a04c 100644 (file)
@@ -44,6 +44,7 @@ struct stream_socket {
        const struct model_ops *model_ops;
        struct socket_context *sock;
        void *private_data;
+       void *process_context;
 };
 
 
@@ -55,6 +56,7 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
        struct tevent_context *event_ctx = srv_conn->event.ctx;
        const struct model_ops *model_ops = srv_conn->model_ops;
        struct loadparm_context *lp_ctx = srv_conn->lp_ctx;
+       void *process_context = srv_conn->process_context;
        TALLOC_CTX *frame = NULL;
 
        if (!reason) reason = "unknown reason";
@@ -89,8 +91,7 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
        srv_conn->event.fde = NULL;
        imessaging_cleanup(srv_conn->msg_ctx);
        TALLOC_FREE(srv_conn);
-       model_ops->terminate(event_ctx, lp_ctx, reason);
-
+       model_ops->terminate(event_ctx, lp_ctx, reason, process_context);
        TALLOC_FREE(frame);
 }
 
@@ -138,7 +139,8 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
                                     const struct stream_server_ops *stream_ops,
                                     struct imessaging_context *msg_ctx,
                                     void *private_data,
-                                    struct stream_connection **_srv_conn)
+                                    struct stream_connection **_srv_conn,
+                                    void *process_context)
 {
        struct stream_connection *srv_conn;
 
@@ -154,6 +156,7 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
        srv_conn->event.ctx     = ev;
        srv_conn->lp_ctx        = lp_ctx;
        srv_conn->event.fde     = NULL;
+       srv_conn->process_context = process_context;
 
        *_srv_conn = srv_conn;
        return NT_STATUS_OK;
@@ -166,7 +169,9 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
 static void stream_new_connection(struct tevent_context *ev,
                                  struct loadparm_context *lp_ctx,
                                  struct socket_context *sock, 
-                                 struct server_id server_id, void *private_data)
+                                 struct server_id server_id,
+                                 void *private_data,
+                                 void *process_context)
 {
        struct stream_socket *stream_socket = talloc_get_type(private_data, struct stream_socket);
        struct stream_connection *srv_conn;
@@ -186,6 +191,7 @@ static void stream_new_connection(struct tevent_context *ev,
        srv_conn->ops           = stream_socket->ops;
        srv_conn->event.ctx     = ev;
        srv_conn->lp_ctx        = lp_ctx;
+       srv_conn->process_context = process_context;
 
        if (!socket_check_access(sock, "smbd", lpcfg_hosts_allow(NULL, lpcfg_default_service(lp_ctx)), lpcfg_hosts_deny(NULL, lpcfg_default_service(lp_ctx)))) {
                stream_terminate_connection(srv_conn, "denied by access rules");
@@ -258,8 +264,9 @@ static void stream_accept_handler(struct tevent_context *ev, struct tevent_fd *f
           connection.  When done, it calls stream_new_connection()
           with the newly created socket */
        stream_socket->model_ops->accept_connection(ev, stream_socket->lp_ctx,
-                                                   stream_socket->sock, 
-                                                   stream_new_connection, stream_socket);
+                                                   stream_socket->sock,
+                                                   stream_new_connection, stream_socket,
+                                                   stream_socket->process_context);
 }
 
 /*
@@ -279,7 +286,8 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx,
                             const char *sock_addr,
                             uint16_t *port,
                             const char *socket_options,
-                            void *private_data)
+                            void *private_data,
+                            void *process_context)
 {
        NTSTATUS status;
        struct stream_socket *stream_socket;
@@ -385,6 +393,7 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx,
        stream_socket->ops              = stream_ops;
        stream_socket->event_ctx        = event_context;
        stream_socket->model_ops        = model_ops;
+       stream_socket->process_context  = process_context;
 
        return NT_STATUS_OK;
 }
index a7d3def..81bf275 100644 (file)
@@ -62,6 +62,7 @@ struct stream_connection {
 
        uint processing;
        const char *terminate;
+       void *process_context;
 };
 
 
index e0e98f6..1d33a43 100644 (file)
@@ -50,8 +50,8 @@ void task_server_terminate(struct task_server *task, const char *reason, bool fa
 
        imessaging_cleanup(task->msg_ctx);
 
-       model_ops->terminate(event_ctx, task->lp_ctx, reason);
-       
+       model_ops->terminate(event_ctx, task->lp_ctx, reason,
+                            task->process_context);
        /* don't free this above, it might contain the 'reason' being printed */
        talloc_free(task);
 }
@@ -67,9 +67,11 @@ struct task_state {
   called by the process model code when the new task starts up. This then calls
   the server specific startup code
 */
-static void task_server_callback(struct tevent_context *event_ctx, 
+static void task_server_callback(struct tevent_context *event_ctx,
                                 struct loadparm_context *lp_ctx,
-                                struct server_id server_id, void *private_data)
+                                struct server_id server_id,
+                                void *private_data,
+                                void *context)
 {
        struct task_state *state = talloc_get_type(private_data, struct task_state);
        struct task_server *task;
@@ -81,6 +83,7 @@ static void task_server_callback(struct tevent_context *event_ctx,
        task->model_ops = state->model_ops;
        task->server_id = server_id;
        task->lp_ctx = lp_ctx;
+       task->process_context = context;
 
        task->msg_ctx = imessaging_init(task,
                                        task->lp_ctx,
@@ -97,11 +100,12 @@ static void task_server_callback(struct tevent_context *event_ctx,
 /*
   startup a task based server
 */
-NTSTATUS task_server_startup(struct tevent_context *event_ctx, 
+NTSTATUS task_server_startup(struct tevent_context *event_ctx,
                             struct loadparm_context *lp_ctx,
-                            const char *service_name, 
-                            const struct model_ops *model_ops, 
+                            const char *service_name,
+                            const struct model_ops *model_ops,
                             void (*task_init)(struct task_server *),
+                            const struct service_details *service_details,
                             int from_parent_fd)
 {
        struct task_state *state;
@@ -113,7 +117,7 @@ NTSTATUS task_server_startup(struct tevent_context *event_ctx,
        state->model_ops = model_ops;
 
        state->model_ops->new_task(event_ctx, lp_ctx, service_name,
-                                  task_server_callback, state,
+                                  task_server_callback, state, service_details,
                                   from_parent_fd);
 
        return NT_STATUS_OK;
index ded4590..2499dc1 100644 (file)
@@ -31,6 +31,7 @@ struct task_server {
        struct loadparm_context *lp_ctx;
        struct server_id server_id;
        void *private_data;
+       void *process_context;
 };
 
 
index bcae5f8..dd9cd31 100644 (file)
@@ -474,7 +474,9 @@ static bool test_start_dcerpc_server(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status,
                                   "unable to initialize process models");
 
-       status = smbsrv_add_socket(tctx, event_ctx, tctx->lp_ctx, process_model_startup("single"), address);
+       status = smbsrv_add_socket(tctx, event_ctx, tctx->lp_ctx,
+                                  process_model_startup("single"),
+                                  address, NULL);
        torture_assert_ntstatus_ok(tctx, status, "starting smb server");
 
        status = dcesrv_init_context(tctx, tctx->lp_ctx, endpoints, &dce_ctx);
@@ -483,7 +485,8 @@ static bool test_start_dcerpc_server(struct torture_context *tctx,
 
        for (e=dce_ctx->endpoint_list;e;e=e->next) {
                status = dcesrv_add_ep(dce_ctx, tctx->lp_ctx,
-                                      e, tctx->ev, process_model_startup("single"));
+                                      e, tctx->ev,
+                                      process_model_startup("single"), NULL);
                torture_assert_ntstatus_ok(tctx, status,
                                "unable listen on dcerpc endpoint server");
        }
index d854a29..faf1bc6 100644 (file)
@@ -330,8 +330,10 @@ static void websrv_task_init(struct task_server *task)
                                                     task->lp_ctx, model_ops,
                                                     &web_stream_ops, 
                                                     "ip", address,
-                                                    &port, lpcfg_socket_options(task->lp_ctx),
-                                                    task);
+                                                    &port,
+                                                    lpcfg_socket_options(task->lp_ctx),
+                                                    task,
+                                                    task->process_context);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
 
@@ -350,7 +352,8 @@ static void websrv_task_init(struct task_server *task)
                                                     &web_stream_ops,
                                                     "ip", wcard[i],
                                                     &port, lpcfg_socket_options(task->lp_ctx),
-                                                    wdata);
+                                                    wdata,
+                                                    task->process_context);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
                talloc_free(wcard);
@@ -372,5 +375,9 @@ failed:
 /* called at smbd startup - register ourselves as a server service */
 NTSTATUS server_service_web_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "web", websrv_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "web", websrv_task_init, &details);
 }
index c8c0733..6aa0418 100644 (file)
@@ -90,9 +90,16 @@ NTSTATUS server_service_winbindd_init(TALLOC_CTX *);
 
 NTSTATUS server_service_winbindd_init(TALLOC_CTX *ctx)
 {
-       NTSTATUS status = register_server_service(ctx, "winbindd", winbindd_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true,
+       };
+
+       NTSTATUS status = register_server_service(ctx, "winbindd",
+                                                 winbindd_task_init, &details);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       return register_server_service(ctx, "winbind", winbindd_task_init);
+       return register_server_service(ctx, "winbind", winbindd_task_init,
+                                      &details);
 }
index b8e9a16..4920aa0 100644 (file)
@@ -347,7 +347,8 @@ static const struct stream_server_ops wreplsrv_stream_ops = {
 NTSTATUS wreplsrv_in_connection_merge(struct wreplsrv_partner *partner,
                                      uint32_t peer_assoc_ctx,
                                      struct tstream_context **stream,
-                                     struct wreplsrv_in_connection **_wrepl_in)
+                                     struct wreplsrv_in_connection **_wrepl_in,
+                                     void* process_context)
 {
        struct wreplsrv_service *service = partner->service;
        struct wreplsrv_in_connection *wrepl_in;
@@ -379,7 +380,8 @@ NTSTATUS wreplsrv_in_connection_merge(struct wreplsrv_partner *partner,
                                             &wreplsrv_stream_ops,
                                             service->task->msg_ctx,
                                             wrepl_in,
-                                            &conn);
+                                            &conn,
+                                            process_context);
        NT_STATUS_NOT_OK_RETURN(status);
 
        /*
@@ -461,7 +463,7 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar
                                                     &wreplsrv_stream_ops,
                                                     "ipv4", address, &port, 
                                                      lpcfg_socket_options(task->lp_ctx),
-                                                    service);
+                                                    service, task->process_context);
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n",
                                         address, port, nt_errstr(status)));
@@ -473,7 +475,7 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar
                status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
                                             model_ops, &wreplsrv_stream_ops,
                                             "ipv4", address, &port, lpcfg_socket_options(task->lp_ctx),
-                                            service);
+                                            service, task->process_context);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n",
                                 address, port, nt_errstr(status)));
index 782e2f2..0e3f0a4 100644 (file)
@@ -988,6 +988,7 @@ static NTSTATUS wreplsrv_push_notify_wait_update(struct wreplsrv_push_notify_sta
 {
        struct wreplsrv_in_connection *wrepl_in;
        struct tstream_context *stream;
+       void *process_context = NULL;
        NTSTATUS status;
 
        status = wrepl_request_recv(state->subreq, state, NULL);
@@ -1011,10 +1012,11 @@ static NTSTATUS wreplsrv_push_notify_wait_update(struct wreplsrv_push_notify_sta
         * NOTE: stream will be stolen by
         *       wreplsrv_in_connection_merge()
         */
+       process_context = state->io->in.partner->service->task->process_context;
        status = wreplsrv_in_connection_merge(state->io->in.partner,
                                              state->wreplconn->assoc_ctx.peer_ctx,
                                              &stream,
-                                             &wrepl_in);
+                                             &wrepl_in, process_context);
        NT_STATUS_NOT_OK_RETURN(status);
 
        /* now we can free the wreplsrv_out_connection */
index dc28e23..bd2ae26 100644 (file)
@@ -508,5 +508,10 @@ static void wreplsrv_task_init(struct task_server *task)
 */
 NTSTATUS server_service_wrepl_init(TALLOC_CTX *ctx)
 {
-       return register_server_service(ctx, "wrepl", wreplsrv_task_init);
+       struct service_details details = {
+               .inhibit_fork_on_accept = true,
+               .inhibit_pre_fork = true
+       };
+       return register_server_service(ctx, "wrepl", wreplsrv_task_init,
+                                      &details);
 }