1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r4703: Add support for EnumTrustDomain, and expand the testsuite.

Add my copyright to the SAMR server.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2005-01-12 07:57:33 +00:00 committed by Gerald (Jerry) Carter
parent 7d8ba92da2
commit 51e94fa26c
4 changed files with 225 additions and 115 deletions

View File

@ -270,6 +270,9 @@
/******************/
/* Function: 0x0d */
/* w2k3 treats max_size as max_domains*60 */
const int LSA_ENUM_TRUST_DOMAIN_MULTIPLIER = 60;
typedef struct {
lsa_String name;
dom_sid2 *sid;
@ -283,7 +286,7 @@
NTSTATUS lsa_EnumTrustDom (
[in,ref] policy_handle *handle,
[in,out,ref] uint32 *resume_handle,
[in,range(0,1000)] uint32 num_entries,
[in,range(0,1000)] uint32 max_size,
[out,ref] lsa_DomainList *domains
);

View File

@ -627,7 +627,7 @@ static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_NO_MEMORY;
}
samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "securityIdentifier", name);
samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "securityIdentifier", sid_string);
}
/* pull in all the template attributes. Note this is always from the global samdb */
@ -761,11 +761,12 @@ static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
if (!trusted_domain_state) {
return NT_STATUS_NO_MEMORY;
}
trusted_domain_state->policy = policy_state;
/* search for the trusted_domain record */
ret = samdb_search(trusted_domain_state->policy->sam_ctx,
mem_ctx, policy_state->system_dn, &msgs, attrs,
"(&(cn=%s)(objectclass=trustedDomain))",
"(&(flatname=%s)(objectclass=trustedDomain))",
r->in.name.string);
if (ret == 0) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@ -818,7 +819,7 @@ static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLO
lsa_DeleteTrustDomain
*/
static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_DeleteTrustDomain *r)
struct lsa_DeleteTrustDomain *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
@ -885,13 +886,88 @@ static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
}
/*
comparison function for sorting lsa_DomainInformation array
*/
static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
{
return strcasecmp(e1->name.string, e2->name.string);
}
/*
lsa_EnumTrustDom
*/
static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_EnumTrustDom *r)
struct lsa_EnumTrustDom *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
struct dcesrv_handle *policy_handle;
struct lsa_DomainInformation *entries;
struct lsa_policy_state *policy_state;
struct ldb_message **domains;
const char *attrs[] = {
"flatname",
"securityIdentifier",
NULL
};
int count, i;
*r->out.resume_handle = 0;
r->out.domains->domains = NULL;
r->out.domains->count = 0;
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
policy_state = policy_handle->data;
/* search for all users in this domain. This could possibly be cached and
resumed based on resume_key */
count = samdb_search(policy_state->sam_ctx, mem_ctx, policy_state->system_dn, &domains, attrs,
"objectclass=trustedDomain");
if (count == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
if (count == 0 || r->in.max_size == 0) {
return NT_STATUS_OK;
}
/* convert to lsa_DomainInformation format */
entries = talloc_array_p(mem_ctx, struct lsa_DomainInformation, count);
if (!entries) {
return NT_STATUS_NO_MEMORY;
}
for (i=0;i<count;i++) {
entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
}
/* sort the results by name */
qsort(entries, count, sizeof(struct lsa_DomainInformation),
(comparison_fn_t)compare_DomainInformation);
if (*r->in.resume_handle >= count) {
*r->out.resume_handle = -1;
return NT_STATUS_NO_MORE_ENTRIES;
}
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 60 */
r->out.domains->count = count - *r->in.resume_handle;
r->out.domains->count = MIN(r->out.domains->count,
1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
r->out.domains->domains = entries + *r->in.resume_handle;
r->out.domains->count = r->out.domains->count;
if (r->out.domains->count < count - *r->in.resume_handle) {
*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
return STATUS_MORE_ENTRIES;
}
return NT_STATUS_OK;
}

View File

@ -5,6 +5,7 @@
Copyright (C) Andrew Tridgell 2004
Copyright (C) Volker Lendecke 2004
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -557,7 +557,7 @@ static BOOL test_Delete(struct dcerpc_pipe *p,
NTSTATUS status;
struct lsa_Delete r;
printf("\ntesting Delete\n");
printf("testing Delete\n");
r.in.handle = handle;
status = dcerpc_lsa_Delete(p, mem_ctx, &r);
@ -566,8 +566,6 @@ static BOOL test_Delete(struct dcerpc_pipe *p,
return False;
}
printf("\n");
return True;
}
@ -1235,90 +1233,68 @@ static BOOL test_EnumPrivs(struct dcerpc_pipe *p,
return ret;
}
static BOOL test_EnumTrustDom(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
static BOOL test_query_each_TrustDom(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
struct lsa_DomainList *domains)
{
struct lsa_EnumTrustDom r;
NTSTATUS status;
uint32_t resume_handle = 0;
struct lsa_DomainList domains;
int i,j;
BOOL ret = True;
printf("\nTesting EnumTrustDom\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
r.in.num_entries = 100;
r.out.domains = &domains;
r.out.resume_handle = &resume_handle;
status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
/* NO_MORE_ENTRIES is allowed */
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
return True;
}
if (!NT_STATUS_IS_OK(status)) {
printf("EnumTrustDom failed - %s\n", nt_errstr(status));
return False;
}
printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
for (i=0; i< domains.count; i++) {
for (i=0; i< domains->count; i++) {
struct lsa_OpenTrustedDomain trust;
struct lsa_OpenTrustedDomainByName trust_by_name;
struct policy_handle trustdom_handle;
struct policy_handle handle2;
struct lsa_Close c;
int levels [] = {1, 3, 6, 8, 12};
trust.in.handle = handle;
trust.in.sid = domains.domains[i].sid;
trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
trust.out.trustdom_handle = &trustdom_handle;
status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
if (!NT_STATUS_IS_OK(status)) {
printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
return False;
}
c.in.handle = &trustdom_handle;
c.out.handle = &handle2;
for (j=0; j < ARRAY_SIZE(levels); j++) {
struct lsa_QueryTrustedDomainInfo q;
union lsa_TrustedDomainInfo info;
q.in.trustdom_handle = &trustdom_handle;
q.in.level = levels[j];
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
if (domains->domains[i].sid) {
trust.in.handle = handle;
trust.in.sid = domains->domains[i].sid;
trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
trust.out.trustdom_handle = &trustdom_handle;
status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = False;
printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
return False;
}
c.in.handle = &trustdom_handle;
c.out.handle = &handle2;
for (j=0; j < ARRAY_SIZE(levels); j++) {
struct lsa_QueryTrustedDomainInfo q;
union lsa_TrustedDomainInfo info;
q.in.trustdom_handle = &trustdom_handle;
q.in.level = levels[j];
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = False;
}
}
status = dcerpc_lsa_Close(p, mem_ctx, &c);
if (!NT_STATUS_IS_OK(status)) {
printf("Close of trusted domain failed - %s\n", nt_errstr(status));
return False;
}
}
status = dcerpc_lsa_Close(p, mem_ctx, &c);
if (!NT_STATUS_IS_OK(status)) {
printf("Close of trusted domain failed - %s\n", nt_errstr(status));
return False;
}
trust_by_name.in.handle = handle;
trust_by_name.in.name = domains.domains[i].name;
trust_by_name.in.name = domains->domains[i].name;
trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
trust_by_name.out.trustdom_handle = &trustdom_handle;
status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
if (!NT_STATUS_IS_OK(status)) {
printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
return False;
@ -1350,8 +1326,13 @@ static BOOL test_EnumTrustDom(struct dcerpc_pipe *p,
for (j=0; j < ARRAY_SIZE(levels); j++) {
struct lsa_QueryTrustedDomainInfoBySid q;
union lsa_TrustedDomainInfo info;
if (!domains->domains[i].sid) {
continue;
}
q.in.handle = handle;
q.in.dom_sid = domains.domains[i].sid;
q.in.dom_sid = domains->domains[i].sid;
q.in.level = levels[j];
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
@ -1366,7 +1347,7 @@ static BOOL test_EnumTrustDom(struct dcerpc_pipe *p,
struct lsa_QueryTrustedDomainInfoByName q;
union lsa_TrustedDomainInfo info;
q.in.handle = handle;
q.in.trusted_domain = domains.domains[i].name;
q.in.trusted_domain = domains->domains[i].name;
q.in.level = levels[j];
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
@ -1376,10 +1357,51 @@ static BOOL test_EnumTrustDom(struct dcerpc_pipe *p,
ret = False;
}
}
}
return ret;
}
static BOOL test_EnumTrustDom(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
struct lsa_EnumTrustDom r;
NTSTATUS enum_status;
uint32_t resume_handle = 0;
struct lsa_DomainList domains;
BOOL ret = True;
printf("\nTesting EnumTrustDom\n");
do {
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
r.out.domains = &domains;
r.out.resume_handle = &resume_handle;
enum_status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
/* NO_MORE_ENTRIES is allowed */
if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
return True;
} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
/* Windows 2003 gets this off by one on the first run */
if (r.out.domains->count < 3 || r.out.domains->count > 4) {
printf("EnumTrustDom didn't fill the buffer we "
"asked it to (got %d, expected %d / %d == %d entries)\n",
r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
ret = False;
}
} else if (!NT_STATUS_IS_OK(enum_status)) {
printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
return False;
}
ret &= test_query_each_TrustDom(p, mem_ctx, handle, &domains);
} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
return ret;
}
@ -1392,46 +1414,52 @@ static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p,
BOOL ret = True;
struct lsa_CreateTrustedDomain r;
struct lsa_TrustInformation trustinfo;
struct dom_sid *domsid;
struct policy_handle trustdom_handle;
struct dom_sid *domsid[12];
struct policy_handle trustdom_handle[12];
struct lsa_QueryTrustedDomainInfo q;
int i;
printf("Testing CreateTrustedDomain\n");
printf("Testing CreateTrustedDomain for 12 domains\n");
domsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-21-97398-379795-12345");
for (i=0; i< 12; i++) {
char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i);
char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i);
domsid[i] = dom_sid_parse_talloc(mem_ctx, trust_sid);
trustinfo.sid = domsid;
init_lsa_String(&trustinfo.name, "torturedomain");
trustinfo.sid = domsid[i];
init_lsa_String(&trustinfo.name, trust_name);
r.in.handle = handle;
r.in.info = &trustinfo;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.trustdom_handle = &trustdom_handle;
status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.name);
r.in.handle = handle;
r.in.info = &trustinfo;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.trustdom_handle = &trustdom_handle[i];
status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
return False;
}
q.in.trustdom_handle = &trustdom_handle;
q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = False;
}
if (!q.out.info) {
ret = False;
} else {
if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) {
printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
q.out.info->name.netbios_name.string, trustinfo.name.string);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.name);
status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
ret = False;
} else {
q.in.trustdom_handle = &trustdom_handle[i];
q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = False;
} else if (!q.out.info) {
ret = False;
} else {
if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) {
printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
q.out.info->name.netbios_name.string, trustinfo.name.string);
ret = False;
}
}
}
}
@ -1439,9 +1467,11 @@ static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p,
if (!test_EnumTrustDom(p, mem_ctx, handle)) {
ret = False;
}
if (!test_Delete(p, mem_ctx, &trustdom_handle)) {
ret = False;
for (i=0; i<12; i++) {
if (!test_Delete(p, mem_ctx, &trustdom_handle[i])) {
ret = False;
}
}
return ret;