static bool test_netprintdestgetinfo(struct torture_context *tctx, struct smbcli_state *cli) { struct rap_NetPrintDestEnum r; int i; r.in.level = 2; r.in.bufsize = 8192; torture_comment(tctx, "Testing rap_NetPrintDestEnum level %d\n", r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintdestenum(cli->tree, tctx, &r), "smbcli_rap_netprintdestenum failed"); for (i=0; i < r.out.count; i++) { torture_assert(tctx, test_netprintdestgetinfo_bydest(tctx, cli, r.out.info[i].info2.PrinterName), "failed to get printdest info"); } return true; }
bool torture_setup_privs(struct torture_context *tctx, struct dcerpc_pipe *p, uint32_t num_privs, const char **privs, const struct dom_sid *user_sid) { struct dcerpc_binding_handle *b = p->binding_handle; struct policy_handle *handle; int i; torture_assert(tctx, test_lsa_OpenPolicy2(b, tctx, &handle), "failed to open policy"); for (i=0; i < num_privs; i++) { struct lsa_LookupPrivValue r; struct lsa_LUID luid; struct lsa_String name; init_lsa_String(&name, privs[i]); r.in.handle = handle; r.in.name = &name; r.out.luid = &luid; torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r), "lsa_LookupPrivValue failed"); if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(tctx, "lsa_LookupPrivValue failed for '%s' with %s\n", privs[i], nt_errstr(r.out.result)); return false; } } { struct lsa_AddAccountRights r; struct lsa_RightSet rights; rights.count = num_privs; rights.names = talloc_zero_array(tctx, struct lsa_StringLarge, rights.count); for (i=0; i < rights.count; i++) { init_lsa_StringLarge(&rights.names[i], privs[i]); } r.in.handle = handle; r.in.sid = discard_const_p(struct dom_sid, user_sid); r.in.rights = &rights; torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(b, tctx, &r), "lsa_AddAccountRights failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "lsa_AddAccountRights failed"); } test_lsa_Close(b, tctx, handle); return true; }
static bool test_netprintjobenum_one(struct torture_context *tctx, struct smbcli_state *cli, const char *PrintQueueName) { struct rap_NetPrintJobEnum r; int i; uint16_t levels[] = { 0, 1, 2 }; r.in.PrintQueueName = PrintQueueName; r.in.bufsize = 8192; for (i=0; i < ARRAY_SIZE(levels); i++) { r.in.level = levels[i]; torture_comment(tctx, "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintjobenum(cli->tree, tctx, &r), "smbcli_rap_netprintjobenum failed"); } return true; }
static bool test_create_acl_dir(struct torture_context *tctx, struct smb2_tree *tree) { torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n"); return test_create_acl_ext(tctx, tree, true); }
/* test SMB2 open with a leading slash on the path. Trying to create a directory with a leading slash should give NT_STATUS_INVALID_PARAMETER error */ static bool test_smb2_leading_slash(struct torture_context *tctx, struct smb2_tree *tree) { union smb_open io; const char *dnameslash = "\\"DNAME; NTSTATUS status; bool ret = true; torture_comment(tctx, "Trying to create a directory with leading slash on path\n"); smb2_deltree(tree, dnameslash); ZERO_STRUCT(io.smb2); io.generic.level = RAW_OPEN_SMB2; io.smb2.in.oplock_level = 0; io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL; io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE; io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.smb2.in.fname = dnameslash; status = smb2_create(tree, tree, &(io.smb2)); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); smb2_deltree(tree, dnameslash); return ret; }
/* a schannel test suite */ bool torture_rpc_schannel(struct torture_context *torture) { bool ret = true; struct { uint16_t acct_flags; uint32_t dcerpc_flags; } tests[] = { { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SIGN}, { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SEAL}, { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128}, { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 }, { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SIGN }, { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SEAL }, { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128 }, { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 } }; int i; for (i=0;i<ARRAY_SIZE(tests);i++) { if (!test_schannel(torture, tests[i].acct_flags, tests[i].dcerpc_flags, i)) { torture_comment(torture, "Failed with acct_flags=0x%x dcerpc_flags=0x%x \n", tests[i].acct_flags, tests[i].dcerpc_flags); ret = false; } } return ret; }
static bool test_SetPrinter(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, struct spoolss_SetPrinterInfoCtr *info_ctr, struct spoolss_DevmodeContainer *devmode_ctr, struct sec_desc_buf *secdesc_ctr, enum spoolss_PrinterControl command) { struct spoolss_SetPrinter r; r.in.handle = handle; r.in.info_ctr = info_ctr; r.in.devmode_ctr = devmode_ctr; r.in.secdesc_ctr = secdesc_ctr; r.in.command = command; torture_comment(tctx, "Testing SetPrinter level %d\n", r.in.info_ctr->level); torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r), "failed to call SetPrinter"); torture_assert_werr_ok(tctx, r.out.result, "failed to call SetPrinter"); return true; }
static bool test_netprintjobsetinfo_byid(struct torture_context *tctx, struct smbcli_state *cli, uint16_t JobID) { struct rap_NetPrintJobSetInfo r; uint16_t levels[] = { 0, 1, 2 }; int i; const char *comment = "tortured by samba"; r.in.JobID = JobID; r.in.bufsize = strlen(comment); r.in.ParamNum = RAP_PARAM_JOBCOMMENT; r.in.Param.string = comment; for (i=0; i < ARRAY_SIZE(levels); i++) { r.in.level = levels[i]; torture_comment(tctx, "Testing rap_NetPrintJobSetInfo(%d) level %d\n", r.in.JobID, r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintjobsetinfo(cli->tree, tctx, &r), "smbcli_rap_netprintjobsetinfo failed"); } return true; }
static bool test_netprintqenum(struct torture_context *tctx, struct smbcli_state *cli) { struct rap_NetPrintQEnum r; int i, q; uint16_t levels[] = { 0, 1, 2, 3, 4, 5 }; for (i=0; i < ARRAY_SIZE(levels); i++) { r.in.level = levels[i]; r.in.bufsize = 8192; torture_comment(tctx, "Testing rap_NetPrintQEnum level %d\n", r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintqenum(cli->tree, tctx, &r), "smbcli_rap_netprintqenum failed"); torture_assert_werr_ok(tctx, W_ERROR(r.out.status), "failed to enum printq"); for (q=0; q<r.out.count; q++) { switch (r.in.level) { case 0: printf("%s\n", r.out.info[q].info0.PrintQName); break; } } } return true; }
/* test the SinkData interface */ static bool test_sinkdata(struct torture_context *tctx, struct dcerpc_pipe *p) { int i; NTSTATUS status; uint8_t *data_in; int len; struct echo_SinkData r; if (torture_setting_bool(tctx, "quick", false) && (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) { len = 100 + (random() % 5000); } else { len = 200000 + (random() % 5000); } data_in = talloc_array(tctx, uint8_t, len); for (i=0;i<len;i++) { data_in[i] = i+1; } r.in.len = len; r.in.data = data_in; status = dcerpc_echo_SinkData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "SinkData(%d) failed", len)); torture_comment(tctx, "sunk %d bytes\n", len); return true; }
static bool test_GetPrinterDriver2(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct test_spoolss_win_context *ctx, struct policy_handle *handle) { NTSTATUS status; struct spoolss_GetPrinterDriver2 gpd2; DATA_BLOB blob = data_blob_talloc_zero(tctx, 87424); uint32_t needed; uint32_t server_major_version; uint32_t server_minor_version; torture_comment(tctx, "Testing GetPrinterDriver2\n"); gpd2.in.handle = handle; gpd2.in.architecture = "Windows NT x86"; gpd2.in.level = 101; gpd2.in.buffer = &blob; gpd2.in.offered = 87424; gpd2.in.client_major_version = 3; gpd2.in.client_minor_version = 0; gpd2.out.needed = &needed; gpd2.out.server_major_version = &server_major_version; gpd2.out.server_minor_version = &server_minor_version; status = dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &gpd2); torture_assert_ntstatus_ok(tctx, status, "GetPrinterDriver2 failed"); if (ctx->printer_has_driver) { torture_assert_werr_ok(tctx, gpd2.out.result, "GetPrinterDriver2 failed."); } return true; }
/* This is a convenience function for all OpenPrinterEx calls */ static bool test_OpenPrinterEx(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, const char *printer_name, uint32_t access_mask) { NTSTATUS status; struct spoolss_OpenPrinterEx op; struct spoolss_UserLevel1 ul_1; torture_comment(tctx, "Opening printer '%s'\n", printer_name); op.in.printername = talloc_strdup(tctx, printer_name); op.in.datatype = NULL; op.in.devmode_ctr.devmode = NULL; op.in.access_mask = access_mask; op.in.userlevel_ctr.level = 1; op.in.userlevel_ctr.user_info.level1 = &ul_1; op.out.handle = handle; ul_1.size = 1234; ul_1.client = "\\clientname"; ul_1.user = "******"; ul_1.build = 1; ul_1.major = 2; ul_1.minor = 3; ul_1.processor = 4567; status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &op); torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed"); torture_assert_werr_ok(tctx, op.out.result, "OpenPrinterEx failed"); return true; }
static bool print_printjob(struct torture_context *tctx, struct smbcli_tree *tree) { int fnum; DATA_BLOB data; ssize_t size_written; const char *str; torture_comment(tctx, "creating printjob %s\n", TORTURE_PRINT_FILE); fnum = smbcli_open(tree, TORTURE_PRINT_FILE, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); if (fnum == -1) { torture_fail(tctx, "failed to open file"); } str = talloc_asprintf(tctx, "TortureTestPage: %d\nData\n",0); data = data_blob_string_const(str); size_written = smbcli_write(tree, fnum, 0, data.data, 0, data.length); if (size_written != data.length) { torture_fail(tctx, "failed to write file"); } torture_assert_ntstatus_ok(tctx, smbcli_close(tree, fnum), "failed to close file"); return true; }
static bool test_GetPrinterData(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, const char *value_name, WERROR expected_werr, uint32_t expected_value) { NTSTATUS status; struct spoolss_GetPrinterData gpd; uint32_t needed; enum winreg_Type type; uint8_t *data = talloc_zero_array(tctx, uint8_t, 4); torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name); gpd.in.handle = handle; gpd.in.value_name = value_name; gpd.in.offered = 4; gpd.out.needed = &needed; gpd.out.type = &type; gpd.out.data = data; status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &gpd); torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed."); torture_assert_werr_equal(tctx, gpd.out.result, expected_werr, "GetPrinterData did not return expected error value."); if (W_ERROR_IS_OK(expected_werr)) { uint32_t value = IVAL(data, 0); torture_assert_int_equal(tctx, value, expected_value, talloc_asprintf(tctx, "GetPrinterData for %s did not return expected value.", value_name)); } return true; }
/* test a echodata call over the internal messaging system */ static bool test_echodata(struct torture_context *tctx, const void *tcase_data, const void *test_data) { struct echo_EchoData r; NTSTATUS status; const struct irpc_test_data *data = (const struct irpc_test_data *)tcase_data; TALLOC_CTX *mem_ctx = tctx; struct dcerpc_binding_handle *irpc_handle; irpc_handle = irpc_binding_handle(mem_ctx, data->msg_ctx1, cluster_id(0, MSG_ID2), &ndr_table_rpcecho); torture_assert(tctx, irpc_handle, "no memory"); /* make the call */ r.in.in_data = (unsigned char *)talloc_strdup(mem_ctx, "0123456789"); r.in.len = strlen((char *)r.in.in_data); status = dcerpc_echo_EchoData_r(irpc_handle, mem_ctx, &r); torture_assert_ntstatus_ok(tctx, status, "EchoData failed"); /* check the answer */ if (memcmp(r.out.out_data, r.in.in_data, r.in.len) != 0) { NDR_PRINT_OUT_DEBUG(echo_EchoData, &r); torture_fail(tctx, "EchoData wrong answer"); } torture_comment(tctx, "Echo '%*.*s' -> '%*.*s'\n", r.in.len, r.in.len, r.in.in_data, r.in.len, r.in.len, r.out.out_data); return true; }
static bool test_openprinter_access(struct torture_context *tctx, struct dcerpc_pipe *p, const char *name, const char *printername, const char *username, uint32_t access_mask, WERROR expected_result) { struct policy_handle handle; struct dcerpc_binding_handle *b = p->binding_handle; bool ret = true; ZERO_STRUCT(handle); if (printername == NULL) { torture_comment(tctx, "skipping test %s as there is no printer\n", name); return true; } ret = test_openprinter_handle(tctx, p, name, printername, username, access_mask, expected_result, &handle); if (is_valid_policy_hnd(&handle)) { test_ClosePrinter(tctx, b, &handle); } return ret; }
static bool test_create_acl_file(struct torture_context *tctx, struct smb2_tree *tree) { torture_comment(tctx, "Testing nttrans create with sec_desc on files\n"); return test_create_acl_ext(tctx, tree, false); }
static bool test_netprintjobenum_args(struct torture_context *tctx, struct smbcli_state *cli, const char *PrintQueueName, uint16_t level, uint16_t *count_p, union rap_printj_info **info_p) { struct rap_NetPrintJobEnum r; r.in.PrintQueueName = PrintQueueName; r.in.bufsize = 8192; r.in.level = level; torture_comment(tctx, "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintjobenum(cli->tree, tctx, &r), "smbcli_rap_netprintjobenum failed"); if (count_p) { *count_p = r.out.count; } if (info_p) { *info_p = r.out.info; } return true; }
/* test a addone call over the internal messaging system */ static bool test_addone(struct torture_context *test, const void *_data, const void *_value) { struct echo_AddOne r; NTSTATUS status; const struct irpc_test_data *data = (const struct irpc_test_data *)_data; uint32_t value = *(const uint32_t *)_value; struct dcerpc_binding_handle *irpc_handle; irpc_handle = irpc_binding_handle(test, data->msg_ctx1, cluster_id(0, MSG_ID2), &ndr_table_rpcecho); torture_assert(test, irpc_handle, "no memory"); /* make the call */ r.in.in_data = value; test_debug = true; status = dcerpc_echo_AddOne_r(irpc_handle, test, &r); test_debug = false; torture_assert_ntstatus_ok(test, status, "AddOne failed"); /* check the answer */ torture_assert(test, *r.out.out_data == r.in.in_data + 1, "AddOne wrong answer"); torture_comment(test, "%u + 1 = %u\n", r.in.in_data, *r.out.out_data); return true; }
/* * Certs used for this protocol have a GUID in the issuer_uniq_id field. * This function fetch it. */ static struct GUID *get_cert_guid(struct torture_context *tctx, TALLOC_CTX *mem_ctx, uint8_t *cert_data, uint32_t cert_len) { hx509_context hctx; hx509_cert cert; heim_bit_string subjectuniqid; DATA_BLOB data; int hret; uint32_t size; struct GUID *guid = talloc_zero(mem_ctx, struct GUID); NTSTATUS status; hx509_context_init(&hctx); hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert); if (hret) { torture_comment(tctx, "error while loading the cert\n"); hx509_context_free(&hctx); return NULL; } hret = hx509_cert_get_issuer_unique_id(hctx, cert, &subjectuniqid); if (hret) { torture_comment(tctx, "error while getting the issuer_uniq_id\n"); hx509_cert_free(cert); hx509_context_free(&hctx); return NULL; } /* The subjectuniqid is a bit string, * which means that the real size has to be divided by 8 * to have the number of bytes */ hx509_cert_free(cert); hx509_context_free(&hctx); size = subjectuniqid.length / 8; data = data_blob_const(subjectuniqid.data, size); status = GUID_from_data_blob(&data, guid); der_free_bit_string(&subjectuniqid); if (!NT_STATUS_IS_OK(status)) { return NULL; } return guid; }
static bool torture_libsmbclient_initialize(struct torture_context *tctx) { SMBCCTX *ctx; torture_comment(tctx, "Testing smbc_new_context\n"); ctx = smbc_new_context(); torture_assert(tctx, ctx, "failed to get new context"); torture_comment(tctx, "Testing smbc_init_context\n"); torture_assert(tctx, smbc_init_context(ctx), "failed to init context"); smbc_free_context(ctx, 1); return true; }
static bool test_fsrvp_get_version(struct torture_context *tctx, struct dcerpc_pipe *p) { struct fss_GetSupportedVersion r; struct dcerpc_binding_handle *b = p->binding_handle; NTSTATUS status; ZERO_STRUCT(r); status = dcerpc_fss_GetSupportedVersion_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetSupportedVersion failed"); torture_comment(tctx, "got MinVersion %u\n", *r.out.MinVersion); torture_comment(tctx, "got MaxVersion %u\n", *r.out.MaxVersion); return true; }
static bool torture_libsmbclient_version(struct torture_context *tctx) { torture_comment(tctx, "Testing smbc_version\n"); torture_assert(tctx, smbc_version(), "failed to get version"); return true; }
/* return the default DN for a ldap server given a connected RPC pipe to the server */ static const char *torture_get_ldap_base_dn(struct torture_context *tctx, struct dcerpc_pipe *p) { const char *hostname = p->binding->host; struct ldb_context *ldb; const char *ldap_url = talloc_asprintf(p, "ldap://%s", hostname); const char *attrs[] = { "defaultNamingContext", NULL }; const char *dnstr; TALLOC_CTX *tmp_ctx = talloc_new(tctx); int ret; struct ldb_result *res; ldb = ldb_init(tmp_ctx, tctx->ev); if (ldb == NULL) { talloc_free(tmp_ctx); return NULL; } if (ldb_set_opaque(ldb, "loadparm", tctx->lp_ctx)) { talloc_free(ldb); return NULL; } ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); ret = ldb_connect(ldb, ldap_url, 0, NULL); if (ret != LDB_SUCCESS) { torture_comment(tctx, "Failed to make LDB connection to target"); talloc_free(tmp_ctx); return NULL; } ret = dsdb_search_dn(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, ""), attrs, 0); if (ret != LDB_SUCCESS) { torture_comment(tctx, "Failed to get defaultNamingContext"); talloc_free(tmp_ctx); return NULL; } dnstr = ldb_msg_find_attr_as_string(res->msgs[0], "defaultNamingContext", NULL); dnstr = talloc_strdup(tctx, dnstr); talloc_free(tmp_ctx); return dnstr; }
static bool test_userinfo_async(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *domain_handle, struct dom_sid2 *domain_sid, const char* user_name, uint32_t *rid) { const uint16_t level = 10; NTSTATUS status; struct composite_context *c; struct libnet_rpc_userinfo user; struct dom_sid *user_sid; user_sid = dom_sid_add_rid(mem_ctx, domain_sid, *rid); ZERO_STRUCT(user); user.in.domain_handle = *domain_handle; user.in.sid = dom_sid_string(mem_ctx, user_sid); user.in.level = level; /* this should be extended */ torture_comment(tctx, "Testing async libnet_rpc_userinfo (SID argument)\n"); c = libnet_rpc_userinfo_send(mem_ctx, tctx->ev, p->binding_handle, &user, msg_handler); torture_assert(tctx, c != NULL, "Failed to call async libnet_rpc_userinfo_send"); status = libnet_rpc_userinfo_recv(c, mem_ctx, &user); torture_assert_ntstatus_ok(tctx, status, "Calling async libnet_rpc_userinfo_recv failed"); ZERO_STRUCT(user); user.in.domain_handle = *domain_handle; user.in.sid = NULL; user.in.username = user_name; user.in.level = level; torture_comment(tctx, "Testing async libnet_rpc_userinfo (username argument)\n"); c = libnet_rpc_userinfo_send(mem_ctx, tctx->ev, p->binding_handle, &user, msg_handler); torture_assert(tctx, c != NULL, "Failed to call async libnet_rpc_userinfo_send"); status = libnet_rpc_userinfo_recv(c, mem_ctx, &user); torture_assert_ntstatus_ok(tctx, status, "Calling async libnet_rpc_userinfo_recv failed"); return true; }
/* test resolution using sync method */ static bool test_sync_resolve(struct torture_context *tctx) { int timelimit = torture_setting_int(tctx, "timelimit", 2); struct timeval tv = timeval_current(); int count = 0; const char *host = torture_setting_string(tctx, "host", NULL); torture_comment(tctx, "Testing sync resolve of '%s' for %d seconds\n", host, timelimit); while (timeval_elapsed(&tv) < timelimit) { inet_ntoa(interpret_addr2(host)); count++; } torture_comment(tctx, "sync rate of %.1f resolves/sec\n", count/timeval_elapsed(&tv)); return true; }
static bool test_netprintqgetinfo(struct torture_context *tctx, struct smbcli_state *cli) { struct rap_NetPrintQGetInfo r; struct rap_NetPrintQEnum r_enum; int i, p; uint16_t levels[] = { 0, 1, 2, 3, 4, 5 }; r.in.level = 0; r.in.bufsize = 0; r.in.PrintQueueName = ""; torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r), "smbcli_rap_netprintqgetinfo failed"); torture_assert_werr_equal(tctx, W_ERROR(r.out.status), WERR_INVALID_PARAMETER, "smbcli_rap_netprintqgetinfo failed"); r_enum.in.level = 5; r_enum.in.bufsize = 8192; torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintqenum(cli->tree, tctx, &r_enum), "failed to enum printq"); torture_assert_werr_ok(tctx, W_ERROR(r_enum.out.status), "failed to enum printq"); for (p=0; p < r_enum.out.count; p++) { for (i=0; i < ARRAY_SIZE(levels); i++) { r.in.level = levels[i]; r.in.bufsize = 8192; r.in.PrintQueueName = r_enum.out.info[p].info5.PrintQueueName; torture_comment(tctx, "Testing rap_NetPrintQGetInfo(%s) level %d\n", r.in.PrintQueueName, r.in.level); torture_assert_ntstatus_ok(tctx, smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r), "smbcli_rap_netprintqgetinfo failed"); torture_assert_werr_ok(tctx, W_ERROR(r.out.status), "smbcli_rap_netprintqgetinfo failed"); switch (r.in.level) { case 0: printf("%s\n", r.out.info.info0.PrintQName); break; } } } return true; }
bool test_opendomain(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *domname, struct dom_sid2 *sid_p) { NTSTATUS status; struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; torture_comment(tctx, "connecting\n"); r1.in.system_name = 0; r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r1.out.connect_handle = &h; status = dcerpc_samr_Connect(p, mem_ctx, &r1); torture_assert_ntstatus_ok(tctx, status, "Connect failed"); r2.in.connect_handle = &h; r2.in.domain_name = domname; r2.out.sid = &sid; torture_comment(tctx, "domain lookup on %s\n", domname->string); status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2); torture_assert_ntstatus_ok(tctx, status, "LookupDomain failed"); r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; torture_comment(tctx, "opening domain\n"); status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3); torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed"); *handle = domain_handle; *sid_p = **r2.out.sid; return true; }
/* test the EchoData interface */ static bool test_echodata(struct torture_context *tctx, struct dcerpc_pipe *p) { int i; NTSTATUS status; uint8_t *data_in, *data_out; int len; struct echo_EchoData r; if (torture_setting_bool(tctx, "quick", false) && (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) { len = 1 + (random() % 500); } else { len = 1 + (random() % 5000); } data_in = talloc_array(tctx, uint8_t, len); data_out = talloc_array(tctx, uint8_t, len); for (i=0;i<len;i++) { data_in[i] = i; } r.in.len = len; r.in.in_data = data_in; status = dcerpc_echo_EchoData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "EchoData(%d) failed\n", len)); data_out = r.out.out_data; for (i=0;i<len;i++) { if (data_in[i] != data_out[i]) { torture_comment(tctx, "Bad data returned for len %d at offset %d\n", len, i); torture_comment(tctx, "in:\n"); dump_data(0, data_in+i, MIN(len-i, 16)); torture_comment(tctx, "out:\n"); dump_data(0, data_out+i, MIN(len-1, 16)); return false; } } return true; }
/* basic testing of change notify on directories */ static bool torture_smb2_notify_disabled(struct torture_context *torture, struct smb2_tree *tree1) { bool ret = true; NTSTATUS status; union smb_notify notify; union smb_open io; struct smb2_handle h1; struct smb2_request *req; torture_comment(torture, "TESTING CHANGE NOTIFY DISABLED\n"); smb2_deltree(tree1, BASEDIR); smb2_util_rmdir(tree1, BASEDIR); /* get a handle on the directory */ ZERO_STRUCT(io.smb2); io.generic.level = RAW_OPEN_SMB2; io.smb2.in.create_flags = 0; io.smb2.in.desired_access = SEC_FILE_ALL; io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL; io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; io.smb2.in.alloc_size = 0; io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE; io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; io.smb2.in.security_flags = 0; io.smb2.in.fname = BASEDIR; status = smb2_create(tree1, torture, &(io.smb2)); torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK, ret, done, "smb2_create"); h1 = io.smb2.out.file.handle; ZERO_STRUCT(notify.smb2); notify.smb2.level = RAW_NOTIFY_SMB2; notify.smb2.in.buffer_size = 1000; notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; notify.smb2.in.file.handle = h1; notify.smb2.in.recursive = true; req = smb2_notify_send(tree1, &(notify.smb2)); status = smb2_notify_recv(req, torture, &(notify.smb2)); torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_NOT_IMPLEMENTED, ret, done, "smb2_notify_recv"); status = smb2_util_close(tree1, h1); torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK, ret, done, "smb2_create"); done: smb2_deltree(tree1, BASEDIR); return ret; }