Merge commit 'release-4-0-0alpha15' into master4-tmp
[kai/samba-autobuild/.git] / source3 / librpc / rpc / dcerpc_ep.c
index bda24a68654798bdd25014a798f37fb9d701642a..3d1acbbee223e74fc5b6e95763a7d4a6fada82e3 100644 (file)
 #include "librpc/rpc/dcerpc_ep.h"
 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
 #include "rpc_client/cli_pipe.h"
+#include "auth.h"
+#include "rpc_server/rpc_ncacn_np.h"
 
 #define EPM_MAX_ANNOTATION_SIZE 64
 
 NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
                                      const struct ndr_interface_table *iface,
                                      uint16_t port,
+                                     const char *ncalrpc,
                                      struct dcerpc_binding_vector **pbvec)
 {
        struct dcerpc_binding_vector *bvec;
@@ -50,7 +53,7 @@ NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       bvec->bindings = talloc_array(bvec, struct dcerpc_binding, ep_count);
+       bvec->bindings = talloc_zero_array(bvec, struct dcerpc_binding, ep_count);
        if (bvec->bindings == NULL) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
@@ -75,7 +78,7 @@ NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
 
                switch (b->transport) {
                        case NCACN_NP:
-                               b->host = talloc_asprintf(b, "\\\\%s", global_myname());
+                               b->host = talloc_asprintf(b, "\\\\%s", lp_netbios_name());
                                if (b->host == NULL) {
                                        status = NT_STATUS_NO_MEMORY;
                                        goto done;
@@ -83,6 +86,7 @@ NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
                                break;
                        case NCACN_IP_TCP:
                                if (port == 0) {
+                                       talloc_free(b);
                                        continue;
                                }
 
@@ -94,8 +98,22 @@ NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
 
                                break;
                        case NCALRPC:
-                               /* TODO */
+                               if (ncalrpc == NULL) {
+                                       talloc_free(b);
+                                       continue;
+                               }
+
+                               b->endpoint = talloc_asprintf(b,
+                                                             "%s/%s",
+                                                             lp_ncalrpc_dir(),
+                                                             ncalrpc);
+                               if (b->endpoint == NULL) {
+                                       status = NT_STATUS_NO_MEMORY;
+                                       goto done;
+                               }
+                               break;
                        default:
+                               talloc_free(b);
                                continue;
                }
 
@@ -114,15 +132,20 @@ done:
        return status;
 }
 
-static NTSTATUS ep_register(const struct ndr_interface_table *iface,
+static NTSTATUS ep_register(TALLOC_CTX *mem_ctx,
+                           const struct ndr_interface_table *iface,
                            const struct dcerpc_binding_vector *bind_vec,
                            const struct GUID *object_guid,
                            const char *annotation,
                            uint32_t replace,
-                           uint32_t unregister)
+                           uint32_t unregister,
+                           struct dcerpc_binding_handle **pbh)
 {
-       struct dcerpc_binding_handle *h = NULL;
-       static struct client_address client_id;
+       struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *h;
+       struct pipe_auth_data *auth;
+       const char *ncalrpc_sock;
+       const char *rpcsrv_type;
        struct epm_entry_t *entries;
        uint32_t num_ents, i;
        TALLOC_CTX *tmp_ctx;
@@ -142,43 +165,61 @@ static NTSTATUS ep_register(const struct ndr_interface_table *iface,
                return NT_STATUS_NO_MEMORY;
        }
 
-#if 0
-       /* NOTE: Samba3 doesn't have a ncalrpc server component yet. As soon as
-        * this is supported, we should talk to the endpoint mapper over the
-        * local transport.
-        */
-
-       /* Connect to the endpoint mapper locally */
-       ncalrpc_sock = talloc_asprintf(tmp_ctx,
-                                     "%s/%s",
-                                     get_dyn_NCALRPCDIR(),
-                                     "epmapper");
-       if (ncalrpc_sock == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto done;
-       }
+       rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+                                          "rpc_server", "epmapper",
+                                          "none");
 
-       status = rpc_pipe_open_ncalrpc(tmp_ctx,
-                                      ncalrpc_sock,
-                                      &ndr_table_epmapper.syntax_id,
-                                      &cli);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto done;
-       }
-#endif
+       if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
+               static struct client_address client_id;
 
-       strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
-       client_id.name = "localhost";
+               strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
+               client_id.name = "localhost";
 
-       status = rpcint_binding_handle(tmp_ctx,
-                                      &ndr_table_epmapper,
-                                      &client_id,
-                                      get_session_info_system(),
-                                      server_messaging_context(),
-                                      &h);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("dcerpc_ep_register: Could not connect to epmapper (%s)",
-                         nt_errstr(status)));
+               status = rpcint_binding_handle(tmp_ctx,
+                                              &ndr_table_epmapper,
+                                              &client_id,
+                                              get_session_info_system(),
+                                              server_messaging_context(),
+                                              &h);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(1, ("dcerpc_ep_register: Could not connect to "
+                                 "epmapper (%s)", nt_errstr(status)));
+                       goto done;
+               }
+       } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
+               /* Connect to the endpoint mapper locally */
+               ncalrpc_sock = talloc_asprintf(tmp_ctx,
+                                             "%s/%s",
+                                             lp_ncalrpc_dir(),
+                                             "EPMAPPER");
+               if (ncalrpc_sock == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
+
+               status = rpc_pipe_open_ncalrpc(tmp_ctx,
+                                              ncalrpc_sock,
+                                              &ndr_table_epmapper.syntax_id,
+                                              &cli);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+
+               status = rpccli_ncalrpc_bind_data(cli, &auth);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0, ("Failed to initialize anonymous bind.\n"));
+                       goto done;
+               }
+
+               status = rpc_pipe_bind(cli, auth);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(2, ("Failed to bind ncalrpc socket.\n"));
+                       goto done;
+               }
+
+               h = cli->binding_handle;
+       } else {
+               status = NT_STATUS_INVALID_PARAMETER;
                goto done;
        }
 
@@ -248,33 +289,63 @@ static NTSTATUS ep_register(const struct ndr_interface_table *iface,
                goto done;
        }
 
+       if (pbh != NULL) {
+               *pbh = talloc_move(mem_ctx, &h);
+               talloc_steal(*pbh, cli);
+       }
+
 done:
        talloc_free(tmp_ctx);
 
        return status;
 }
 
-NTSTATUS dcerpc_ep_register(const struct ndr_interface_table *iface,
+NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx,
+                           const struct ndr_interface_table *iface,
                            const struct dcerpc_binding_vector *bind_vec,
                            const struct GUID *object_guid,
-                           const char *annotation)
+                           const char *annotation,
+                           struct dcerpc_binding_handle **ph)
 {
-       return ep_register(iface, bind_vec, object_guid, annotation, 1, 0);
+       return ep_register(mem_ctx,
+                          iface,
+                          bind_vec,
+                          object_guid,
+                          annotation,
+                          1,
+                          0,
+                          ph);
 }
 
-NTSTATUS dcerpc_ep_register_noreplace(const struct ndr_interface_table *iface,
+NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx,
+                                     const struct ndr_interface_table *iface,
                                      const struct dcerpc_binding_vector *bind_vec,
                                      const struct GUID *object_guid,
-                                     const char *annotation)
+                                     const char *annotation,
+                                     struct dcerpc_binding_handle **ph)
 {
-       return ep_register(iface, bind_vec, object_guid, annotation, 0, 0);
+       return ep_register(mem_ctx,
+                          iface,
+                          bind_vec,
+                          object_guid,
+                          annotation,
+                          0,
+                          0,
+                          ph);
 }
 
 NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface,
                              const struct dcerpc_binding_vector *bind_vec,
                              const struct GUID *object_guid)
 {
-       return ep_register(iface, bind_vec, object_guid, NULL, 0, 1);
+       return ep_register(NULL,
+                          iface,
+                          bind_vec,
+                          object_guid,
+                          NULL,
+                          0,
+                          1,
+                          NULL);
 }
 
 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */