TODO binding floor
authorStefan Metzmacher <metze@samba.org>
Fri, 24 Jan 2014 06:37:14 +0000 (07:37 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:56:53 +0000 (12:56 +0200)
librpc/rpc/binding.c

index 56487f69f30dbbc97f178d3421c431b70eb4d12c..670d7e78c2637ad8d515ea61c187b26b4ccf18c8 100644 (file)
@@ -1301,30 +1301,28 @@ static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct nd
        return blob;
 }
 
-static bool dcerpc_floor_pack_rhs_if_version_data(
-       TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax,
-       DATA_BLOB *pblob)
+static DATA_BLOB dcerpc_floor_pack_rhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax)
 {
        DATA_BLOB blob;
-       struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx);
        enum ndr_err_code ndr_err;
+       struct ndr_push *ndr;
 
+       ndr = ndr_push_init_ctx(mem_ctx);
        if (ndr == NULL) {
-               return false;
+               return data_blob_null;
        }
 
        ndr->flags |= LIBNDR_FLAG_NOALIGN;
 
        ndr_err = ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version >> 16);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return false;
+               return data_blob_null;
        }
 
        blob = ndr_push_blob(ndr);
        talloc_steal(mem_ctx, blob.data);
        talloc_free(ndr);
-       *pblob = blob;
-       return true;
+       return blob;
 }
 
 char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
@@ -1758,7 +1756,7 @@ _PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx,
 
        tower->num_floors = 2 + num_protocols;
        tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors);
-
+       if (
        /* Floor 0 */
        tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
 
@@ -1815,3 +1813,93 @@ _PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx,
 
        return NT_STATUS_OK;
 }
+
+_PUBLIC_ NTSTATUS dcerpc_build_epm_tower_floors(TALLOC_CTX *mem_ctx,
+                                       const struct dcerpc_binding *binding,
+                                       const struct ndr_syntax_id *abstract,
+                                       const struct ndr_syntax_id *transfer,
+                                       uint16_t *_num_floors,
+                                       struct epm_floor *_floors);
+{
+       uint16_t *num_floors;
+       struct epm_floor *floors;
+       const enum epm_protocol *protseq = NULL;
+       int num_protocols = -1, i;
+       NTSTATUS status;
+
+       /* Find transport */
+       for (i=0;i<ARRAY_SIZE(transports);i++) {
+               if (transports[i].transport == binding->transport) {
+                       protseq = transports[i].protseq;
+                       num_protocols = transports[i].num_protocols;
+                       break;
+               }
+       }
+
+       if (num_protocols == -1) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       num_floors = 2 + num_protocols;
+       floors = talloc_array(mem_ctx, struct epm_floor, num_floors);
+       if (floors == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* Floor 0 */
+       floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
+
+       floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors, abstract);
+
+       ok = dcerpc_floor_pack_rhs_if_version_data(ower->floors, abstract,
+                               &tower->floors[0].rhs.uuid.unknown);
+       if (!ok) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* Floor 1 */
+       tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID;
+
+       tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors,
+                                                               &ndr_transfer_syntax_ndr);
+
+       tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(tower->floors, 2);
+
+       /* Floor 2 to num_protocols */
+       for (i = 0; i < num_protocols; i++) {
+               tower->floors[2 + i].lhs.protocol = protseq[i];
+               tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(tower->floors, NULL, 0);
+               ZERO_STRUCT(tower->floors[2 + i].rhs);
+               dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[2 + i], "");
+       }
+
+       /* The 4th floor contains the endpoint */
+       if (num_protocols >= 2 && binding->endpoint) {
+               status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[3], binding->endpoint);
+               if (NT_STATUS_IS_ERR(status)) {
+                       return status;
+               }
+       }
+
+       /* The 5th contains the network address */
+       if (num_protocols >= 3 && binding->host) {
+               if (is_ipaddress(binding->host) ||
+                   (binding->host[0] == '\\' && binding->host[1] == '\\')) {
+                       status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4],
+                                                          binding->host);
+               } else {
+                       /* note that we don't attempt to resolve the
+                          name here - when we get a hostname here we
+                          are in the client code, and want to put in
+                          a wildcard all-zeros IP for the server to
+                          fill in */
+                       status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4],
+                                                          "0.0.0.0");
+               }
+               if (NT_STATUS_IS_ERR(status)) {
+                       return status;
+               }
+       }
+
+       return NT_STATUS_OK;
+}