s3-rpc_server: Add create_dcerpc_ncalrpc_socket().
[idra/samba.git] / source3 / rpc_server / rpc_server.c
index 9134b958abb0f209e53be91a63ee95e621468b9a..c995e22ea05bb03ba0575dc0864fd8481c1b37e3 100644 (file)
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "rpc_server/rpc_pipes.h"
 #include "rpc_server/rpc_server.h"
+#include "rpc_server/rpc_config.h"
 #include "rpc_dce.h"
 #include "librpc/gen_ndr/netlogon.h"
 #include "librpc/gen_ndr/auth.h"
@@ -160,28 +161,10 @@ static void named_pipe_listener(struct tevent_context *ev,
                                uint16_t flags,
                                void *private_data);
 
-bool setup_named_pipe_socket(const char *pipe_name,
-                            struct tevent_context *ev_ctx,
-                            struct messaging_context *msg_ctx)
+int create_named_pipe_socket(const char *pipe_name)
 {
-       struct dcerpc_ncacn_listen_state *state;
-       struct tevent_fd *fde;
-       char *np_dir;
-
-       state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
-       if (!state) {
-               DEBUG(0, ("Out of memory\n"));
-               return false;
-       }
-       state->ep.name = talloc_strdup(state, pipe_name);
-       if (state->ep.name == NULL) {
-               DEBUG(0, ("Out of memory\n"));
-               goto out;
-       }
-       state->fd = -1;
-
-       state->ev_ctx = ev_ctx;
-       state->msg_ctx = msg_ctx;
+       char *np_dir = NULL;
+       int fd = -1;
 
        /*
         * As lp_ncalrpc_dir() should have 0755, but
@@ -194,7 +177,7 @@ bool setup_named_pipe_socket(const char *pipe_name,
                goto out;
        }
 
-       np_dir = talloc_asprintf(state, "%s/np", lp_ncalrpc_dir());
+       np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
        if (!np_dir) {
                DEBUG(0, ("Out of memory\n"));
                goto out;
@@ -206,13 +189,44 @@ bool setup_named_pipe_socket(const char *pipe_name,
                goto out;
        }
 
-       state->fd = create_pipe_sock(np_dir, pipe_name, 0700);
-       if (state->fd == -1) {
+       fd = create_pipe_sock(np_dir, pipe_name, 0700);
+       if (fd == -1) {
                DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
                          np_dir, pipe_name));
                goto out;
        }
+
+       DEBUG(10, ("Openened pipe socket fd %d for %s\n", fd, pipe_name));
+
+out:
        talloc_free(np_dir);
+       return fd;
+}
+
+bool setup_named_pipe_socket(const char *pipe_name,
+                            struct tevent_context *ev_ctx,
+                            struct messaging_context *msg_ctx)
+{
+       struct dcerpc_ncacn_listen_state *state;
+       struct tevent_fd *fde;
+
+       state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
+       if (!state) {
+               DEBUG(0, ("Out of memory\n"));
+               return false;
+       }
+       state->ep.name = talloc_strdup(state, pipe_name);
+       if (state->ep.name == NULL) {
+               DEBUG(0, ("Out of memory\n"));
+               goto out;
+       }
+       state->fd = create_named_pipe_socket(pipe_name);
+       if (state->fd == -1) {
+               goto out;
+       }
+
+       state->ev_ctx = ev_ctx;
+       state->msg_ctx = msg_ctx;
 
        DEBUG(10, ("Openened pipe socket fd %d for %s\n",
                   state->fd, pipe_name));
@@ -236,11 +250,6 @@ out:
        return false;
 }
 
-static void named_pipe_accept_function(struct tevent_context *ev_ctx,
-                                      struct messaging_context *msg_ctx,
-                                      const char *pipe_name,
-                                      int fd);
-
 static void named_pipe_listener(struct tevent_context *ev,
                                struct tevent_fd *fde,
                                uint16_t flags,
@@ -273,7 +282,7 @@ static void named_pipe_listener(struct tevent_context *ev,
        named_pipe_accept_function(state->ev_ctx,
                                   state->msg_ctx,
                                   state->ep.name,
-                                  sd);
+                                  sd, NULL, 0);
 }
 
 
@@ -306,14 +315,26 @@ struct named_pipe_client {
 
        struct iovec *iov;
        size_t count;
+
+       named_pipe_termination_fn *term_fn;
+       void *private_data;
 };
 
+static int named_pipe_destructor(struct named_pipe_client *npc)
+{
+       if (npc->term_fn) {
+               npc->term_fn(npc->private_data);
+       }
+       return 0;
+}
+
 static void named_pipe_accept_done(struct tevent_req *subreq);
 
-static void named_pipe_accept_function(struct tevent_context *ev_ctx,
-                                      struct messaging_context *msg_ctx,
-                                      const char *pipe_name,
-                                      int fd)
+void named_pipe_accept_function(struct tevent_context *ev_ctx,
+                               struct messaging_context *msg_ctx,
+                               const char *pipe_name, int fd,
+                               named_pipe_termination_fn *term_fn,
+                               void *private_data)
 {
        struct named_pipe_client *npc;
        struct tstream_context *plain;
@@ -336,6 +357,10 @@ static void named_pipe_accept_function(struct tevent_context *ev_ctx,
        }
        npc->ev = ev_ctx;
        npc->msg_ctx = msg_ctx;
+       npc->term_fn = term_fn;
+       npc->private_data = private_data;
+
+       talloc_set_destructor(npc, named_pipe_destructor);
 
        /* make sure socket is in NON blocking state */
        ret = set_blocking(fd, false);
@@ -615,15 +640,6 @@ fail:
        return;
 }
 
-static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
-                               struct messaging_context *msg_ctx,
-                               enum dcerpc_transport_t transport,
-                               const char *name,
-                               struct tsocket_address *cli_addr,
-                               struct tsocket_address *srv_addr,
-                               int s,
-                               dcerpc_ncacn_disconnect_fn fn);
-
 /********************************************************************
  * Start listening on the tcp/ip socket
  ********************************************************************/
@@ -803,6 +819,32 @@ static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
                                    uint16_t flags,
                                    void *private_data);
 
+int create_dcerpc_ncalrpc_socket(const char *name)
+{
+       int fd = -1;
+
+       if (name == NULL) {
+               name = "DEFAULT";
+       }
+
+       if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
+               DEBUG(0, ("Failed to create ncalrpc directory %s - %s\n",
+                         lp_ncalrpc_dir(), strerror(errno)));
+               return -1;
+       }
+
+       fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
+       if (fd == -1) {
+               DEBUG(0, ("Failed to create ncalrpc socket! [%s/%s]\n",
+                         lp_ncalrpc_dir(), name));
+               return -1;
+       }
+
+       DEBUG(10, ("Openened ncalrpc socket fd %d for %s\n", fd, name));
+
+       return fd;
+}
+
 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
                                 struct messaging_context *msg_ctx,
                                 const char *name,
@@ -823,29 +865,19 @@ bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
        if (name == NULL) {
                name = "DEFAULT";
        }
-       state->ep.name = talloc_strdup(state, name);
 
+       state->ep.name = talloc_strdup(state, name);
        if (state->ep.name == NULL) {
                DEBUG(0, ("Out of memory\n"));
                talloc_free(state);
                return false;
        }
 
-       if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
-               DEBUG(0, ("Failed to create pipe directory %s - %s\n",
-                         lp_ncalrpc_dir(), strerror(errno)));
-               goto out;
-       }
-
-       state->fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
+       state->fd = create_dcerpc_ncalrpc_socket(name);
        if (state->fd == -1) {
-               DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
-                         lp_ncalrpc_dir(), name));
                goto out;
        }
 
-       DEBUG(10, ("Openened pipe socket fd %d for %s\n", state->fd, name));
-
        state->ev_ctx = ev_ctx;
        state->msg_ctx = msg_ctx;
 
@@ -945,14 +977,14 @@ struct dcerpc_ncacn_conn {
 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
 
-static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
-                               struct messaging_context *msg_ctx,
-                               enum dcerpc_transport_t transport,
-                               const char *name,
-                               struct tsocket_address *cli_addr,
-                               struct tsocket_address *srv_addr,
-                               int s,
-                               dcerpc_ncacn_disconnect_fn fn) {
+void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
+                        struct messaging_context *msg_ctx,
+                        enum dcerpc_transport_t transport,
+                        const char *name,
+                        struct tsocket_address *cli_addr,
+                        struct tsocket_address *srv_addr,
+                        int s,
+                        dcerpc_ncacn_disconnect_fn fn) {
        struct dcerpc_ncacn_conn *ncacn_conn;
        struct tevent_req *subreq;
        bool system_user = false;