r8593: register the rpc server with irpc
[sfrench/samba-autobuild/.git] / source4 / rpc_server / dcerpc_sock.c
index 618f5af20f178fa009a3939eb3c654d6e82c792e..cf3ce3cf7e3d704a6f44a96506b6c01840436a81 100644 (file)
 */
 
 #include "includes.h"
-#include "events.h"
+#include "lib/socket/socket.h"
+#include "system/dir.h"
+#include "system/filesys.h"
+#include "lib/events/events.h"
 #include "rpc_server/dcerpc_server.h"
 #include "smbd/service_stream.h"
+#include "lib/messaging/irpc.h"
 
 struct dcesrv_socket_context {
        const struct dcesrv_endpoint *endpoint;
@@ -35,18 +39,17 @@ struct dcesrv_socket_context {
 /*
   write_fn callback for dcesrv_output()
 */
-static ssize_t dcerpc_write_fn(void *private, DATA_BLOB *out)
+static NTSTATUS dcerpc_write_fn(void *private_data, DATA_BLOB *out, size_t *nwritten)
 {
        NTSTATUS status;
-       struct socket_context *sock = private;
+       struct socket_context *sock = talloc_get_type(private_data, struct socket_context);
        size_t sendlen;
 
        status = socket_send(sock, out, &sendlen, 0);
-       if (NT_STATUS_IS_ERR(status)) {
-               return -1;
-       }
+       NT_STATUS_IS_ERR_RETURN(status);
 
-       return sendlen;
+       *nwritten = sendlen;
+       return status;
 }
 
 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
@@ -55,7 +58,7 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons
 }
 
 
-void dcesrv_sock_accept(struct stream_connection *srv_conn)
+static void dcesrv_sock_accept(struct stream_connection *srv_conn)
 {
        NTSTATUS status;
        struct dcesrv_socket_context *dcesrv_sock = 
@@ -75,16 +78,23 @@ void dcesrv_sock_accept(struct stream_connection *srv_conn)
 
        srv_conn->private = dcesrv_conn;
 
+       irpc_add_name(srv_conn->msg_ctx, "rpc_server");
+
        return; 
 }
 
-void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
+static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
 {
        NTSTATUS status;
        struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
        DATA_BLOB tmp_blob;
        size_t nread;
 
+       if (dce_conn->processing) {
+               EVENT_FD_NOT_READABLE(conn->event.fde);
+               return;
+       }
+
        tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
        if (tmp_blob.data == NULL) {
                dcesrv_terminate_connection(dce_conn, "out of memory");
@@ -103,9 +113,13 @@ void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
 
        tmp_blob.length = nread;
 
+       dce_conn->processing = True;
        status = dcesrv_input(dce_conn, &tmp_blob);
+       dce_conn->processing = False;
        talloc_free(tmp_blob.data);
 
+       EVENT_FD_READABLE(conn->event.fde);
+
        if (!NT_STATUS_IS_OK(status)) {
                dcesrv_terminate_connection(dce_conn, nt_errstr(status));
                return;
@@ -116,13 +130,13 @@ void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
        }
 }
 
-void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
+static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
 {
        struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
        NTSTATUS status;
 
        status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (NT_STATUS_IS_ERR(status)) {
                dcesrv_terminate_connection(dce_conn, "eof on socket");
                return;
        }
@@ -149,7 +163,7 @@ static NTSTATUS add_socket_rpc_unix(struct dcesrv_context *dce_ctx, struct dcesr
        uint16_t port = 1;
        NTSTATUS status;
 
-       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
 
        /* remember the endpoint of this socket */
@@ -157,11 +171,11 @@ static NTSTATUS add_socket_rpc_unix(struct dcesrv_context *dce_ctx, struct dcesr
        dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
 
        status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
-                                    "unix", e->ep_description.endpoint, &port, 
+                                    "unix", e->ep_description->endpoint, &port, 
                                     dcesrv_sock);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
-                        e->ep_description.endpoint, nt_errstr(status)));
+                        e->ep_description->endpoint, nt_errstr(status)));
        }
 
        return status;
@@ -175,27 +189,27 @@ static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dc
        char *full_path;
        NTSTATUS status;
 
-       if (!e->ep_description.endpoint) {
+       if (!e->ep_description->endpoint) {
                /* No identifier specified: use DEFAULT. 
                 * DO NOT hardcode this value anywhere else. Rather, specify 
                 * no endpoint and let the epmapper worry about it. */
-               e->ep_description.endpoint = talloc_strdup(dce_ctx, "DEFAULT");
+               e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");
        }
 
-       full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description.endpoint);
+       full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description->endpoint);
 
-       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
 
        /* remember the endpoint of this socket */
        dcesrv_sock->endpoint           = e;
-       dcesrv_sock->dcesrv_ctx         = dce_ctx;
+       dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
 
        status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
                                     "unix", full_path, &port, dcesrv_sock);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
-                        e->ep_description.endpoint, full_path, nt_errstr(status)));
+                        e->ep_description->endpoint, full_path, nt_errstr(status)));
        }
        return status;
 }
@@ -211,16 +225,16 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
        uint16_t port = 0;
        NTSTATUS status;
                        
-       if (e->ep_description.endpoint) {
-               port = atoi(e->ep_description.endpoint);
+       if (e->ep_description->endpoint) {
+               port = atoi(e->ep_description->endpoint);
        }
 
-       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
 
        /* remember the endpoint of this socket */
        dcesrv_sock->endpoint           = e;
-       dcesrv_sock->dcesrv_ctx         = dce_ctx;
+       dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
 
        status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
                                     "ipv4", address, &port, dcesrv_sock);
@@ -229,8 +243,8 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
                         address, port, nt_errstr(status)));
        }
 
-       if (e->ep_description.endpoint == NULL) {
-               e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port);
+       if (e->ep_description->endpoint == NULL) {
+               e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);
        }
 
        return status;
@@ -246,7 +260,7 @@ static NTSTATUS add_socket_rpc_tcp(struct dcesrv_context *dce_ctx, struct dcesrv
                int num_interfaces = iface_count();
                int i;
                for(i = 0; i < num_interfaces; i++) {
-                       const char *address = sys_inet_ntoa(*iface_n_ip(i));
+                       const char *address = iface_n_ip(i);
                        status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
                        NT_STATUS_NOT_OK_RETURN(status);
                }
@@ -268,12 +282,12 @@ NTSTATUS dcesrv_sock_init(struct dcesrv_context *dce_ctx,
        NTSTATUS status;
 
        /* Make sure the directory for NCALRPC exists */
-       if (!directory_exist(lp_ncalrpc_dir(), NULL)) {
+       if (!directory_exist(lp_ncalrpc_dir())) {
                mkdir(lp_ncalrpc_dir(), 0755);
        }
 
        for (e=dce_ctx->endpoint_list;e;e=e->next) {
-               switch (e->ep_description.transport) {
+               switch (e->ep_description->transport) {
                case NCACN_UNIX_STREAM:
                        status = add_socket_rpc_unix(dce_ctx, e, event_ctx, model_ops);
                        NT_STATUS_NOT_OK_RETURN(status);