*/
#include "includes.h"
+#include "librpc/gen_ndr/ndr_drsuapi.h"
+
+struct DsPrivate {
+ struct policy_handle bind_handle;
+ struct GUID bind_guid;
+ const char *domain_obj_dn;
+ const char *domain_guid_str;
+ struct GUID domain_guid;
+ struct drsuapi_DsGetDCInfo2 dcinfo;
+};
+
+static BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
+{
+ NTSTATUS status;
+ struct drsuapi_DsBind r;
+ BOOL ret = True;
+
+ GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
+
+ r.in.bind_guid = &priv->bind_guid;
+ r.in.bind_info = NULL;
+ r.out.bind_handle = &priv->bind_handle;
-static const char *machine_password;
+ printf("testing DsBind\n");
+
+ status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsBind failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
-#define TEST_MACHINE_NAME "torturetest"
+ return ret;
+}
-#if 0
-static void reopen(struct dcerpc_pipe **p, const struct dcerpc_interface_table *iface)
+static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
NTSTATUS status;
+ struct drsuapi_DsCrackNames r;
+ struct drsuapi_DsNameString names[1];
+ BOOL ret = True;
+ const char *dns_domain;
+ const char *nt4_domain;
+ const char *FQDN_1779_name;
+
+ ZERO_STRUCT(r);
+ r.in.bind_handle = &priv->bind_handle;
+ r.in.level = 1;
+ r.in.req.req1.unknown1 = 0x000004e4;
+ r.in.req.req1.unknown2 = 0x00000407;
+ r.in.req.req1.count = 1;
+ r.in.req.req1.names = names;
+ r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+ names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
- if (*p) {
- dcerpc_pipe_close(*p);
+ if (!ret) {
+ return ret;
}
- status = torture_rpc_connection(p, iface->endpoints->names[0], iface->uuid, iface->if_version);
+ dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
+ nt4_domain = r.out.ctr.ctr1->array[0].result_name;
+
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("Failed to reopen '%s' - %s\n", iface->name, nt_errstr(status));
- exit(1);
+ const char *errstr = nt_errstr(status);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
}
-}
-static void print_depth(int depth)
-{
- int i;
- for (i=0;i<depth;i++) {
- printf(" ");
+ if (!ret) {
+ return ret;
}
-}
-static void test_ptr_scan(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table *iface,
- int opnum, DATA_BLOB *base_in, int min_ofs, int max_ofs, int depth);
+ priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
+ GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
-static void try_expand(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table *iface,
- int opnum, DATA_BLOB *base_in, int insert_ofs, int depth)
-{
- DATA_BLOB stub_in, stub_out;
- int n;
- NTSTATUS status;
- struct dcerpc_pipe *p = NULL;
- reopen(&p, iface);
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+ names[0].str = priv->domain_guid_str;
- /* work out how much to expand to get a non fault */
- for (n=0;n<2000;n++) {
- stub_in = data_blob(NULL, base_in->length + n);
- data_blob_clear(&stub_in);
- memcpy(stub_in.data, base_in->data, insert_ofs);
- memcpy(stub_in.data+insert_ofs+n, base_in->data+insert_ofs, base_in->length-insert_ofs);
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
- status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- print_depth(depth);
- printf("expand by %d gives %s\n", n, nt_errstr(status));
- if (n >= 4) {
- test_ptr_scan(mem_ctx, iface, opnum, &stub_in,
- insert_ofs, insert_ofs+n, depth+1);
- }
- return;
- } else {
-#if 0
- print_depth(depth);
- printf("expand by %d gives fault 0x%x\n", n, p->last_fault_code);
-#endif
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = nt4_domain;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
}
- if (p->last_fault_code == 5) {
- reopen(&p, iface);
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, priv->dcinfo.netbios_name);
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
}
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
}
- dcerpc_pipe_close(p);
-}
+ if (!ret) {
+ return ret;
+ }
+ FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
-static void test_ptr_scan(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table *iface,
- int opnum, DATA_BLOB *base_in, int min_ofs, int max_ofs, int depth)
-{
- DATA_BLOB stub_in, stub_out;
- int ofs;
- NTSTATUS status;
- struct dcerpc_pipe *p = NULL;
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
+ names[0].str = FQDN_1779_name;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
- reopen(&p, iface);
+ if (!ret) {
+ return ret;
+ }
- stub_in = data_blob(NULL, base_in->length);
- memcpy(stub_in.data, base_in->data, base_in->length);
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
- /* work out which elements are pointers */
- for (ofs=min_ofs;ofs<=max_ofs-4;ofs+=4) {
- SIVAL(stub_in.data, ofs, 1);
- status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *errstr = nt_errstr(status);
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- print_depth(depth);
- printf("possible ptr at ofs %d - fault 0x%08x\n",
- ofs-min_ofs, p->last_fault_code);
- if (p->last_fault_code == 5) {
- reopen(&p, iface);
- }
- if (depth == 0) {
- try_expand(mem_ctx, iface, opnum, &stub_in, ofs+4, depth+1);
- } else {
- try_expand(mem_ctx, iface, opnum, &stub_in, max_ofs, depth+1);
- }
- SIVAL(stub_in.data, ofs, 0);
- continue;
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
+
+ printf("testing DsCrackNames with name '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid);
+
+ printf("testing DsCrackNames with Site GUID '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+ names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid);
+
+ printf("testing DsCrackNames with Computer GUID '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
+
+ printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
+
+ printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
+ }
+
+ r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
+ r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+ names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
+
+ printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
+ names[0].str, r.in.req.req1.format_desired);
+
+ status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
}
- SIVAL(stub_in.data, ofs, 0);
+ printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (!ret) {
+ return ret;
}
- dcerpc_pipe_close(p);
+ return ret;
}
-
-static void test_scan_call(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table *iface, int opnum)
+static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
- DATA_BLOB stub_in, stub_out;
- int i;
NTSTATUS status;
- struct dcerpc_pipe *p = NULL;
+ struct drsuapi_DsGetDomainControllerInfo r;
+ BOOL ret = True;
- reopen(&p, iface);
+ r.in.bind_handle = &priv->bind_handle;
+ r.in.level = 1;
- /* work out the minimum amount of input data */
- for (i=0;i<2000;i++) {
- stub_in = data_blob(NULL, i);
- data_blob_clear(&stub_in);
+ r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
+ r.in.req.req1.level = 1;
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
- status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
+ ret = False;
+ }
- if (NT_STATUS_IS_OK(status)) {
- printf("opnum %d min_input %d - output %d\n",
- opnum, stub_in.length, stub_out.length);
- dump_data(0, stub_out.data, stub_out.length);
- dcerpc_pipe_close(p);
- test_ptr_scan(mem_ctx, iface, opnum, &stub_in, 0, stub_in.length, 0);
- return;
+ r.in.req.req1.level = 2;
+
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
}
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
+ ret = False;
+ } else {
+ if (r.out.ctr.ctr2.count > 0) {
+ priv->dcinfo = r.out.ctr.ctr2.array[0];
+ }
+ }
+
+ r.in.req.req1.level = -1;
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *errstr = nt_errstr(status);
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- printf("opnum %d size %d fault 0x%08x\n", opnum, i, p->last_fault_code);
- if (p->last_fault_code == 5) {
- reopen(&p, iface);
- }
- continue;
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
+ ret = False;
+ }
+
+ r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
+ r.in.req.req1.level = 2;
+
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with netbios domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with netbios domain failed - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
+ ret = False;
+ }
+
+ r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
+ r.in.req.req1.level = 2;
+
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with invalid domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
+{
+ NTSTATUS status;
+ struct drsuapi_DsWriteAccountSpn r;
+ struct drsuapi_DsNameString names[2];
+ BOOL ret = True;
+
+ r.in.bind_handle = &priv->bind_handle;
+ r.in.level = 1;
+
+ printf("testing DsWriteAccountSpn\n");
+
+ r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
+ r.in.req.req1.unknown1 = 0;
+ r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
+ r.in.req.req1.count = 2;
+ r.in.req.req1.spn_names = names;
+ names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
+ names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
+
+ status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
}
+ printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
+ r.in.req.req1.unknown1 = 0;
- printf("opnum %d size %d error %s\n", opnum, i, nt_errstr(status));
+ status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
+ ret = False;
}
- printf("opnum %d minimum not found!?\n", opnum);
- dcerpc_pipe_close(p);
+ return ret;
}
+static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
+{
+ NTSTATUS status;
+ struct drsuapi_DsReplicaGetInfo r;
+ BOOL ret = True;
+ int i;
+ struct {
+ int32 level;
+ int32 infotype;
+ const char *obj_dn;
+ } array[] = {
+ {
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_CURSORS,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO,
+ DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_CURSORS2,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_CURSORS3,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
+ "__IGNORED__"
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_CURSURS05,
+ NULL
+ },{
+ DRSUAPI_DS_REPLICA_GET_INFO2,
+ DRSUAPI_DS_REPLICA_INFO_06,
+ NULL
+ }
+ };
+
+ r.in.bind_handle = &priv->bind_handle;
+
+ for (i=0; i < ARRAY_SIZE(array); i++) {
+ const char *object_dn;
+
+ printf("testing DsReplicaGetInfo level %d infotype %d\n",
+ array[i].level, array[i].infotype);
+
+ object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
+
+ r.in.level = array[i].level;
+ switch(r.in.level) {
+ case DRSUAPI_DS_REPLICA_GET_INFO:
+ r.in.req.req1.info_type = array[i].infotype;
+ r.in.req.req1.object_dn = object_dn;
+ ZERO_STRUCT(r.in.req.req1.guid1);
+ break;
+ case DRSUAPI_DS_REPLICA_GET_INFO2:
+ r.in.req.req2.info_type = array[i].infotype;
+ r.in.req.req2.object_dn = object_dn;
+ ZERO_STRUCT(r.in.req.req1.guid1);
+ r.in.req.req2.unknown1 = 0;
+ r.in.req.req2.string1 = NULL;
+ r.in.req.req2.string2 = NULL;
+ r.in.req.req2.unknown2 = 0;
+ break;
+ }
+
+ status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
+ printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
+ ret = False;
+ } else {
+ printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
+ array[i].level, array[i].infotype);
+ }
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+ }
-static BOOL test_scan(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+ return ret;
+}
+
+static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
- test_scan_call(mem_ctx, &dcerpc_table_drsuapi, 0x0);
- return True;
+ NTSTATUS status;
+ BOOL ret = True;
+ int i;
+ struct drsuapi_DsReplicaSync r;
+ struct drsuapi_DsReplicaSyncRequest1Info info1;
+
+ struct {
+ int32 level;
+ } array[] = {
+ {
+ 1
+ }
+ };
+
+ r.in.bind_handle = &priv->bind_handle;
+
+ for (i=0; i < ARRAY_SIZE(array); i++) {
+ printf("testing DsReplicaGetInfo level %d\n",
+ array[i].level);
+
+ r.in.level = array[i].level;
+ switch(r.in.level) {
+ case 1:
+ r.in.req.req1.info = &info1;
+ r.in.req.req1.info->unknown1 = 32;
+ r.in.req.req1.info->unknown2 = 120;
+ ZERO_STRUCT(r.in.req.req1.info->guid1);
+ ZERO_ARRAY(r.in.req.req1.info->unknown3);
+ r.in.req.req1.info->nc_dn = priv->domain_obj_dn;
+ r.in.req.req1.guid1 = priv->dcinfo.ntds_guid;
+ r.in.req.req1.string1 = NULL;
+ r.in.req.req1.unknown1 = 16;
+ break;
+ }
+
+ status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
+ 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(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+ }
+
+ return ret;
}
-#endif
-static BOOL test_DRSBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
NTSTATUS status;
- struct DRSUAPI_BIND r;
+ struct drsuapi_DsUnbind r;
BOOL ret = True;
- ZERO_STRUCT(r.in.blob);
+ r.in.bind_handle = &priv->bind_handle;
+ r.out.bind_handle = &priv->bind_handle;
- status = dcerpc_DRSUAPI_BIND(p, mem_ctx, &r);
+ printf("testing DsUnbind\n");
+
+ status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("DRSUAPI_BIND level failed - %s\n", nt_errstr(status));
+ const char *errstr = nt_errstr(status);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsBind failed - %s\n", win_errstr(r.out.result));
ret = False;
}
return ret;
}
-BOOL torture_rpc_drsuapi(int dummy)
+BOOL torture_rpc_drsuapi(void)
{
NTSTATUS status;
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
- void *join_ctx;
- const char *binding = lp_parm_string(-1, "torture", "binding");
+ struct DsPrivate priv;
- if (!binding) {
- printf("You must specify a ncacn binding string\n");
+ status = torture_rpc_connection(&p,
+ DCERPC_DRSUAPI_NAME,
+ DCERPC_DRSUAPI_UUID,
+ DCERPC_DRSUAPI_VERSION);
+ if (!NT_STATUS_IS_OK(status)) {
return False;
}
- lp_set_cmdline("netbios name", TEST_MACHINE_NAME);
+ printf("Connected to DRAUAPI pipe\n");
- join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
- &machine_password);
- if (!join_ctx) {
- printf("Failed to join as BDC\n");
- return False;
+ mem_ctx = talloc_init("torture_rpc_drsuapi");
+
+ ZERO_STRUCT(priv);
+
+ if (!test_DsBind(p, mem_ctx, &priv)) {
+ ret = False;
}
- status = dcerpc_pipe_connect(&p, binding,
- DCERPC_DRSUAPI_UUID,
- DCERPC_DRSUAPI_VERSION,
- lp_workgroup(),
- TEST_MACHINE_NAME"$",
- machine_password);
+ if (!test_DsGetDCInfo(p, mem_ctx, &priv)) {
+ ret = False;
+ }
- if (!NT_STATUS_IS_OK(status)) {
- return False;
+ if (!test_DsCrackNames(p, mem_ctx, &priv)) {
+ ret = False;
}
- mem_ctx = talloc_init("torture_rpc_drsuapi");
+ if (!test_DsWriteAccountSpn(p, mem_ctx, &priv)) {
+ ret = False;
+ }
+
+ if (!test_DsReplicaGetInfo(p, mem_ctx, &priv)) {
+ ret = False;
+ }
- if (!test_DRSBind(p, mem_ctx)) {
+ if (!test_DsReplicaSync(p, mem_ctx, &priv)) {
ret = False;
}
-#if 0
- if (!test_scan(p, mem_ctx)) {
+ if (!test_DsUnbind(p, mem_ctx, &priv)) {
ret = False;
}
-#endif
+
talloc_destroy(mem_ctx);
torture_rpc_close(p);
- torture_leave_domain(join_ctx);
-
return ret;
}