static bool test_handles_drsuapi(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; struct policy_handle handle; struct policy_handle handle2; struct GUID bind_guid; struct drsuapi_DsBind r; struct drsuapi_DsUnbind c; TALLOC_CTX *mem_ctx = talloc_new(torture); torture_comment(torture, "RPC-HANDLE-DRSUAPI\n"); status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_drsuapi); torture_assert_ntstatus_ok(torture, status, "opening drsuapi pipe1"); status = torture_rpc_connection(mem_ctx, &p2, &dcerpc_table_drsuapi); torture_assert_ntstatus_ok(torture, status, "opening drsuapi pipe1"); GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid); r.in.bind_guid = &bind_guid; r.in.bind_info = NULL; r.out.bind_handle = &handle; status = dcerpc_drsuapi_DsBind(p1, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { torture_comment(torture, "drsuapi_DsBind not supported - skipping\n"); talloc_free(mem_ctx); return true; } c.in.bind_handle = &handle; c.out.bind_handle = &handle2; status = dcerpc_drsuapi_DsUnbind(p2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT, "closing policy handle on p2"); torture_assert_int_equal(torture, p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, "closing policy handle on p2"); status = dcerpc_drsuapi_DsUnbind(p1, mem_ctx, &c); torture_assert_ntstatus_ok(torture, status, "closing policy handle on p1"); status = dcerpc_drsuapi_DsUnbind(p1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT, "closing policy handle on p1 again"); torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, "closing policy handle on p1 again"); talloc_free(mem_ctx); return true; }
static bool test_handles_samr(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; struct dcerpc_binding_handle *b1, *b2; struct policy_handle handle; struct policy_handle handle2; struct samr_Connect r; struct samr_Close c; TALLOC_CTX *mem_ctx = talloc_new(torture); torture_comment(torture, "RPC-HANDLE-SAMR\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); b1 = p1->binding_handle; status = torture_rpc_connection(torture, &p2, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe2"); b2 = p2->binding_handle; r.in.system_name = 0; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.connect_handle = &handle; torture_assert_ntstatus_ok(torture, dcerpc_samr_Connect_r(b1, mem_ctx, &r), "Connect failed"); torture_assert_ntstatus_ok(torture, r.out.result, "opening policy handle on p1"); c.in.handle = &handle; c.out.handle = &handle2; status = dcerpc_samr_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_samr_Close_r(b1, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_ok(torture, c.out.result, "closing policy handle on p1"); status = dcerpc_samr_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); talloc_free(mem_ctx); return true; }
bool torture_delshare(struct torture_context *torture) { struct dcerpc_pipe *p; struct dcerpc_binding *binding; struct libnet_context* libnetctx; const char *host; NTSTATUS status; bool ret = true; struct libnet_DelShare share; host = torture_setting_string(torture, "host", NULL); status = torture_rpc_binding(torture, &binding); torture_assert_ntstatus_ok(torture, status, "Failed to get binding"); libnetctx = libnet_context_init(torture->ev, torture->lp_ctx); libnetctx->cred = popt_get_cmdline_credentials(); status = torture_rpc_connection(torture, &p, &ndr_table_srvsvc); torture_assert_ntstatus_ok(torture, status, "Failed to get rpc connection"); if (!test_addshare(torture, p->binding_handle, torture, host, TEST_SHARENAME)) { return false; } share.in.server_name = dcerpc_binding_get_string_option(binding, "host"); share.in.share_name = TEST_SHARENAME; status = libnet_DelShare(libnetctx, torture, &share); torture_assert_ntstatus_ok(torture, status, "Failed to delete share"); return ret; }
BOOL torture_rpc_epmapper(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; TALLOC_CTX *mem_ctx; BOOL ret = True; mem_ctx = talloc_init("torture_rpc_epmapper"); status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_epmapper); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return False; } if (!test_Lookup(p, mem_ctx)) { ret = False; } if (!test_Insert(p, mem_ctx)) { ret = False; } if (!test_InqObject(p, mem_ctx)) { ret = False; } talloc_free(mem_ctx); return ret; }
bool torture_usermod(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; struct policy_handle h; struct lsa_String domain_name; struct dom_sid2 sid; uint32_t rid; int i; char *name; TALLOC_CTX *mem_ctx; bool ret = true; struct dcerpc_binding_handle *b; mem_ctx = talloc_init("test_userdel"); status = torture_rpc_connection(torture, &p, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "RPC connect"); b = p->binding_handle; domain_name.string = lpcfg_workgroup(torture->lp_ctx); name = talloc_strdup(mem_ctx, TEST_USERNAME); if (!test_domain_open(torture, b, &domain_name, mem_ctx, &h, &sid)) { ret = false; goto done; } if (!test_user_create(torture, b, mem_ctx, &h, name, &rid)) { ret = false; goto done; } for (i = USER_FIELD_FIRST; i <= USER_FIELD_LAST; i++) { struct libnet_rpc_usermod m; if (!test_usermod(torture, p, mem_ctx, &h, i, &m, &name)) { ret = false; goto cleanup; } if (!test_compare(torture, p, mem_ctx, &h, &m, name)) { ret = false; goto cleanup; } } cleanup: if (!test_user_cleanup(torture, b, mem_ctx, &h, TEST_USERNAME)) { ret = false; goto done; } done: talloc_free(mem_ctx); return ret; }
BOOL torture_rpc_svcctl(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; struct policy_handle h; TALLOC_CTX *mem_ctx; BOOL ret = True; mem_ctx = talloc_init("torture_rpc_svcctl"); status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_svcctl); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return False; } if (!test_OpenSCManager(p, mem_ctx, &h)) { ret = False; } if (!test_EnumServicesStatus(p, mem_ctx, &h)) { ret = False; } if (!test_CloseServiceHandle(p, mem_ctx, &h)) { ret = False; } talloc_free(mem_ctx); return ret; }
static bool test_handles_samr(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; struct policy_handle handle; struct policy_handle handle2; struct samr_Connect r; struct samr_Close c; TALLOC_CTX *mem_ctx = talloc_new(torture); torture_comment(torture, "RPC-HANDLE-SAMR\n"); status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); status = torture_rpc_connection(mem_ctx, &p2, &dcerpc_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); r.in.system_name = 0; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.connect_handle = &handle; status = dcerpc_samr_Connect(p1, mem_ctx, &r); torture_assert_ntstatus_ok(torture, status, "opening policy handle on p1"); c.in.handle = &handle; c.out.handle = &handle2; status = dcerpc_samr_Close(p2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT, "closing policy handle on p2"); torture_assert_int_equal(torture, p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, "closing policy handle on p2"); status = dcerpc_samr_Close(p1, mem_ctx, &c); torture_assert_ntstatus_ok(torture, status, "closing policy handle on p1"); status = dcerpc_samr_Close(p1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT, "closing policy handle on p1 again"); torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, "closing policy handle on p1 again"); talloc_free(mem_ctx); return true; }
static bool test_random_uuid(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; struct rpc_request *req; struct GUID uuid; struct dssetup_DsRoleGetPrimaryDomainInformation r1; struct lsa_GetUserName r2; struct lsa_String *authority_name_p = NULL; struct lsa_String *account_name_p = NULL; torture_comment(torture, "RPC-OBJECTUUID-RANDOM\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_dssetup); torture_assert_ntstatus_ok(torture, status, "opening dsetup pipe1"); status = torture_rpc_connection(torture, &p2, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); uuid = GUID_random(); r1.in.level = DS_ROLE_BASIC_INFORMATION; status = dcerpc_ndr_request(p1, &uuid, &ndr_table_dssetup, NDR_DSSETUP_DSROLEGETPRIMARYDOMAININFORMATION, torture, &r1); torture_assert_ntstatus_ok(torture, status, "DsRoleGetPrimaryDomainInformation failed"); torture_assert_werr_ok(torture, r1.out.result, "DsRoleGetPrimaryDomainInformation failed"); uuid = GUID_random(); r2.in.system_name = "\\"; r2.in.account_name = &account_name_p; r2.in.authority_name = &authority_name_p; r2.out.account_name = &account_name_p; r2.out.authority_name = &authority_name_p; status = dcerpc_ndr_request(p2, &uuid, &ndr_table_lsarpc, NDR_LSA_GETUSERNAME, torture, &r2); torture_assert_ntstatus_ok(torture, status, "lsaClose failed"); torture_assert_ntstatus_ok(torture, r2.out.result, "lsaClose failed"); return true; }
static bool test_rpc_netservergetinfo(struct torture_context *tctx, struct smbcli_state *cli) { struct rap_WserverGetInfo r; struct dcerpc_pipe *p; struct dcerpc_binding_handle *b; struct srvsvc_NetSrvGetInfo s; union srvsvc_NetSrvInfo info; const char *server_name; torture_assert_ntstatus_ok(tctx, torture_rpc_connection(tctx, &p, &ndr_table_srvsvc), "failed to open srvsvc"); b = p->binding_handle; s.in.server_unc = NULL; s.in.level = 101; s.out.info = &info; torture_assert_ntstatus_ok(tctx, dcerpc_srvsvc_NetSrvGetInfo_r(b, tctx, &s), "srvsvc_NetSrvGetInfo level 101 failed"); torture_assert_werr_ok(tctx, s.out.result, "srvsvc_NetSrvGetInfo level 101 failed"); r.in.bufsize = 0xffff; r.in.level = 0; torture_assert_ntstatus_ok(tctx, smbcli_rap_netservergetinfo(cli->tree, tctx, &r), "rap_netservergetinfo level 0 failed"); torture_assert_int_equal(tctx, r.out.status, 0, "rap_netservergetinfo level 0 failed"); server_name = talloc_strndup(tctx, info.info101->server_name, 16); torture_assert_str_equal(tctx, (const char *)r.out.info.info0.name, server_name, "server name"); r.in.level = 1; torture_assert_ntstatus_ok(tctx, smbcli_rap_netservergetinfo(cli->tree, tctx, &r), "rap_netservergetinfo level 1 failed"); torture_assert_int_equal(tctx, r.out.status, 0, "rap_netservergetinfo level 1 failed"); torture_assert_str_equal(tctx, (const char *)r.out.info.info1.name, server_name, "server name"); torture_assert_int_equal(tctx, r.out.info.info1.version_major, info.info101->version_major, "version major"); torture_assert_int_equal(tctx, r.out.info.info1.version_minor, info.info101->version_minor, "version minor"); torture_assert_int_equal(tctx, r.out.info.info1.servertype, info.info101->server_type, "server_type"); torture_assert_str_equal(tctx, r.out.info.info1.comment, info.info101->comment, "comment"); talloc_free(p); return true; }
/** * Create and initialize libnet_context Context. * Use this function in cases where we need to have SAMR and LSA pipes * of libnet_context to be connected before executing any other * libnet call * * @param rpc_connect [in] Connects SAMR and LSA pipes */ bool test_libnet_context_init(struct torture_context *tctx, bool rpc_connect, struct libnet_context **_net_ctx) { NTSTATUS status; bool bret = true; struct libnet_context *net_ctx; net_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx); torture_assert(tctx, net_ctx != NULL, "Failed to create libnet_context"); /* Use command line credentials for testing */ net_ctx->cred = cmdline_credentials; if (rpc_connect) { /* connect SAMR pipe */ status = torture_rpc_connection(tctx, &net_ctx->samr.pipe, &ndr_table_samr); torture_assert_ntstatus_ok_goto(tctx, status, bret, done, "Failed to connect SAMR pipe"); net_ctx->samr.samr_handle = net_ctx->samr.pipe->binding_handle; /* connect LSARPC pipe */ status = torture_rpc_connection(tctx, &net_ctx->lsa.pipe, &ndr_table_lsarpc); torture_assert_ntstatus_ok_goto(tctx, status, bret, done, "Failed to connect LSA pipe"); net_ctx->lsa.lsa_handle = net_ctx->lsa.pipe->binding_handle; } *_net_ctx = net_ctx; done: if (!bret) { /* a previous call has failed, * clean up memory before exit */ talloc_free(net_ctx); } return bret; }
bool torture_useradd(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; struct policy_handle h; struct lsa_String domain_name; struct dom_sid2 sid; const char *name = TEST_USERNAME; TALLOC_CTX *mem_ctx; bool ret = true; struct dcerpc_binding_handle *b; mem_ctx = talloc_init("test_useradd"); status = torture_rpc_connection(torture, &p, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "RPC connect failed"); b = p->binding_handle; domain_name.string = lpcfg_workgroup(torture->lp_ctx); if (!test_domain_open(torture, b, &domain_name, mem_ctx, &h, &sid)) { ret = false; goto done; } if (!test_useradd(torture, p, mem_ctx, &h, name)) { ret = false; goto done; } if (!test_user_cleanup(torture, b, mem_ctx, &h, name)) { ret = false; goto done; } if (!test_domain_open(torture, b, &domain_name, mem_ctx, &h, &sid)) { ret = false; goto done; } if (!test_useradd_async(torture, p, mem_ctx, &h, name)) { ret = false; goto done; } if (!test_user_cleanup(torture, b, mem_ctx, &h, name)) { ret = false; goto done; } done: talloc_free(mem_ctx); return ret; }
bool torture_groupinfo(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; TALLOC_CTX *mem_ctx; bool ret = true; struct policy_handle h; struct lsa_String name; struct dom_sid2 sid; uint32_t rid; struct dcerpc_binding_handle *b; mem_ctx = talloc_init("test_userinfo"); status = torture_rpc_connection(torture, &p, &ndr_table_samr); if (!NT_STATUS_IS_OK(status)) { return false; } b = p->binding_handle; name.string = lpcfg_workgroup(torture->lp_ctx); /* * Testing synchronous version */ if (!test_domain_open(torture, b, &name, mem_ctx, &h, &sid)) { ret = false; goto done; } if (!test_group_create(torture, b, mem_ctx, &h, TEST_GROUPNAME, &rid)) { ret = false; goto done; } if (!test_groupinfo(torture, p, mem_ctx, &h, &sid, TEST_GROUPNAME, &rid)) { ret = false; goto done; } if (!test_group_cleanup(torture, b, mem_ctx, &h, TEST_GROUPNAME)) { ret = false; goto done; } done: talloc_free(mem_ctx); return ret; }
static bool torture_rpc_spoolss_access_teardown_common(struct torture_context *tctx, struct torture_access_context *t) { if (t->user.testuser) { torture_leave_domain(tctx, t->user.testuser); } /* remove membership ? */ if (t->user.num_builtin_memberships) { } /* remove privs ? */ if (t->user.num_privs) { } /* restore sd */ if (t->user.sd && t->printername) { struct policy_handle handle; struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_SetPrinterInfo3 info3; struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; struct dcerpc_pipe *spoolss_pipe; struct dcerpc_binding_handle *b; torture_assert_ntstatus_ok(tctx, torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss), "Error connecting to server"); b = spoolss_pipe->binding_handle; ZERO_STRUCT(info_ctr); ZERO_STRUCT(info3); ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(secdesc_ctr); info_ctr.level = 3; info_ctr.info.info3 = &info3; secdesc_ctr.sd = t->sd_orig; torture_assert(tctx, test_openprinter_handle(tctx, spoolss_pipe, "", t->printername, "", SEC_FLAG_MAXIMUM_ALLOWED, WERR_OK, &handle), "failed to open printer"); torture_assert(tctx, test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0), "failed to set sd"); talloc_free(spoolss_pipe); } return true; }
static void reopen(struct torture_context *tctx, struct dcerpc_pipe **p, const struct ndr_interface_table *iface) { NTSTATUS status; talloc_free(*p); status = torture_rpc_connection(tctx, p, iface); if (!NT_STATUS_IS_OK(status)) { printf("Failed to reopen '%s' - %s\n", iface->name, nt_errstr(status)); exit(1); } }
BOOL torture_delshare(struct torture_context *torture) { struct dcerpc_pipe *p; struct dcerpc_binding *bind; struct libnet_context* libnetctx; const char *host, *binding; TALLOC_CTX *mem_ctx; NTSTATUS status; BOOL ret = True; struct libnet_DelShare share; mem_ctx = talloc_init("test_listshares"); host = torture_setting_string(torture, "host", NULL); binding = torture_setting_string(torture, "binding", NULL); status = dcerpc_parse_binding(mem_ctx, binding, &bind); if (!NT_STATUS_IS_OK(status)) { printf("Error while parsing the binding string\n"); ret = False; goto done; } libnetctx = libnet_context_init(NULL); libnetctx->cred = cmdline_credentials; status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_srvsvc); if (!test_addshare(p, mem_ctx, host, TEST_SHARENAME)) { ret = False; goto done; } share.in.server_name = bind->host; share.in.share_name = TEST_SHARENAME; status = libnet_DelShare(libnetctx, mem_ctx, &share); if (!NT_STATUS_IS_OK(status)) { ret = False; goto done; } done: talloc_free(mem_ctx); return ret; }
static bool torture_rpc_setup (struct torture_context *tctx, void **data) { NTSTATUS status; struct torture_rpc_tcase *tcase = talloc_get_type( tctx->active_tcase, struct torture_rpc_tcase); struct torture_rpc_tcase_data *tcase_data; *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data); tcase_data->credentials = popt_get_cmdline_credentials(); status = torture_rpc_connection(tctx, &(tcase_data->pipe), tcase->table); torture_assert_ntstatus_ok(tctx, status, "Error connecting to server"); return NT_STATUS_IS_OK(status); }
bool torture_userdel(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; struct policy_handle h; struct lsa_String domain_name; struct dom_sid2 sid; uint32_t rid; const char *name = TEST_USERNAME; TALLOC_CTX *mem_ctx; bool ret = true; struct dcerpc_binding_handle *b; mem_ctx = talloc_init("test_userdel"); status = torture_rpc_connection(torture, &p, &ndr_table_samr); if (!NT_STATUS_IS_OK(status)) { return false; } b = p->binding_handle; domain_name.string = lpcfg_workgroup(torture->lp_ctx); if (!test_domain_open(torture, b, &domain_name, mem_ctx, &h, &sid)) { ret = false; goto done; } if (!test_user_create(torture, b, mem_ctx, &h, name, &rid)) { ret = false; goto done; } if (!test_userdel(torture, p, mem_ctx, &h, name)) { ret = false; goto done; } done: talloc_free(mem_ctx); return ret; }
static bool test_handles_random_assoc(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-RANDOM-ASSOC\n"); torture_comment(torture, "connect samr pipe1\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); torture_comment(torture, "pipe1 uses assoc_group_id[0x%08X]\n", dcerpc_binding_get_assoc_group_id(p1->binding)); transport = p1->conn->transport.transport; /* * We use ~p1->assoc_group_id instead of p1->assoc_group_id, because * this way we are less likely to use an id which is already in use. */ assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); assoc_group_id = ~assoc_group_id; torture_comment(torture, "connect samr pipe2 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p2, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe2"); torture_comment(torture, "connect samr pipe3 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe3"); talloc_free(mem_ctx); return true; }
BOOL torture_rpc_dcom(void) { NTSTATUS status; struct dcerpc_pipe *p; TALLOC_CTX *mem_ctx; BOOL ret = True; mem_ctx = talloc_init("torture_rpc_dcom"); status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_IOXIDResolver); if (!NT_STATUS_IS_OK(status)) { ret = False; } printf("\n"); talloc_free(mem_ctx); return ret; }
bool torture_domainopen(struct torture_context *torture) { NTSTATUS status; struct libnet_context *net_ctx; TALLOC_CTX *mem_ctx; bool ret = true; struct policy_handle h; struct lsa_String name; mem_ctx = talloc_init("test_domain_open"); net_ctx = libnet_context_init(torture->ev, torture->lp_ctx); status = torture_rpc_connection(torture, &net_ctx->samr.pipe, &ndr_table_samr); if (!NT_STATUS_IS_OK(status)) { return false; } name.string = lp_workgroup(torture->lp_ctx); /* * Testing synchronous version */ if (!test_domainopen(net_ctx, mem_ctx, &name, &h)) { ret = false; goto done; } if (!test_cleanup(net_ctx->samr.pipe, mem_ctx, &h)) { ret = false; goto done; } done: talloc_free(mem_ctx); return ret; }
bool torture_rpc_dfs(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; bool ret = true; enum dfs_ManagerVersion version; const char *host = torture_setting_string(torture, "host", NULL); status = torture_rpc_connection(torture, &p, &ndr_table_netdfs); torture_assert_ntstatus_ok(torture, status, "Unable to connect"); ret &= test_GetManagerVersion(p, torture, &version); ret &= test_ManagerInitialize(p, torture, host); ret &= test_Enum(p, torture); ret &= test_EnumEx(p, torture, host); ret &= test_StdRoot(p, torture, torture, host); ret &= test_FtRoot(p, torture, host); ret &= test_DcAddress(p, torture, host); return ret; }
BOOL torture_rpc_dssetup(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p; TALLOC_CTX *mem_ctx; BOOL ret = True; mem_ctx = talloc_init("torture_rpc_dssetup"); status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_dssetup); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return False; } ret &= test_DsRoleGetPrimaryDomainInformation(p, mem_ctx); talloc_free(mem_ctx); return ret; }
static bool test_handles_random_assoc(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-RANDOM-ASSOC\n"); torture_comment(torture, "connect samr pipe1\n"); status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); transport = p1->conn->transport.transport, assoc_group_id = p1->assoc_group_id; torture_comment(torture, "pip1 use assoc_group_id[0x%08X]\n", assoc_group_id); torture_comment(torture, "connect samr pipe2 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(mem_ctx, &p2, &dcerpc_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe2"); torture_comment(torture, "connect samr pipe3 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(mem_ctx, &p3, &dcerpc_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe3"); talloc_free(mem_ctx); return true; }
static bool torture_rpc_spoolss_access_setup_common(struct torture_context *tctx, struct torture_access_context *t) { void *testuser; const char *testuser_passwd; struct cli_credentials *test_credentials; struct dom_sid *test_sid; struct dcerpc_pipe *p; const char *printername; const char *binding = torture_setting_string(tctx, "binding", NULL); struct dcerpc_pipe *spoolss_pipe; testuser = torture_create_testuser_max_pwlen(tctx, t->user.username, torture_setting_string(tctx, "workgroup", NULL), ACB_NORMAL, &testuser_passwd, 32); if (!testuser) { torture_fail(tctx, "Failed to create test user"); } test_credentials = cli_credentials_init(tctx); cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED); cli_credentials_set_domain(test_credentials, lpcfg_workgroup(tctx->lp_ctx), CRED_SPECIFIED); cli_credentials_set_username(test_credentials, t->user.username, CRED_SPECIFIED); cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED); test_sid = discard_const_p(struct dom_sid, torture_join_user_sid(testuser)); if (t->user.num_builtin_memberships) { struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(testuser); torture_assert(tctx, spoolss_access_setup_membership(tctx, samr_pipe, t->user.num_builtin_memberships, t->user.builtin_memberships, test_sid), "failed to setup membership"); } if (t->user.num_privs) { struct dcerpc_pipe *lsa_pipe; torture_assert_ntstatus_ok(tctx, torture_rpc_connection(tctx, &lsa_pipe, &ndr_table_lsarpc), "Error connecting to server"); torture_assert(tctx, spoolss_access_setup_privs(tctx, lsa_pipe, t->user.num_privs, t->user.privs, test_sid, &t->user.privs_present), "failed to setup privs"); talloc_free(lsa_pipe); } torture_assert_ntstatus_ok(tctx, torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss), "Error connecting to server"); torture_assert(tctx, test_EnumPrinters_findone(tctx, spoolss_pipe, &printername), "failed to enumerate printers"); if (t->user.sd && printername) { torture_assert(tctx, spoolss_access_setup_sd(tctx, spoolss_pipe, printername, test_sid, &t->sd_orig), "failed to setup sd"); } talloc_free(spoolss_pipe); torture_assert_ntstatus_ok(tctx, dcerpc_pipe_connect(tctx, &p, binding, &ndr_table_spoolss, test_credentials, tctx->ev, tctx->lp_ctx), "Error connecting to server"); t->spoolss_pipe = p; t->printername = printername; t->user.testuser = testuser; return true; }
static bool test_handles_mixed_shared(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5, *p6; struct dcerpc_binding_handle *b1, *b2; struct policy_handle handle; struct policy_handle handle2; struct samr_Connect r; struct lsa_Close lc; struct samr_Close sc; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-MIXED-SHARED\n"); torture_comment(torture, "connect samr pipe1\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); b1 = p1->binding_handle; transport = p1->conn->transport.transport; assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); torture_comment(torture, "connect lsa pipe2\n"); status = torture_rpc_connection_transport(torture, &p2, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", dcerpc_binding_get_assoc_group_id(p2->binding)); r.in.system_name = 0; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.connect_handle = &handle; torture_comment(torture, "samr_Connect to open a policy handle on samr p1\n"); torture_assert_ntstatus_ok(torture, dcerpc_samr_Connect_r(b1, mem_ctx, &r), "Connect failed"); torture_assert_ntstatus_ok(torture, r.out.result, "opening policy handle on p1"); lc.in.handle = &handle; lc.out.handle = &handle2; sc.in.handle = &handle; sc.out.handle = &handle2; torture_comment(torture, "use policy handle on lsa p2 - should fail\n"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &lc); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing handle on lsa p2"); torture_comment(torture, "closing policy handle on samr p1\n"); torture_assert_ntstatus_ok(torture, dcerpc_samr_Close_r(b1, mem_ctx, &sc), "Close failed"); torture_assert_ntstatus_ok(torture, sc.out.result, "closing policy handle on p1"); talloc_free(p1); talloc_free(p2); smb_msleep(10); torture_comment(torture, "connect samr pipe3 - should fail\n"); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe3"); torture_comment(torture, "connect lsa pipe4 - should fail\n"); status = torture_rpc_connection_transport(torture, &p4, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe4"); /* * We use ~assoc_group_id instead of p1->assoc_group_id, because * this way we are less likely to use an id which is already in use. */ assoc_group_id = ~assoc_group_id; torture_comment(torture, "connect samr pipe5 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p5, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe5"); torture_comment(torture, "connect lsa pipe6 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p6, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe6"); talloc_free(mem_ctx); return true; }
static bool test_handles_lsa(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; struct dcerpc_binding_handle *b1, *b2; struct policy_handle handle; struct policy_handle handle2; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy r; struct lsa_Close c; uint16_t system_name = '\\'; TALLOC_CTX *mem_ctx = talloc_new(torture); torture_comment(torture, "RPC-HANDLE-LSARPC\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); b1 = p1->binding_handle; status = torture_rpc_connection(torture, &p2, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); b2 = p2->binding_handle; qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0; attr.len = 0; attr.root_dir = NULL; attr.object_name = NULL; attr.attributes = 0; attr.sec_desc = NULL; attr.sec_qos = &qos; r.in.system_name = &system_name; r.in.attr = &attr; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b1, mem_ctx, &r), "OpenPolicy failed"); if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(torture, "lsa_OpenPolicy not supported - skipping\n"); talloc_free(mem_ctx); return true; } c.in.handle = &handle; c.out.handle = &handle2; status = dcerpc_lsa_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_Close_r(b1, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_ok(torture, c.out.result, "closing policy handle on p1"); status = dcerpc_lsa_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); talloc_free(mem_ctx); return true; }
static bool test_handles_lsa_shared(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5; struct dcerpc_binding_handle *b1, *b2, *b3, *b4; struct policy_handle handle; struct policy_handle handle2; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy r; struct lsa_Close c; struct lsa_QuerySecurity qsec; struct sec_desc_buf *sdbuf = NULL; uint16_t system_name = '\\'; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-LSARPC-SHARED\n"); torture_comment(torture, "connect lsa pipe1\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); b1 = p1->binding_handle; transport = p1->conn->transport.transport; assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); torture_comment(torture, "connect lsa pipe2\n"); status = torture_rpc_connection_transport(torture, &p2, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", dcerpc_binding_get_assoc_group_id(p2->binding)); qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0; attr.len = 0; attr.root_dir = NULL; attr.object_name = NULL; attr.attributes = 0; attr.sec_desc = NULL; attr.sec_qos = &qos; r.in.system_name = &system_name; r.in.attr = &attr; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; torture_comment(torture, "open lsa policy handle\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b1, mem_ctx, &r), "OpenPolicy failed"); if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(torture, "lsa_OpenPolicy not supported - skipping\n"); talloc_free(mem_ctx); return true; } /* * connect p3 after the policy handle is opened */ torture_comment(torture, "connect lsa pipe3 after the policy handle is opened\n"); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe3"); b3 = p3->binding_handle; qsec.in.handle = &handle; qsec.in.sec_info = 0; qsec.out.sdbuf = &sdbuf; c.in.handle = &handle; c.out.handle = &handle2; /* * use policy handle on all 3 connections */ torture_comment(torture, "use the policy handle on p1,p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p3"); /* * close policy handle on connection 2 and the others get a fault */ torture_comment(torture, "close the policy handle on p2 others get a fault\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_Close_r(b2, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_equal(torture, c.out.result, NT_STATUS_OK, "closing policy handle on p2"); status = dcerpc_lsa_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); status = dcerpc_lsa_Close_r(b3, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p3"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2 again"); /* * open a new policy handle on p3 */ torture_comment(torture, "open a new policy handle on p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b3, mem_ctx, &r), "OpenPolicy failed"); torture_assert_ntstatus_equal(torture, r.out.result, NT_STATUS_OK, "open policy handle on p3"); /* * use policy handle on all 3 connections */ torture_comment(torture, "use the policy handle on p1,p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p3"); /* * close policy handle on connection 2 and the others get a fault */ torture_comment(torture, "close the policy handle on p2 others get a fault\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_Close_r(b2, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_equal(torture, c.out.result, NT_STATUS_OK, "closing policy handle on p2"); status = dcerpc_lsa_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); status = dcerpc_lsa_Close_r(b3, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p3"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2 again"); /* * open a new policy handle */ torture_comment(torture, "open a new policy handle on p1 and use it\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b1, mem_ctx, &r), "OpenPolicy failed"); torture_assert_ntstatus_equal(torture, r.out.result, NT_STATUS_OK, "open 2nd policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p1"); /* close first connection */ torture_comment(torture, "disconnect p1\n"); talloc_free(p1); smb_msleep(5); /* * and it's still available on p2,p3 */ torture_comment(torture, "use policy handle on p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p2 after p1 was disconnected"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p3 after p1 was disconnected"); /* * now open p4 * and use the handle on it */ torture_comment(torture, "connect lsa pipe4 and use policy handle\n"); status = torture_rpc_connection_transport(torture, &p4, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe4"); b4 = p4->binding_handle; torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b4, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "using policy handle on p4"); /* * now close p2,p3,p4 * without closing the policy handle */ torture_comment(torture, "disconnect p2,p3,p4\n"); talloc_free(p2); talloc_free(p3); talloc_free(p4); smb_msleep(10); /* * now open p5 */ torture_comment(torture, "connect lsa pipe5 - should fail\n"); status = torture_rpc_connection_transport(torture, &p5, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe5"); talloc_free(mem_ctx); return true; }
/* Get the SID from a user */ static const struct dom_sid *get_user_sid(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *user) { struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy2 r; struct lsa_Close c; NTSTATUS status; struct policy_handle handle; struct lsa_LookupNames l; struct lsa_TransSidArray sids; struct lsa_RefDomainList *domains = NULL; struct lsa_String lsa_name; uint32_t count = 0; struct dom_sid *result; TALLOC_CTX *tmp_ctx; struct dcerpc_pipe *p2; struct dcerpc_binding_handle *b; const char *domain = cli_credentials_get_domain(cmdline_credentials); torture_assert_ntstatus_ok(tctx, torture_rpc_connection(tctx, &p2, &ndr_table_lsarpc), "could not open lsarpc pipe"); b = p2->binding_handle; if (!(tmp_ctx = talloc_new(mem_ctx))) { return NULL; } qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0; attr.len = 0; attr.root_dir = NULL; attr.object_name = NULL; attr.attributes = 0; attr.sec_desc = NULL; attr.sec_qos = &qos; r.in.system_name = "\\"; r.in.attr = &attr; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return NULL; } if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(tctx, "OpenPolicy2_ failed - %s\n", nt_errstr(r.out.result)); talloc_free(tmp_ctx); return NULL; } sids.count = 0; sids.sids = NULL; lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user); l.in.handle = &handle; l.in.num_names = 1; l.in.names = &lsa_name; l.in.sids = &sids; l.in.level = 1; l.in.count = &count; l.out.count = &count; l.out.sids = &sids; l.out.domains = &domains; status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "LookupNames of %s failed - %s\n", lsa_name.string, nt_errstr(status)); talloc_free(tmp_ctx); return NULL; } if (domains->count == 0) { return NULL; } result = dom_sid_add_rid(mem_ctx, domains->domains[0].sid, l.out.sids->sids[0].rid); c.in.handle = &handle; c.out.handle = &handle; status = dcerpc_lsa_Close_r(b, tmp_ctx, &c); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return NULL; } if (!NT_STATUS_IS_OK(c.out.result)) { torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(c.out.result)); talloc_free(tmp_ctx); return NULL; } talloc_free(tmp_ctx); talloc_free(p2); torture_comment(tctx, "Get_user_sid finished\n"); return result; }
struct test_join *torture_create_testuser(struct torture_context *torture, const char *username, const char *domain, uint16_t acct_type, const char **random_password) { NTSTATUS status; struct samr_Connect c; struct samr_CreateUser2 r; struct samr_OpenDomain o; struct samr_LookupDomain l; struct dom_sid2 *sid = NULL; struct samr_GetUserPwInfo pwp; struct samr_PwInfo info; struct samr_SetUserInfo s; union samr_UserInfo u; struct policy_handle handle; struct policy_handle domain_handle; uint32_t access_granted; uint32_t rid; DATA_BLOB session_key; struct lsa_String name; int policy_min_pw_len = 0; struct test_join *join; char *random_pw; const char *dc_binding = torture_setting_string(torture, "dc_binding", NULL); join = talloc(NULL, struct test_join); if (join == NULL) { return NULL; } ZERO_STRUCTP(join); printf("Connecting to SAMR\n"); if (dc_binding) { status = dcerpc_pipe_connect(join, &join->p, dc_binding, &ndr_table_samr, cmdline_credentials, NULL, torture->lp_ctx); } else { status = torture_rpc_connection(torture, &join->p, &ndr_table_samr); } if (!NT_STATUS_IS_OK(status)) { return NULL; } c.in.system_name = NULL; c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; c.out.connect_handle = &handle; status = dcerpc_samr_Connect(join->p, join, &c); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { errstr = dcerpc_errstr(join, join->p->last_fault_code); } printf("samr_Connect failed - %s\n", errstr); return NULL; } printf("Opening domain %s\n", domain); name.string = domain; l.in.connect_handle = &handle; l.in.domain_name = &name; l.out.sid = &sid; status = dcerpc_samr_LookupDomain(join->p, join, &l); if (!NT_STATUS_IS_OK(status)) { printf("LookupDomain failed - %s\n", nt_errstr(status)); goto failed; } talloc_steal(join, *l.out.sid); join->dom_sid = *l.out.sid; join->dom_netbios_name = talloc_strdup(join, domain); if (!join->dom_netbios_name) goto failed; o.in.connect_handle = &handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain(join->p, join, &o); if (!NT_STATUS_IS_OK(status)) { printf("OpenDomain failed - %s\n", nt_errstr(status)); goto failed; } printf("Creating account %s\n", username); again: name.string = username; r.in.domain_handle = &domain_handle; r.in.account_name = &name; r.in.acct_flags = acct_type; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.user_handle = &join->user_handle; r.out.access_granted = &access_granted; r.out.rid = &rid; status = dcerpc_samr_CreateUser2(join->p, join, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { status = DeleteUser_byname(join->p, join, &domain_handle, name.string); if (NT_STATUS_IS_OK(status)) { goto again; } } if (!NT_STATUS_IS_OK(status)) { printf("CreateUser2 failed - %s\n", nt_errstr(status)); goto failed; } join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid); pwp.in.user_handle = &join->user_handle; pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info->min_password_length; } random_pw = generate_random_str(join, MAX(8, policy_min_pw_len)); printf("Setting account password '%s'\n", random_pw); ZERO_STRUCT(u); s.in.user_handle = &join->user_handle; s.in.info = &u; s.in.level = 24; encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE); u.info24.password_expired = 0; status = dcerpc_fetch_session_key(join->p, &session_key); if (!NT_STATUS_IS_OK(status)) { printf("SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); torture_leave_domain(torture, join); goto failed; } arcfour_crypt_blob(u.info24.password.data, 516, &session_key); status = dcerpc_samr_SetUserInfo(join->p, join, &s); if (!NT_STATUS_IS_OK(status)) { printf("SetUserInfo failed - %s\n", nt_errstr(status)); goto failed; } ZERO_STRUCT(u); s.in.user_handle = &join->user_handle; s.in.info = &u; s.in.level = 21; u.info21.acct_flags = acct_type | ACB_PWNOEXP; u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME; u.info21.comment.string = talloc_asprintf(join, "Tortured by Samba4: %s", timestring(join, time(NULL))); u.info21.full_name.string = talloc_asprintf(join, "Torture account for Samba4: %s", timestring(join, time(NULL))); u.info21.description.string = talloc_asprintf(join, "Samba4 torture account created by host %s: %s", lp_netbios_name(torture->lp_ctx), timestring(join, time(NULL))); printf("Resetting ACB flags, force pw change time\n"); status = dcerpc_samr_SetUserInfo(join->p, join, &s); if (!NT_STATUS_IS_OK(status)) { printf("SetUserInfo failed - %s\n", nt_errstr(status)); goto failed; } if (random_password) { *random_password = random_pw; } return join; failed: torture_leave_domain(torture, join); return NULL; }
/* work out how many calls there are for an interface */ static BOOL test_num_calls(const struct dcerpc_interface_table *iface, TALLOC_CTX *mem_ctx, struct dcerpc_syntax_id *id) { struct dcerpc_pipe *p; NTSTATUS status; int i; DATA_BLOB stub_in, stub_out; int idl_calls; struct dcerpc_interface_table tbl; /* FIXME: This should be fixed when torture_rpc_connection * takes a dcerpc_syntax_id */ tbl.name = iface->name; tbl.syntax_id = *id; status = torture_rpc_connection(mem_ctx, &p, iface); if (!NT_STATUS_IS_OK(status)) { char *uuid_str = GUID_string(mem_ctx, &id->uuid); printf("Failed to connect to '%s' on '%s' - %s\n", uuid_str, iface->name, nt_errstr(status)); talloc_free(uuid_str); return False; } /* make null calls */ stub_in = data_blob(NULL, 1000); memset(stub_in.data, 0xFF, stub_in.length); for (i=0;i<200;i++) { status = dcerpc_request(p, NULL, False, i, mem_ctx, &stub_in, &stub_out); if (!NT_STATUS_IS_OK(status) && p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) { break; } if (!NT_STATUS_IS_OK(status) && p->last_fault_code == 5) { printf("\tpipe disconnected at %d\n", i); goto done; } if (!NT_STATUS_IS_OK(status) && p->last_fault_code == 0x80010111) { printf("\terr 0x80010111 at %d\n", i); goto done; } } printf("\t%d calls available\n", i); idl_calls = idl_num_calls(&id->uuid, id->if_version); if (idl_calls == -1) { printf("\tinterface not known in local IDL\n"); } else if (i != idl_calls) { printf("\tWARNING: local IDL defines %u calls\n", idl_calls); } else { printf("\tOK: matches num_calls in local IDL\n"); } done: talloc_free(p); return True; }