/* test request timeouts */ #if 0 /* this test needs fixing to work over ncacn_np */ static bool test_timeout(struct torture_context *tctx, struct dcerpc_pipe *p) { NTSTATUS status; struct rpc_request *req; struct echo_TestSleep r; int timeout_saved = p->request_timeout; if (torture_setting_bool(tctx, "quick", false)) { torture_skip(tctx, "timeout testing disabled - use \"torture:quick=no\" to enable\n"); } torture_comment(tctx, "testing request timeouts\n"); r.in.seconds = 2; p->request_timeout = 1; req = dcerpc_echo_TestSleep_send(p, tctx, &r); if (!req) { torture_comment(tctx, "Failed to send async sleep request\n"); goto failed; } req->ignore_timeout = true; status = dcerpc_ndr_request_recv(req); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_IO_TIMEOUT, "request should have timed out"); torture_comment(tctx, "testing request destruction\n"); req = dcerpc_echo_TestSleep_send(p, tctx, &r); if (!req) { torture_comment(tctx, "Failed to send async sleep request\n"); goto failed; } talloc_free(req); req = dcerpc_echo_TestSleep_send(p, tctx, &r); if (!req) { torture_comment(tctx, "Failed to send async sleep request\n"); goto failed; } req->ignore_timeout = true; status = dcerpc_ndr_request_recv(req); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_IO_TIMEOUT, "request should have timed out"); p->request_timeout = timeout_saved; return test_addone(tctx, p); failed: p->request_timeout = timeout_saved; return false; }
static void init_domain_recv_lsa_policy(struct rpc_request *req) { struct init_domain_state *state = talloc_get_type(req->async.private_data, struct init_domain_state); state->ctx->status = dcerpc_ndr_request_recv(req); if ((!NT_STATUS_IS_OK(state->ctx->status) || !NT_STATUS_IS_OK(state->lsa_openpolicy.out.result))) { if (retry_with_schannel(state, state->domain->lsa_binding, init_domain_recv_lsa_pipe)) { return; } } if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->lsa_openpolicy.out.result; if (!composite_is_ok(state->ctx)) return; state->queryinfo.in.handle = state->domain->lsa_policy_handle; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; req = dcerpc_lsa_QueryInfoPolicy_send(state->domain->lsa_pipe, state, &state->queryinfo); composite_continue_rpc(state->ctx, req, init_domain_recv_queryinfo, state); }
/* a useful helper function for synchronous rpc requests this can be used when you have ndr push/pull functions in the standard format */ _PUBLIC_ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, const struct GUID *object, const struct ndr_interface_table *table, uint32_t opnum, TALLOC_CTX *mem_ctx, void *r) { struct rpc_request *req; req = dcerpc_ndr_request_send(p, object, table, opnum, false, mem_ctx, r); if (req == NULL) { return NT_STATUS_NO_MEMORY; } return dcerpc_ndr_request_recv(req); }
static void init_domain_recv_queryinfo(struct rpc_request *req) { struct init_domain_state *state = talloc_get_type(req->async.private_data, struct init_domain_state); struct lsa_DomainInfo *dominfo; struct composite_context *ctx; state->ctx->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->queryinfo.out.result; if (!composite_is_ok(state->ctx)) return; dominfo = &state->queryinfo.out.info->account_domain; if (strcasecmp(state->domain->info->name, dominfo->name.string) != 0) { DEBUG(2, ("Expected domain name %s, DC %s said %s\n", state->domain->info->name, dcerpc_server_name(state->domain->lsa_pipe), dominfo->name.string)); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } if (!dom_sid_equal(state->domain->info->sid, dominfo->sid)) { DEBUG(2, ("Expected domain sid %s, DC %s said %s\n", dom_sid_string(state, state->domain->info->sid), dcerpc_server_name(state->domain->lsa_pipe), dom_sid_string(state, dominfo->sid))); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } state->domain->samr_binding = init_domain_binding(state, &dcerpc_table_samr); /* We want to use the same flags as the LSA pipe did (so, if * it needed schannel, then we need that here too) */ state->domain->samr_binding->flags = state->domain->lsa_binding->flags; state->domain->samr_pipe = NULL; ctx = wb_connect_samr_send(state, state->domain); composite_continue(state->ctx, ctx, init_domain_recv_samr, state); }
static void unbecomeDC_drsuapi_bind_recv(struct rpc_request *req) { struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; if (!W_ERROR_IS_OK(s->drsuapi.bind_r.out.result)) { composite_error(c, werror_to_ntstatus(s->drsuapi.bind_r.out.result)); return; } ZERO_STRUCT(s->drsuapi.remote_info28); if (s->drsuapi.bind_r.out.bind_info) { switch (s->drsuapi.bind_r.out.bind_info->length) { case 24: { struct drsuapi_DsBindInfo24 *info24; info24 = &s->drsuapi.bind_r.out.bind_info->info.info24; s->drsuapi.remote_info28.supported_extensions = info24->supported_extensions; s->drsuapi.remote_info28.site_guid = info24->site_guid; s->drsuapi.remote_info28.pid = info24->pid; s->drsuapi.remote_info28.repl_epoch = 0; break; } case 48: { struct drsuapi_DsBindInfo48 *info48; info48 = &s->drsuapi.bind_r.out.bind_info->info.info48; s->drsuapi.remote_info28.supported_extensions = info48->supported_extensions; s->drsuapi.remote_info28.site_guid = info48->site_guid; s->drsuapi.remote_info28.pid = info48->pid; s->drsuapi.remote_info28.repl_epoch = info48->repl_epoch; break; } case 28: s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28; break; } } unbecomeDC_drsuapi_remove_ds_server_send(s); }
static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req) { struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; struct drsuapi_DsRemoveDSServer *r = &s->drsuapi.rm_ds_srv_r; c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; if (!W_ERROR_IS_OK(r->out.result)) { composite_error(c, werror_to_ntstatus(r->out.result)); return; } if (*r->out.level_out != 1) { composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } composite_done(c); }
/* test the TestSleep interface */ static bool test_sleep(struct torture_context *tctx, struct dcerpc_pipe *p) { int i; NTSTATUS status; #define ASYNC_COUNT 3 struct rpc_request *req[ASYNC_COUNT]; struct echo_TestSleep r[ASYNC_COUNT]; bool done[ASYNC_COUNT]; struct timeval snd[ASYNC_COUNT]; struct timeval rcv[ASYNC_COUNT]; struct timeval diff[ASYNC_COUNT]; struct tevent_context *ctx; int total_done = 0; if (torture_setting_bool(tctx, "quick", false)) { torture_skip(tctx, "TestSleep disabled - use \"torture:quick=no\" to enable\n"); } torture_comment(tctx, "Testing TestSleep - use \"torture:quick=yes\" to disable\n"); for (i=0;i<ASYNC_COUNT;i++) { done[i] = false; snd[i] = timeval_current(); rcv[i] = timeval_zero(); r[i].in.seconds = ASYNC_COUNT-i; req[i] = dcerpc_echo_TestSleep_send(p, tctx, &r[i]); torture_assert(tctx, req[i], "Failed to send async sleep request\n"); } ctx = dcerpc_event_context(p); while (total_done < ASYNC_COUNT) { torture_assert(tctx, event_loop_once(ctx) == 0, "Event context loop failed"); for (i=0;i<ASYNC_COUNT;i++) { if (done[i] == false && req[i]->state == RPC_REQUEST_DONE) { int rounded_tdiff; total_done++; done[i] = true; rcv[i] = timeval_current(); diff[i] = timeval_until(&snd[i], &rcv[i]); rounded_tdiff = (int)(0.5 + diff[i].tv_sec + (1.0e-6*diff[i].tv_usec)); status = dcerpc_ndr_request_recv(req[i]); torture_comment(tctx, "rounded_tdiff=%d\n", rounded_tdiff); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "TestSleep(%d) failed", i)); torture_assert(tctx, r[i].out.result == r[i].in.seconds, talloc_asprintf(tctx, "Failed - Asked to sleep for %u seconds (server replied with %u seconds and the reply takes only %u seconds)", r[i].out.result, r[i].in.seconds, (unsigned int)diff[i].tv_sec)); torture_assert(tctx, r[i].out.result <= rounded_tdiff, talloc_asprintf(tctx, "Failed - Slept for %u seconds (but reply takes only %u.%06u seconds)", r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec)); if (r[i].out.result+1 == rounded_tdiff) { torture_comment(tctx, "Slept for %u seconds (but reply takes %u.%06u seconds - busy server?)\n", r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec); } else if (r[i].out.result == rounded_tdiff) { torture_comment(tctx, "Slept for %u seconds (reply takes %u.%06u seconds - ok)\n", r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec); } else { torture_comment(tctx, "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)", r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec); /* TODO: let the test fail here, when we support async rpc on ncacn_np */ } } } } torture_comment(tctx, "\n"); return true; }