r4176: I just remeber that I have already implement STR_CONFORMANT
[samba.git] / source4 / torture / rpc / drsuapi.c
index 2938a1a7440eca8087bf6be9c3ca99f5e5d6d454..7bef1e53609d2d66cfdfd7201df13a9f4b9ecc2f 100644 (file)
 */
 
 #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;
 }