r20353: Restructure the DRSUAPI DsGetDomainControllerInfo test, because as
authorAndrew Bartlett <abartlet@samba.org>
Wed, 27 Dec 2006 02:01:38 +0000 (02:01 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:30:15 +0000 (14:30 -0500)
usual things are more complex than they appear.

Also remove the incorrect server-side implementation, which blindly
assumed some sense of consistancy across the API switch levels.

Andrew Bartlett
(This used to be commit 79941adbff843f5027dacd31b972deca4a1557ec)

source4/librpc/idl/drsuapi.idl
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/scripting/ejs/ejsrpc.c
source4/scripting/ejs/ejsrpc.h
source4/torture/rpc/drsuapi.c

index fe0e98fe0ddba7b699b9ebd60349dcdbeebb82a6..02cafb64c166718f8b535864c709545306b20ac0 100644 (file)
@@ -1065,13 +1065,13 @@ interface drsuapi
        } drsuapi_DsGetDCInfoCtr2;
 
        typedef struct {
-               uint32 unknown1;
+               [flag(BIG_ENDIAN)] ipv4address last_logon_ipv4_ip;
                uint32 unknown2;
                uint32 unknown3;
                uint32 unknown4;
                uint32 unknown5;
                uint32 unknown6;
-               [charset(UTF16),string] uint16 *server_nt4_account;
+               [charset(UTF16),string] uint16 *nt4_account;
        } drsuapi_DsGetDCInfo01;
 
        typedef struct {
index dd26145522dddf16ab41718bfab9890e538c030f..eaf2c6591954f1ff5467235e0a853b5bb4e0d91e 100644 (file)
@@ -374,7 +374,6 @@ static WERROR drsuapi_DsGetDomainControllerInfo_1(struct drsuapi_bind_state *b_s
        struct ldb_dn *sites_dn;
        struct ldb_result *res;
 
-       const char *attrs_account_01[] = { "samAccountName", NULL };
        const char *attrs_account_1[] = { "cn", "dnsHostName", NULL };
        const char *attrs_account_2[] = { "cn", "dnsHostName", "objectGUID", NULL };
 
@@ -384,12 +383,10 @@ static WERROR drsuapi_DsGetDomainControllerInfo_1(struct drsuapi_bind_state *b_s
 
        const char *attrs_ntds[] = { "options", "objectGUID", NULL };
 
-       const char *attrs_01[] = { "serverReference", NULL };
        const char *attrs_1[] = { "serverReference", "cn", "dnsHostName", NULL };
        const char *attrs_2[] = { "serverReference", "cn", "dnsHostName", "objectGUID", NULL };
        const char **attrs;
 
-       struct drsuapi_DsGetDCInfoCtr01 *ctr01;
        struct drsuapi_DsGetDCInfoCtr1 *ctr1;
        struct drsuapi_DsGetDCInfoCtr2 *ctr2;
 
@@ -408,8 +405,8 @@ static WERROR drsuapi_DsGetDomainControllerInfo_1(struct drsuapi_bind_state *b_s
 
        switch (r->out.level_out) {
        case -1:
-               attrs = attrs_01;
-               break;
+               /* this level is not like the others */
+               return WERR_UNKNOWN_LEVEL;
        case 1:
                attrs = attrs_1;
                break;
@@ -428,29 +425,6 @@ static WERROR drsuapi_DsGetDomainControllerInfo_1(struct drsuapi_bind_state *b_s
        }
 
        switch (r->out.level_out) {
-       case -1:
-               ctr01 = &r->out.ctr.ctr01;
-               ctr01->count = res->count;
-               ctr01->array = talloc_zero_array(mem_ctx, 
-                                                struct drsuapi_DsGetDCInfo01, 
-                                                res->count);
-               for (i=0; i < res->count; i++) {
-                       struct ldb_result *res_account;
-                       struct ldb_dn *ref_dn
-                               = ldb_msg_find_attr_as_dn(b_state->sam_ctx, 
-                                                         mem_ctx, res->msgs[i], 
-                                                         "serverReference");
-                       ret = ldb_search_exp_fmt(b_state->sam_ctx, mem_ctx, &res_account, ref_dn, 
-                                                LDB_SCOPE_BASE, attrs_account_01, "objectClass=computer");
-                       if (ret) {
-                               return WERR_GENERAL_FAILURE;
-                       }
-                       if (res_account->count == 1) {
-                               ctr01->array[i].server_nt4_account
-                                       = ldb_msg_find_attr_as_string(res_account->msgs[0], "samAccountName", NULL);
-                       }
-               }
-               break;
        case 1:
                ctr1 = &r->out.ctr.ctr1;
                ctr1->count = res->count;
index 08a675a11727acdf246e6bc4ff68cb6917ddad83..c41cdd972bdfb7c59ca441e4ca97f8f298f47665 100644 (file)
@@ -253,6 +253,26 @@ NTSTATUS ejs_push_string(struct ejs_rpc *ejs,
        return mprSetVar(v, name, mprString(s));
 }
 
+
+/*
+  pull a ipv4address (internally a string)
+*/
+NTSTATUS ejs_pull_ipv4address(struct ejs_rpc *ejs, 
+                             struct MprVar *v, const char *name, const char **s)
+{
+       return ejs_pull_string(ejs, v, name, s);
+}
+
+/*
+  push a ipv4address (internally a string)
+*/
+NTSTATUS ejs_push_ipv4address(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, char * const *s)
+{
+       return ejs_push_string(ejs, v, name, *s);
+}
+
+
 NTSTATUS ejs_pull_dom_sid(struct ejs_rpc *ejs, 
                          struct MprVar *v, const char *name, struct dom_sid *r)
 {
index bc9a38fcb3c8597249354e52573d6fbcb02c8144..72880421201b5dd2212efd439578a64f2e8cd0a6 100644 (file)
@@ -93,6 +93,10 @@ NTSTATUS ejs_pull_string(struct ejs_rpc *ejs,
                         struct MprVar *v, const char *name, const char **s);
 NTSTATUS ejs_push_string(struct ejs_rpc *ejs, 
                         struct MprVar *v, const char *name, const char *s);
+NTSTATUS ejs_pull_ipv4address(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, const char **s);
+NTSTATUS ejs_push_ipv4address(struct ejs_rpc *ejs, 
+                        struct MprVar *v, const char *name, char * const *s);
 void ejs_set_constant_int(int eid, const char *name, int value);
 void ejs_set_constant_string(int eid, const char *name, const char *value);
 
index d876b079dd379d71872d8097baf85d5b0f5d2f4a..3ce1d1053af958969676edbe17e3af91f5d5a90c 100644 (file)
@@ -66,64 +66,119 @@ static BOOL test_DsGetDomainControllerInfo(struct dcerpc_pipe *p, TALLOC_CTX *me
        NTSTATUS status;
        struct drsuapi_DsGetDomainControllerInfo r;
        BOOL ret = True;
+       BOOL found = False;
+       int i, j, k;
+       
+       struct {
+               const char *name;
+               WERROR expected;
+       } names[] = { 
+               {       
+                       .name = torture_join_dom_netbios_name(priv->join),
+                       .expected = WERR_OK
+               },
+               {
+                       .name = torture_join_dom_dns_name(priv->join),
+                       .expected = WERR_OK
+               },
+               {
+                       .name = "__UNKNOWN_DOMAIN__",
+                       .expected = WERR_DS_OBJ_NOT_FOUND
+               },
+               {
+                       .name = "unknown.domain.samba.example.com",
+                       .expected = WERR_DS_OBJ_NOT_FOUND
+               },
+       };
+       int levels[] = {1, 2};
+       int level;
+
+       for (i=0; i < ARRAY_SIZE(levels); i++) {
+               for (j=0; j < ARRAY_SIZE(names); j++) {
+                       level = levels[i];
+                       r.in.bind_handle = &priv->bind_handle;
+                       r.in.level = 1;
+                       
+                       r.in.req.req1.domain_name = names[j].name;
+                       r.in.req.req1.level = level;
+                       
+                       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_EQUAL(r.out.result, names[j].expected)) {
+                               printf("DsGetDomainControllerInfo level %d\n"
+                                      "    with dns domain failed - %s, expected %s\n",
+                                      r.in.req.req1.level, win_errstr(r.out.result),
+                                      win_errstr(names[j].expected));
+                               ret = False;
+                       }
+               
+                       if (!W_ERROR_IS_OK(r.out.result)) {
+                               /* If this was an error, we can't read the result structure */
+                               continue;
+                       }
 
-       r.in.bind_handle = &priv->bind_handle;
-       r.in.level = 1;
-
-       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_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);
+                       if (r.in.req.req1.level != r.out.level_out) {
+                               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level in (%d) != out (%d)\n",
+                                      r.in.req.req1.level, r.out.level_out);
+                               ret = False;
+                               /* We can't safely read the result structure */
+                               continue;
+                       }
+                       switch (level) {
+                       case 1:
+                               for (k=0; k < r.out.ctr.ctr1.count; k++) {
+                                       if (strcasecmp_m(r.out.ctr.ctr1.array[k].netbios_name, 
+                                                        torture_join_netbios_name(priv->join))) {
+                                               found = True;
+                                       }
+                               }
+                               break;
+                       case 2:
+                               if (r.out.ctr.ctr2.count > 0) {
+                                       priv->dcinfo    = r.out.ctr.ctr2.array[0];
+                               }
+                               for (k=0; k < r.out.ctr.ctr2.count; k++) {
+                                       if (strcasecmp_m(r.out.ctr.ctr2.array[k].netbios_name, 
+                                                        torture_join_netbios_name(priv->join))) {
+                                               found = True;
+                                       }
+                               }
+                               break;
+                       }
+                       if (!found) {
+                               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d: Failed to find the domain controller (%s) we just created during the join\n",
+                                      r.in.req.req1.level,
+                                      torture_join_netbios_name(priv->join));
+                               ret = False;
+                       }
                }
-               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.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];
-               }
+       if (lp_parm_bool(-1, "torture", "samba4", False)) {
+               printf("skipping DsGetDomainControllerInfo level -1 test against Samba4\n");
+               return ret;
        }
 
+       r.in.bind_handle = &priv->bind_handle;
+       r.in.level = 1;
+       
+       r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
        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);
-
+              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);
@@ -131,62 +186,35 @@ static BOOL test_DsGetDomainControllerInfo(struct dcerpc_pipe *p, TALLOC_CTX *me
                        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);
+                      "    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));
+                      "    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);
+       
+       {
+               const char *dc_account = talloc_asprintf(mem_ctx, "%s\\%s$",
+                                                        torture_join_dom_netbios_name(priv->join), 
+                                                        priv->dcinfo.netbios_name);
+               for (k=0; k < r.out.ctr.ctr1.count; k++) {
+                       if (strcasecmp_m(r.out.ctr.ctr01.array[k].nt4_account, 
+                                        dc_account)) {
+                               found = True;
+                       }
                }
-               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);
+               if (!found) {
+                       printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d: Failed to find the domain controller (%s) in last logon records\n",
+                              r.in.req.req1.level,
+                              dc_account);
+                       ret = False;
                }
-               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;
 }