mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
600 lines
15 KiB
C
600 lines
15 KiB
C
|
/*
|
||
|
Unix SMB/CIFS implementation.
|
||
|
test suite for accessmasks on the SAMR pipe
|
||
|
|
||
|
Copyright (C) Ronnie Sahlberg 2007
|
||
|
|
||
|
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
|
||
|
the Free Software Foundation; either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "includes.h"
|
||
|
#include "torture/torture.h"
|
||
|
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||
|
#include "torture/rpc/rpc.h"
|
||
|
#include "param/param.h"
|
||
|
#include "libcli/security/security.h"
|
||
|
#include "librpc/gen_ndr/ndr_security.h"
|
||
|
|
||
|
|
||
|
/* test user created to test the ACLs associated to SAMR objects */
|
||
|
#define TEST_USER_NAME "samr_testuser"
|
||
|
|
||
|
|
||
|
static NTSTATUS torture_samr_Close(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p,
|
||
|
struct policy_handle *h)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct samr_Close cl;
|
||
|
|
||
|
cl.in.handle = h;
|
||
|
cl.out.handle = h;
|
||
|
status = dcerpc_samr_Close(p, tctx, &cl);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p,
|
||
|
uint32_t mask, struct policy_handle *h)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct samr_Connect5 r5;
|
||
|
union samr_ConnectInfo info;
|
||
|
|
||
|
info.info1.unknown1 = 0;
|
||
|
info.info1.unknown2 = 0;
|
||
|
r5.in.system_name = "";
|
||
|
r5.in.level = 1;
|
||
|
r5.in.info = &info;
|
||
|
r5.out.info = &info;
|
||
|
r5.out.connect_handle = h;
|
||
|
r5.in.access_mask = mask;
|
||
|
|
||
|
status = dcerpc_samr_Connect5(p, tctx, &r5);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
/* check which bits in accessmask allows us to connect to the server */
|
||
|
static bool test_samr_accessmask_Connect5(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct policy_handle h;
|
||
|
int i;
|
||
|
uint32_t mask;
|
||
|
|
||
|
printf("testing which bits in accessmask allows us to connect\n");
|
||
|
mask = 1;
|
||
|
for (i=0;i<33;i++) {
|
||
|
printf("testing Connect5 with access mask 0x%08x", mask);
|
||
|
status = torture_samr_Connect5(tctx, p, mask, &h);
|
||
|
mask <<= 1;
|
||
|
|
||
|
switch (i) {
|
||
|
case 6:
|
||
|
case 7:
|
||
|
case 8:
|
||
|
case 9:
|
||
|
case 10:
|
||
|
case 11:
|
||
|
case 12:
|
||
|
case 13:
|
||
|
case 14:
|
||
|
case 15:
|
||
|
case 20:
|
||
|
case 21:
|
||
|
case 22:
|
||
|
case 23:
|
||
|
case 26:
|
||
|
case 27:
|
||
|
printf(" expecting to fail");
|
||
|
/* of only one of these bits are set we expect to
|
||
|
fail by default
|
||
|
*/
|
||
|
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
/* these bits set are expected to succeed by default */
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &h);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
printf(" OK\n");
|
||
|
}
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
/* check which bits in accessmask allows us to EnumDomains()
|
||
|
by default we must specify at least one of :
|
||
|
SAMR/EnumDomains
|
||
|
Maximum
|
||
|
GenericAll
|
||
|
GenericRead
|
||
|
in the access mask to Connect5() in order to be allowed to perform
|
||
|
EnumDomains() on the policy handle returned from Connect5()
|
||
|
*/
|
||
|
static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct samr_EnumDomains ed;
|
||
|
struct policy_handle ch;
|
||
|
int i;
|
||
|
uint32_t mask;
|
||
|
uint32_t resume_handle = 0;
|
||
|
|
||
|
printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n");
|
||
|
mask = 1;
|
||
|
for (i=0;i<33;i++) {
|
||
|
printf("testing Connect5/EnumDomains with access mask 0x%08x", mask);
|
||
|
status = torture_samr_Connect5(tctx, p, mask, &ch);
|
||
|
mask <<= 1;
|
||
|
|
||
|
switch (i) {
|
||
|
case 4: /* SAMR/EnumDomains */
|
||
|
case 25: /* Maximum */
|
||
|
case 28: /* GenericAll */
|
||
|
case 31: /* GenericRead */
|
||
|
/* these bits set are expected to succeed by default */
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
ed.in.connect_handle = &ch;
|
||
|
ed.in.resume_handle = &resume_handle;
|
||
|
ed.in.buf_size = (uint32_t)-1;
|
||
|
ed.out.resume_handle = &resume_handle;
|
||
|
|
||
|
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("EnumDomains failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
printf(" expecting to fail");
|
||
|
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf(" OK\n");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ed.in.connect_handle = &ch;
|
||
|
ed.in.resume_handle = &resume_handle;
|
||
|
ed.in.buf_size = (uint32_t)-1;
|
||
|
ed.out.resume_handle = &resume_handle;
|
||
|
|
||
|
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
|
||
|
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
|
||
|
printf("EnumDomains failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
printf(" OK\n");
|
||
|
}
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* test how ACLs affect how/if a user can connect to the SAMR service
|
||
|
*
|
||
|
* samr_SetSecurity() returns SUCCESS when changing the ACL for
|
||
|
* a policy handle got from Connect5() but the ACL is not changed on
|
||
|
* the server
|
||
|
*/
|
||
|
static bool test_samr_connect_user_acl(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p,
|
||
|
struct cli_credentials *test_credentials,
|
||
|
const struct dom_sid *test_sid)
|
||
|
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct policy_handle ch;
|
||
|
struct policy_handle uch;
|
||
|
struct samr_QuerySecurity qs;
|
||
|
struct samr_SetSecurity ss;
|
||
|
struct security_ace ace;
|
||
|
struct security_descriptor *sd;
|
||
|
struct sec_desc_buf sdb;
|
||
|
bool ret = True;
|
||
|
int sd_size;
|
||
|
struct dcerpc_pipe *test_p;
|
||
|
const char *binding = torture_setting_string(tctx, "binding", NULL);
|
||
|
|
||
|
printf("testing ACLs to allow/prevent users to connect to SAMR");
|
||
|
|
||
|
/* connect to SAMR */
|
||
|
status = torture_samr_Connect5(tctx, p, SEC_FLAG_MAXIMUM_ALLOWED, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* get the current ACL for the SAMR policy handle */
|
||
|
qs.in.handle = &ch;
|
||
|
qs.in.sec_info = SECINFO_DACL;
|
||
|
status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("QuerySecurity failed - %s\n", nt_errstr(status));
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
/* how big is the security descriptor? */
|
||
|
sd_size = qs.out.sdbuf->sd_size;
|
||
|
|
||
|
|
||
|
/* add an ACE to the security descriptor to deny the user the
|
||
|
* 'connect to server' right
|
||
|
*/
|
||
|
sd = qs.out.sdbuf->sd;
|
||
|
ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
|
||
|
ace.flags = 0;
|
||
|
ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
|
||
|
ace.trustee = *test_sid;
|
||
|
status = security_descriptor_dacl_add(sd, &ace);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Failed to add ACE to security descriptor\n");
|
||
|
ret = False;
|
||
|
}
|
||
|
ss.in.handle = &ch;
|
||
|
ss.in.sec_info = SECINFO_DACL;
|
||
|
ss.in.sdbuf = &sdb;
|
||
|
sdb.sd = sd;
|
||
|
status = dcerpc_samr_SetSecurity(p, tctx, &ss);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("SetSecurity failed - %s\n", nt_errstr(status));
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Try to connect as the test user */
|
||
|
status = dcerpc_pipe_connect(tctx,
|
||
|
&test_p, binding, &ndr_table_samr,
|
||
|
test_credentials, NULL);
|
||
|
/* connect to SAMR as the user */
|
||
|
status = torture_samr_Connect5(tctx, test_p, SEC_FLAG_MAXIMUM_ALLOWED, &uch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
/* disconnec the user */
|
||
|
talloc_free(test_p);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* read the sequrity descriptor back. it should not have changed
|
||
|
* eventhough samr_SetSecurity returned SUCCESS
|
||
|
*/
|
||
|
status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("QuerySecurity failed - %s\n", nt_errstr(status));
|
||
|
ret = False;
|
||
|
}
|
||
|
if (sd_size != qs.out.sdbuf->sd_size) {
|
||
|
printf("security descriptor changed\n");
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
if (ret == True) {
|
||
|
printf(" OK\n");
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* check which bits in accessmask allows us to LookupDomain()
|
||
|
by default we must specify at least one of :
|
||
|
in the access mask to Connect5() in order to be allowed to perform
|
||
|
case 5: samr/opendomain
|
||
|
case 25: Maximum
|
||
|
case 28: GenericAll
|
||
|
case 29: GenericExecute
|
||
|
LookupDomain() on the policy handle returned from Connect5()
|
||
|
*/
|
||
|
static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct samr_LookupDomain ld;
|
||
|
struct policy_handle ch;
|
||
|
struct lsa_String dn;
|
||
|
int i;
|
||
|
uint32_t mask;
|
||
|
|
||
|
printf("testing which bits in Connect5 accessmask allows us to LookupDomain\n");
|
||
|
mask = 1;
|
||
|
for (i=0;i<33;i++) {
|
||
|
printf("testing Connect5/LookupDomain with access mask 0x%08x", mask);
|
||
|
status = torture_samr_Connect5(tctx, p, mask, &ch);
|
||
|
mask <<= 1;
|
||
|
|
||
|
switch (i) {
|
||
|
case 5:
|
||
|
case 25: /* Maximum */
|
||
|
case 28: /* GenericAll */
|
||
|
case 29: /* GenericExecute */
|
||
|
/* these bits set are expected to succeed by default */
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
ld.in.connect_handle = &ch;
|
||
|
ld.in.domain_name = &dn;
|
||
|
dn.string = lp_workgroup();
|
||
|
|
||
|
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
printf(" expecting to fail");
|
||
|
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf(" OK\n");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ld.in.connect_handle = &ch;
|
||
|
ld.in.domain_name = &dn;
|
||
|
dn.string = lp_workgroup();
|
||
|
|
||
|
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
|
||
|
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
|
||
|
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
printf(" OK\n");
|
||
|
}
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
/* check which bits in accessmask allows us to OpenDomain()
|
||
|
by default we must specify at least one of :
|
||
|
samr/opendomain
|
||
|
Maximum
|
||
|
GenericAll
|
||
|
GenericExecute
|
||
|
in the access mask to Connect5() in order to be allowed to perform
|
||
|
OpenDomain() on the policy handle returned from Connect5()
|
||
|
*/
|
||
|
static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
struct samr_LookupDomain ld;
|
||
|
struct samr_OpenDomain od;
|
||
|
struct policy_handle ch;
|
||
|
struct policy_handle dh;
|
||
|
struct lsa_String dn;
|
||
|
int i;
|
||
|
uint32_t mask;
|
||
|
|
||
|
|
||
|
/* first we must grab the sid of the domain */
|
||
|
status = torture_samr_Connect5(tctx, p, SEC_FLAG_MAXIMUM_ALLOWED, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
ld.in.connect_handle = &ch;
|
||
|
ld.in.domain_name = &dn;
|
||
|
dn.string = lp_workgroup();
|
||
|
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
printf("testing which bits in Connect5 accessmask allows us to OpenDomain\n");
|
||
|
mask = 1;
|
||
|
for (i=0;i<33;i++) {
|
||
|
printf("testing Connect5/OpenDomain with access mask 0x%08x", mask);
|
||
|
status = torture_samr_Connect5(tctx, p, mask, &ch);
|
||
|
mask <<= 1;
|
||
|
|
||
|
switch (i) {
|
||
|
case 5:
|
||
|
case 25: /* Maximum */
|
||
|
case 28: /* GenericAll */
|
||
|
case 29: /* GenericExecute */
|
||
|
/* these bits set are expected to succeed by default */
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Connect5 failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
od.in.connect_handle = &ch;
|
||
|
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||
|
od.in.sid = ld.out.sid;
|
||
|
od.out.domain_handle = &dh;
|
||
|
|
||
|
status = dcerpc_samr_OpenDomain(p, tctx, &od);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("OpenDomain failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &dh);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
printf(" expecting to fail");
|
||
|
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf(" OK\n");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
status = torture_samr_Close(tctx, p, &ch);
|
||
|
if (!NT_STATUS_IS_OK(status)) {
|
||
|
printf("Close failed - %s\n", nt_errstr(status));
|
||
|
return False;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
printf(" OK\n");
|
||
|
}
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
static bool test_samr_connect(struct torture_context *tctx,
|
||
|
struct dcerpc_pipe *p)
|
||
|
{
|
||
|
void *testuser;
|
||
|
const char *testuser_passwd;
|
||
|
struct cli_credentials *test_credentials;
|
||
|
bool ret = True;
|
||
|
const struct dom_sid *test_sid;
|
||
|
|
||
|
/* create a test user */
|
||
|
testuser = torture_create_testuser(tctx, TEST_USER_NAME, lp_workgroup(), ACB_NORMAL, &testuser_passwd);
|
||
|
if (!testuser) {
|
||
|
printf("Failed to create test user\n");
|
||
|
return False;
|
||
|
}
|
||
|
test_credentials = cli_credentials_init(tctx);
|
||
|
cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
|
||
|
cli_credentials_set_domain(test_credentials, lp_workgroup(), CRED_SPECIFIED);
|
||
|
cli_credentials_set_username(test_credentials, TEST_USER_NAME, CRED_SPECIFIED);
|
||
|
cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
|
||
|
test_sid = torture_join_user_sid(testuser);
|
||
|
|
||
|
|
||
|
/* test which bits in the accessmask to Connect5
|
||
|
will allow us to connect to the server
|
||
|
*/
|
||
|
if (!test_samr_accessmask_Connect5(tctx, p)) {
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* test which bits in the accessmask to Connect5 will allow
|
||
|
* us to call EnumDomains()
|
||
|
*/
|
||
|
if (!test_samr_accessmask_EnumDomains(tctx, p)) {
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
/* test which bits in the accessmask to Connect5 will allow
|
||
|
* us to call LookupDomain()
|
||
|
*/
|
||
|
if (!test_samr_accessmask_LookupDomain(tctx, p)) {
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* test which bits in the accessmask to Connect5 will allow
|
||
|
* us to call OpenDomain()
|
||
|
*/
|
||
|
if (!test_samr_accessmask_OpenDomain(tctx, p)) {
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* test if ACLs can be changed for the policy handle
|
||
|
* returned by Connect5
|
||
|
*/
|
||
|
if (!test_samr_connect_user_acl(tctx, p, test_credentials, test_sid)) {
|
||
|
ret = False;
|
||
|
}
|
||
|
|
||
|
/* remove the test user */
|
||
|
torture_leave_domain(testuser);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
struct torture_suite *torture_rpc_samr_accessmask(TALLOC_CTX *mem_ctx)
|
||
|
{
|
||
|
struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR_ACCESSMASK");
|
||
|
struct torture_rpc_tcase *tcase;
|
||
|
|
||
|
tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
|
||
|
&ndr_table_samr);
|
||
|
|
||
|
torture_rpc_tcase_add_test(tcase, "CONNECT", test_samr_connect);
|
||
|
|
||
|
return suite;
|
||
|
}
|