static bool test_Insert(struct torture_context *tctx, struct dcerpc_pipe *p) { NTSTATUS status; struct epm_Insert r; struct dcerpc_binding *bd; r.in.num_ents = 1; r.in.entries = talloc_array(tctx, struct epm_entry_t, 1); ZERO_STRUCT(r.in.entries[0].object); r.in.entries[0].annotation = "smbtorture endpoint"; status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &bd); torture_assert_ntstatus_ok(tctx, status, "Unable to generate dcerpc_binding struct"); r.in.entries[0].tower = talloc(tctx, struct epm_twr_t); status = dcerpc_binding_build_tower(tctx, bd, &r.in.entries[0].tower->tower); torture_assert_ntstatus_ok(tctx, status, "Unable to build tower from binding struct"); r.in.replace = 0; status = dcerpc_epm_Insert(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "Insert failed"); torture_assert(tctx, r.out.result == 0, "Insert failed"); if (!test_Delete(p, tctx, r.in.entries)) { return false; } return true; }
static bool test_Insert(struct torture_context *tctx, struct dcerpc_binding_handle *h, struct ndr_syntax_id object, const char *annotation, struct dcerpc_binding *b) { struct epm_Insert r; NTSTATUS status; r.in.num_ents = 1; r.in.entries = talloc_array(tctx, struct epm_entry_t, 1); if (torture_setting_bool(tctx, "samba4", false)) { torture_skip(tctx, "Skip Insert test against Samba4"); } /* FIXME zero */ ZERO_STRUCT(r.in.entries[0].object); r.in.entries[0].annotation = annotation; r.in.entries[0].tower = talloc(tctx, struct epm_twr_t); status = dcerpc_binding_build_tower(tctx, b, &r.in.entries[0].tower->tower); torture_assert_ntstatus_ok(tctx, status, "Unable to build tower from binding struct"); r.in.replace = 0; /* shoot! */ status = dcerpc_epm_Insert_r(h, tctx, &r); if (NT_STATUS_IS_ERR(status)) { torture_comment(tctx, "epm_Insert failed - %s\n", nt_errstr(status)); return false; } if (r.out.result != EPMAPPER_STATUS_OK) { torture_comment(tctx, "epm_Insert failed - internal error: 0x%.4x\n", r.out.result); return false; } return true; }
static bool test_Insert_noreplace(struct torture_context *tctx, struct dcerpc_pipe *p) { bool ok; NTSTATUS status; struct epm_Insert r; struct dcerpc_binding *b; struct dcerpc_binding_handle *h = p->binding_handle; torture_comment(tctx, "Testing epm_Insert(noreplace) and epm_Delete\n"); if (torture_setting_bool(tctx, "samba4", false)) { torture_skip(tctx, "Skip Insert test against Samba4"); } r.in.num_ents = 1; r.in.entries = talloc_array(tctx, struct epm_entry_t, 1); ZERO_STRUCT(r.in.entries[0].object); r.in.entries[0].annotation = "smbtorture endpoint"; status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &b); torture_assert_ntstatus_ok(tctx, status, "Unable to generate dcerpc_binding struct"); r.in.entries[0].tower = talloc(tctx, struct epm_twr_t); status = dcerpc_binding_build_tower(tctx, b, &r.in.entries[0].tower->tower); torture_assert_ntstatus_ok(tctx, status, "Unable to build tower from binding struct"); r.in.replace = 0; status = dcerpc_epm_Insert_r(h, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "epm_Insert failed"); torture_assert(tctx, r.out.result == 0, "epm_Insert failed"); ok = test_Delete(tctx, h, "smbtorture", b); if (!ok) { return false; } return true; }
static BOOL test_Insert(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct epm_Insert r; struct dcerpc_binding *bd; r.in.num_ents = 1; r.in.entries = talloc_array(mem_ctx, struct epm_entry_t, 1); ZERO_STRUCT(r.in.entries[0].object); r.in.entries[0].annotation = "smbtorture endpoint"; status = dcerpc_parse_binding(mem_ctx, "ncalrpc:[SMBTORTURE]", &bd); if (NT_STATUS_IS_ERR(status)) { printf("Unable to generate dcerpc_binding struct\n"); return False; } r.in.entries[0].tower = talloc(mem_ctx, struct epm_twr_t); status = dcerpc_binding_build_tower(mem_ctx, bd, &r.in.entries[0].tower->tower); if (NT_STATUS_IS_ERR(status)) { printf("Unable to build tower from binding struct\n"); return False; } r.in.replace = 0; status = dcerpc_epm_Insert(p, mem_ctx, &r); if (NT_STATUS_IS_ERR(status)) { printf("Insert failed - %s\n", nt_errstr(status)); return False; } if (r.out.result != 0) { printf("Insert failed - %d\n", r.out.result); printf("NOT CONSIDERING AS A FAILURE\n"); return True; } if (!test_Delete(p, mem_ctx, r.in.entries)) { return False; } return True; }
static bool test_BindingString(struct torture_context *tctx, const void *test_data) { const char *binding = test_data; struct dcerpc_binding *b, *b2; const char *s, *s2; struct epm_tower tower; TALLOC_CTX *mem_ctx = tctx; /* Parse */ torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(mem_ctx, binding, &b), "Error parsing binding string"); s = dcerpc_binding_string(mem_ctx, b); torture_assert(tctx, s != NULL, "Error converting binding back to string"); torture_assert_casestr_equal(tctx, binding, s, "Mismatch while comparing original and regenerated binding strings"); /* Generate protocol towers */ torture_assert_ntstatus_ok(tctx, dcerpc_binding_build_tower(mem_ctx, b, &tower), "Error generating protocol tower"); /* Convert back to binding and then back to string and compare */ torture_assert_ntstatus_ok(tctx, dcerpc_binding_from_tower(mem_ctx, &tower, &b2), "Error generating binding from tower for original binding"); /* Compare to a stripped down version of the binding string because * the protocol tower doesn't contain the extra option data */ b->options = NULL; b->flags = 0; s = dcerpc_binding_string(mem_ctx, b); torture_assert(tctx, s != NULL, "Error converting binding back to string for (stripped down)"); s2 = dcerpc_binding_string(mem_ctx, b2); torture_assert(tctx, s != NULL, "Error converting binding back to string"); if (is_ipaddress(b->host)) torture_assert_casestr_equal(tctx, s, s2, "Mismatch while comparing original and from protocol tower generated binding strings"); return true; }
static bool test_Delete(struct torture_context *tctx, struct dcerpc_binding_handle *h, const char *annotation, struct dcerpc_binding *b) { NTSTATUS status; struct epm_Delete r; r.in.num_ents = 1; r.in.entries = talloc_array(tctx, struct epm_entry_t, 1); ZERO_STRUCT(r.in.entries[0].object); r.in.entries[0].annotation = annotation; r.in.entries[0].tower = talloc(tctx, struct epm_twr_t); status = dcerpc_binding_build_tower(tctx, b, &r.in.entries[0].tower->tower); torture_assert_ntstatus_ok(tctx, status, "Unable to build tower from binding struct"); r.in.num_ents = 1; status = dcerpc_epm_Delete_r(h, tctx, &r); if (NT_STATUS_IS_ERR(status)) { torture_comment(tctx, "epm_Delete failed - %s\n", nt_errstr(status)); return false; } if (r.out.result != EPMAPPER_STATUS_OK) { torture_comment(tctx, "epm_Delete failed - internal error: 0x%.4x\n", r.out.result); return false; } return true; }
/* * Build a list of all interfaces handled by all endpoint servers. */ static uint32_t build_ep_list(TALLOC_CTX *mem_ctx, struct dcesrv_endpoint *endpoint_list, const struct GUID *uuid, const char *srv_addr, struct dcesrv_ep_iface **peps) { struct dcesrv_ep_iface *eps = NULL; struct dcesrv_endpoint *d; uint32_t total = 0; NTSTATUS status; *peps = NULL; for (d = endpoint_list; d != NULL; d = d->next) { struct dcesrv_iface_list *iface; struct dcerpc_binding *description; for (iface = d->iface_list; iface != NULL; iface = iface->next) { if (uuid && !interface_match_by_uuid(iface->iface, uuid)) { continue; } eps = talloc_realloc(mem_ctx, eps, struct dcesrv_ep_iface, total + 1); if (eps == NULL) { return 0; } eps[total].name = talloc_strdup(eps, iface->iface->name); eps[total].syntax_id = iface->iface->syntax_id; description = dcerpc_binding_dup(mem_ctx, d->ep_description); if (description == NULL) { return 0; } description->object = iface->iface->syntax_id; if (description->transport == NCACN_IP_TCP && srv_addr != NULL && (strcmp(description->host, "0.0.0.0") == 0 || strcmp(description->host, "::") == 0)) { description->host = srv_addr; } status = dcerpc_binding_build_tower(eps, description, &eps[total].ep); TALLOC_FREE(description); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to build tower for %s\n", iface->iface->name)); continue; } total++; } } *peps = eps; return total; }
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, struct dcerpc_binding_handle **pbh) { 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; uint32_t result = EPMAPPER_STATUS_OK; NTSTATUS status; if (iface == NULL) { return NT_STATUS_INVALID_PARAMETER; } if (bind_vec == NULL || bind_vec->count == 0) { return NT_STATUS_INVALID_PARAMETER; } tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, "rpc_server", "epmapper", "none"); if (strcasecmp_m(rpcsrv_type, "embedded") == 0) { struct tsocket_address *local; int rc; rc = tsocket_address_inet_from_strings(tmp_ctx, "ip", "127.0.0.1", 0, &local); if (rc < 0) { return NT_STATUS_NO_MEMORY; } status = rpcint_binding_handle(tmp_ctx, &ndr_table_epmapper, local, 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; } num_ents = bind_vec->count; entries = talloc_array(tmp_ctx, struct epm_entry_t, num_ents); for (i = 0; i < num_ents; i++) { struct dcerpc_binding *map_binding = &bind_vec->bindings[i]; struct epm_twr_t *map_tower; map_tower = talloc_zero(entries, struct epm_twr_t); if (map_tower == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } status = dcerpc_binding_build_tower(entries, map_binding, &map_tower->tower); if (!NT_STATUS_IS_OK(status)) { goto done; } entries[i].tower = map_tower; if (annotation == NULL) { entries[i].annotation = talloc_strdup(entries, ""); } else { entries[i].annotation = talloc_strndup(entries, annotation, EPM_MAX_ANNOTATION_SIZE); } if (entries[i].annotation == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } if (object_guid != NULL) { entries[i].object = *object_guid; } else { entries[i].object = map_binding->object.uuid; } } if (unregister) { status = dcerpc_epm_Delete(h, tmp_ctx, num_ents, entries, &result); } else { status = dcerpc_epm_Insert(h, tmp_ctx, num_ents, entries, replace, &result); } if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_ep_register: Could not insert tower (%s)\n", nt_errstr(status))); goto done; } if (result != EPMAPPER_STATUS_OK) { DEBUG(0, ("dcerpc_ep_register: Could not insert tower (0x%.8x)\n", result)); status = NT_STATUS_UNSUCCESSFUL; goto done; } if (pbh != NULL) { *pbh = talloc_move(mem_ctx, &h); talloc_steal(*pbh, cli); } done: talloc_free(tmp_ctx); return status; }
static bool test_Map_tcpip(struct torture_context *tctx, struct dcerpc_binding_handle *h, struct ndr_syntax_id map_syntax) { struct epm_Map r; struct GUID uuid; struct policy_handle entry_handle; struct ndr_syntax_id syntax; struct dcerpc_binding map_binding; struct epm_twr_t map_tower; struct epm_twr_p_t towers[20]; struct epm_tower t; uint32_t num_towers; uint32_t port; uint32_t i; long int p; const char *tmp; const char *ip; char *ptr; NTSTATUS status; torture_comment(tctx, "Testing epm_Map\n"); ZERO_STRUCT(uuid); ZERO_STRUCT(entry_handle); r.in.object = &uuid; r.in.map_tower = &map_tower; r.in.entry_handle = &entry_handle; r.out.entry_handle = &entry_handle; r.in.max_towers = 10; r.out.towers = towers; r.out.num_towers = &num_towers; /* Create map tower */ map_binding.transport = NCACN_IP_TCP; map_binding.object = map_syntax; map_binding.host = "0.0.0.0"; map_binding.endpoint = "135"; status = dcerpc_binding_build_tower(tctx, &map_binding, &map_tower.tower); torture_assert_ntstatus_ok(tctx, status, "epm_Map_tcpip failed: can't create map_tower"); torture_comment(tctx, "epm_Map request for '%s':\n", ndr_interface_name(&map_syntax.uuid, map_syntax.if_version)); display_tower(tctx, &r.in.map_tower->tower); status = dcerpc_epm_Map_r(h, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed"); torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK, "epm_Map_tcpip failed: result is not EPMAPPER_STATUS_OK"); /* Check the result */ t = r.out.towers[0].twr->tower; /* Check if we got the correct RPC interface identifier */ dcerpc_floor_get_lhs_data(&t.floors[0], &syntax); torture_assert(tctx, ndr_syntax_id_equal(&syntax, &map_syntax), "epm_Map_tcpip failed: Interface identifier mismatch"); torture_comment(tctx, "epm_Map_tcpip response for '%s':\n", ndr_interface_name(&syntax.uuid, syntax.if_version)); dcerpc_floor_get_lhs_data(&t.floors[1], &syntax); torture_assert(tctx, ndr_syntax_id_equal(&syntax, &ndr_transfer_syntax_ndr), "epm_Map_tcpip failed: floor 2 is not NDR encoded"); torture_assert(tctx, t.floors[2].lhs.protocol == EPM_PROTOCOL_NCACN, "epm_Map_tcpip failed: floor 3 is not NCACN_IP_TCP"); tmp = dcerpc_floor_get_rhs_data(tctx, &t.floors[3]); p = strtol(tmp, &ptr, 10); port = p & 0xffff; torture_assert(tctx, port > 1024 && port < 65535, "epm_Map_tcpip failed"); ip = dcerpc_floor_get_rhs_data(tctx, &t.floors[4]); torture_assert(tctx, is_ipaddress(ip), "epm_Map_tcpip failed"); for (i = 0; i < *r.out.num_towers; i++) { if (r.out.towers[i].twr) { display_tower(tctx, &t); } } return true; }