diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/idl/drsuapi.idl | 4 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 30 | ||||
-rw-r--r-- | source4/scripting/ejs/ejsrpc.c | 20 | ||||
-rw-r--r-- | source4/scripting/ejs/ejsrpc.h | 4 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi.c | 222 |
5 files changed, 153 insertions, 127 deletions
diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index fe0e98fe0d..02cafb64c1 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -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 { diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index dd26145522..eaf2c65919 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -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; diff --git a/source4/scripting/ejs/ejsrpc.c b/source4/scripting/ejs/ejsrpc.c index 08a675a117..c41cdd972b 100644 --- a/source4/scripting/ejs/ejsrpc.c +++ b/source4/scripting/ejs/ejsrpc.c @@ -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) { diff --git a/source4/scripting/ejs/ejsrpc.h b/source4/scripting/ejs/ejsrpc.h index bc9a38fcb3..7288042120 100644 --- a/source4/scripting/ejs/ejsrpc.h +++ b/source4/scripting/ejs/ejsrpc.h @@ -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); diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c index d876b079dd..3ce1d1053a 100644 --- a/source4/torture/rpc/drsuapi.c +++ b/source4/torture/rpc/drsuapi.c @@ -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; } |