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 83641f819f618d5345ec7916194dc18792b82bde..20fa5770f8250c0950ef1df786ff2cfb9d6d80de 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 35a2b99e222eaec7ba5a1e0543162a71ea39e66e..3f845c7e2401f54319d3452a2b0453648c576e1f 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 d4f5f27d0bb48a8f8c13a7e7105d766d6fe02793..6a90e3089f5c325c86d2a6a8e086d7cc7a0716d1 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 ba8431a3d1dfe52f8067c87f9f187c72e4ca34de..10be7ce86fc27417965217f54805d7db79d6128d 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 946a8fef3ecfe80c145d5ce590a5f7a77791323f..a5508aff1a58e4eb79e1c521d5202499b0a35dc8 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 0951a0f0cc0f1c52d62824c0a7753d2be859ba1f..8f16a2efb75e05a38e0affbe2a51b1c172c16a17 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 e6102322cc87275cb43a63075a09cc7f8b900c0a..9a66211ebe8a5dfe3f7edfee612853ec4b561046 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 d5c721b605691fc02512008a1d5bfa73489903fb..788959a737ad18c104e3702c174d0e8a6aec2e00 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 13e338de445413818de06f344be86490819ce5ac..00b5c745fec3dcc22709062c0ed43df7c0d1bc63 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 7febf158a01ed86659dd4d9773469a2613b8567e..d48b03288821572b29c145f868d73955396bd8fa 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 7730ff981caf62912644106fdfcdd3f45303cc49..d12c4e70e028916ec2334298dc9bc98132cfb2d5 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 2196bb045e9a8046a204dcc4b9761ea0e59c808d..834c72f5f7c33a771cebdcdf242fff334b9d8409 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 7949dc2f3b0b0d40743dac3abee396c114b98b56..0884d2f53b55070f0046552f94d10d0cdb2c17c1 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 6a985c5c63c0dbc9ec32b6b3a228a538e6974e00..24eaa65459e466fd651e023ddd68819bdb8d18a9 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 c038075e0ddcc129f883f69c0ddb072631cc243d..f2fb0f69434e47877052154411a2f87e94c26707 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 3ff9f6ff887e72700e4e4a751c72f82bf97720db..eb75184a05f677f2861f734764aa9b8633e37335 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 a607861d6e3fb751d5ecfc09d27ed337d68def21..ddf24a994a8032c1590e0ab70cee2edb961bf7c3 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 7e4c032ab4c80a828c303fd88f358563bfe3aeec..45641a4f2c92884b2db037bfd2f08ed773e2a614 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 40af4a64bb36fd95e4ec6951faa1d435376d1d84..5ddfe78a288ab8b9c8c547f4d74209c83c823a21 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 d7bf3c87c7be91378729f3930cd3a9df214cd28b..656a7f2e29c23c78f21bd83654175ad2934776cc 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 54169e9b0cc2e5fbd141abe2271686711978cad6..1027415a5550ce0b7228c0b816f07a59edc76a59 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 c6cbfc23edad58868c4d3d2c57259b78feba6fdc..431134e03cae7726d287d9f0bb8a189c463c5d08 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 61ed684d00fe4cd3d812e5a2c9e48c8b804e4505..9a77ca80b706986433e51c0d5a9b68599d8593dd 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 23a9e6315b93db53a5489d0d73e65b412e954c7c..2d11f142aed0d703d6ed6f95a0d4515fc1799801 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 c7e31bc47186f5ba272c77bc2d5bf0da5fd6abaf..744f94217176e7bc8de2539dae8d6269aef24190 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 917a1876e07970ed1c66fd010f9e8918173cc835..3f4a04ccf8445cb35c8b1bcb0cd32bfd3a1f5354 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 a7d3def6eae7eaff0a59c145e7c00c6daa6995a8..81bf2754bebe1c7d6870e58316611a0664ddc1e9 100644 (file)
@@ -62,6 +62,7 @@ struct stream_connection {
 
        uint processing;
        const char *terminate;
+       void *process_context;
 };
 
 
index e0e98f644e1c5b51ff120c4051d8a6e97aa70fa0..1d33a43e919cea5ead23c10dcf4296cacacf53c4 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 ded4590daffe05f19f7f05097e000b798233d8e3..2499dc1ddaf4b27902774aa2c627100bc5530204 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 bcae5f8b17bd0025ba34ed0df2c438e97108da25..dd9cd31e8c09af2ef00fb27f42c8b921f0b53de5 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 d854a298a9cbfb46a4f10a9a13af8c2f07dced14..faf1bc65650cc24a9e8620c47b2ff32c689fb8f0 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 c8c0733b6156beb46632e7a2b7f5c7c04ad116db..6aa0418537882bf319beecc76f19f5a184078ce1 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 b8e9a16dc21d24723f6bcef9e37960dcece6cbc4..4920aa0328fe2990e7001a205140474ac996334d 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 782e2f2908f8e57da308bee6c4741cefa781c8c5..0e3f0a458ba714600bbe511bbdebb4f9965d55b0 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 dc28e23371e574bb9cdf1d92eeb7a74cd97a3c4e..bd2ae2660a0a473c44fcc95e214ee3ad780b7505 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);
 }