📄 binding.c
字号:
if (b->options[0] == NULL) b->options = NULL; *b_out = b; return NT_STATUS_OK;}_PUBLIC_ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax){ TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data"); struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx, NULL); enum ndr_err_code ndr_err; uint16_t if_version=0; ndr->flags |= LIBNDR_FLAG_NOALIGN; ndr_err = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return ndr_map_error2ntstatus(ndr_err); } ndr_err = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return ndr_map_error2ntstatus(ndr_err); } syntax->if_version = if_version; talloc_free(mem_ctx); return NT_STATUS_OK;}static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax){ struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx, NULL); ndr->flags |= LIBNDR_FLAG_NOALIGN; ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); return ndr_push_blob(ndr);}const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor){ switch (epm_floor->lhs.protocol) { case EPM_PROTOCOL_TCP: if (epm_floor->rhs.tcp.port == 0) return NULL; return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.tcp.port); case EPM_PROTOCOL_UDP: if (epm_floor->rhs.udp.port == 0) return NULL; return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.udp.port); case EPM_PROTOCOL_HTTP: if (epm_floor->rhs.http.port == 0) return NULL; return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.http.port); case EPM_PROTOCOL_IP: return talloc_strdup(mem_ctx, epm_floor->rhs.ip.ipaddr); case EPM_PROTOCOL_NCACN: return NULL; case EPM_PROTOCOL_NCADG: return NULL; case EPM_PROTOCOL_SMB: if (strlen(epm_floor->rhs.smb.unc) == 0) return NULL; return talloc_strdup(mem_ctx, epm_floor->rhs.smb.unc); case EPM_PROTOCOL_PIPE: if (strlen(epm_floor->rhs.pipe.path) == 0) return NULL; return talloc_strdup(mem_ctx, epm_floor->rhs.pipe.path); case EPM_PROTOCOL_NETBIOS: if (strlen(epm_floor->rhs.netbios.name) == 0) return NULL; return talloc_strdup(mem_ctx, epm_floor->rhs.netbios.name); case EPM_PROTOCOL_NCALRPC: return NULL; case EPM_PROTOCOL_VINES_SPP: return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_spp.port); case EPM_PROTOCOL_VINES_IPC: return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_ipc.port); case EPM_PROTOCOL_STREETTALK: return talloc_strdup(mem_ctx, epm_floor->rhs.streettalk.streettalk); case EPM_PROTOCOL_UNIX_DS: if (strlen(epm_floor->rhs.unix_ds.path) == 0) return NULL; return talloc_strdup(mem_ctx, epm_floor->rhs.unix_ds.path); case EPM_PROTOCOL_NULL: return NULL; default: DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); break; } return NULL;}static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor, const char *data){ switch (epm_floor->lhs.protocol) { case EPM_PROTOCOL_TCP: epm_floor->rhs.tcp.port = atoi(data); return NT_STATUS_OK; case EPM_PROTOCOL_UDP: epm_floor->rhs.udp.port = atoi(data); return NT_STATUS_OK; case EPM_PROTOCOL_HTTP: epm_floor->rhs.http.port = atoi(data); return NT_STATUS_OK; case EPM_PROTOCOL_IP: epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr); return NT_STATUS_OK; case EPM_PROTOCOL_NCACN: epm_floor->rhs.ncacn.minor_version = 0; return NT_STATUS_OK; case EPM_PROTOCOL_NCADG: epm_floor->rhs.ncadg.minor_version = 0; return NT_STATUS_OK; case EPM_PROTOCOL_SMB: epm_floor->rhs.smb.unc = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.smb.unc); return NT_STATUS_OK; case EPM_PROTOCOL_PIPE: epm_floor->rhs.pipe.path = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.pipe.path); return NT_STATUS_OK; case EPM_PROTOCOL_NETBIOS: epm_floor->rhs.netbios.name = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.netbios.name); return NT_STATUS_OK; case EPM_PROTOCOL_NCALRPC: return NT_STATUS_OK; case EPM_PROTOCOL_VINES_SPP: epm_floor->rhs.vines_spp.port = atoi(data); return NT_STATUS_OK; case EPM_PROTOCOL_VINES_IPC: epm_floor->rhs.vines_ipc.port = atoi(data); return NT_STATUS_OK; case EPM_PROTOCOL_STREETTALK: epm_floor->rhs.streettalk.streettalk = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.streettalk.streettalk); return NT_STATUS_OK; case EPM_PROTOCOL_UNIX_DS: epm_floor->rhs.unix_ds.path = talloc_strdup(mem_ctx, data); NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.unix_ds.path); return NT_STATUS_OK; case EPM_PROTOCOL_NULL: return NT_STATUS_OK; default: DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); break; } return NT_STATUS_NOT_SUPPORTED;}enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot){ int i; /* Find a transport that has 'prot' as 4th protocol */ for (i=0;i<ARRAY_SIZE(transports);i++) { if (transports[i].num_protocols >= 2 && transports[i].protseq[1] == prot) { return transports[i].transport; } } /* Unknown transport */ return (unsigned int)-1;}_PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower){ int i; /* Find a transport that matches this tower */ for (i=0;i<ARRAY_SIZE(transports);i++) { int j; if (transports[i].num_protocols != tower->num_floors - 2) { continue; } for (j = 0; j < transports[i].num_protocols; j++) { if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) { break; } } if (j == transports[i].num_protocols) { return transports[i].transport; } } /* Unknown transport */ return (unsigned int)-1;}_PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding **b_out){ NTSTATUS status; struct dcerpc_binding *binding; binding = talloc(mem_ctx, struct dcerpc_binding); NT_STATUS_HAVE_NO_MEMORY(binding); ZERO_STRUCT(binding->object); binding->options = NULL; binding->host = NULL; binding->target_hostname = NULL; binding->flags = 0; binding->assoc_group_id = 0; binding->transport = dcerpc_transport_by_tower(tower); if (binding->transport == (unsigned int)-1) { return NT_STATUS_NOT_SUPPORTED; } if (tower->num_floors < 1) { return NT_STATUS_OK; } /* Set object uuid */ status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status))); return status; } /* Ignore floor 1, it contains the NDR version info */ binding->options = NULL; /* Set endpoint */ if (tower->num_floors >= 4) { binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[3]); } else { binding->endpoint = NULL; } /* Set network address */ if (tower->num_floors >= 5) { binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); NT_STATUS_HAVE_NO_MEMORY(binding->host); binding->target_hostname = binding->host; } *b_out = binding; return NT_STATUS_OK;}_PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower){ 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) { DEBUG(0, ("Unable to find transport with id '%d'\n", binding->transport)); return NT_STATUS_UNSUCCESSFUL; } tower->num_floors = 2 + num_protocols; tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors); /* Floor 0 */ tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &binding->object); tower->floors[0].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); /* Floor 1 */ tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID; tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &ndr_transfer_syntax); tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 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(mem_ctx, NULL, 0); ZERO_STRUCT(tower->floors[2 + i].rhs); dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], ""); } /* The 4th floor contains the endpoint */ if (num_protocols >= 2 && binding->endpoint) { status = dcerpc_floor_set_rhs_data(mem_ctx, &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)) { status = dcerpc_floor_set_rhs_data(mem_ctx, &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(mem_ctx, &tower->floors[4], "0.0.0.0"); } if (NT_STATUS_IS_ERR(status)) { return status; } } return NT_STATUS_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -