summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/librpc/idl/samr.idl70
-rw-r--r--source4/torture/rpc/samr.c237
2 files changed, 273 insertions, 34 deletions
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
index 6d2b8cfbe6..41071a1f9c 100644
--- a/source4/librpc/idl/samr.idl
+++ b/source4/librpc/idl/samr.idl
@@ -292,7 +292,7 @@
NTSTATUS samr_GetAliasMembership(
[in,ref] policy_handle *handle,
- [in,ref] lsa_SidArray *sids,
+ [in,ref] lsa_SidArray *sids,
[out] samr_Ids *rids
);
@@ -679,7 +679,31 @@
/************************/
/* Function 0x26 */
- NTSTATUS samr_CHANGE_PASSWORD_USER();
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 hash[16];
+ } samr_Hash;
+
+ /*
+ this interface is quite mysterious. I can make w2k3 give me
+ NT_STATUS_PASSWORD_RESTRICTION and NT_STATUS_WRONG_PASSWORD
+ with various options, but so far I haven't managed a successful
+ password change. Perhaps this interface is disabled now?
+ Needs testing against NT4
+ */
+ NTSTATUS samr_ChangePasswordUser(
+ [in,ref] policy_handle *handle,
+ [in] bool8 unknown1,
+ [in] samr_Hash *hash1,
+ [in] samr_Hash *hash2,
+ [in] bool8 unknown2,
+ [in] samr_Hash *hash3,
+ [in] samr_Hash *hash4,
+ [in] bool8 unknown3,
+ [in] samr_Hash *hash5,
+ [in] bool8 unknown4,
+ [in] samr_Hash *hash6
+ );
/************************/
/* Function 0x27 */
@@ -764,17 +788,48 @@
[out,switch_is(level)] samr_DispInfo info
);
+
/************************/
/* Function 0x29 */
- NTSTATUS samr_GET_DISPLAY_ENUMERATION_INDEX();
+
+ /*
+ this seems to be an alphabetic search function. The returned index
+ is the index for samr_QueryDisplayInfo needed to get names occurring
+ after the specified name. The supplied name does not need to exist
+ in the database (for example you can supply just a first letter for
+ searching starting at that letter)
+
+ The level corresponds to the samr_QueryDisplayInfo level
+ */
+ NTSTATUS samr_GetDisplayEnumerationIndex(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [in] samr_Name name,
+ [out] uint32 idx
+ );
+
+
/************************/
/* Function 0x2a */
- NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_DOMAIN();
+
+ /*
+ w2k3 return NT_STATUS_NOT_IMPLEMENTED for this
+ */
+ NTSTATUS samr_TestPrivateFunctionsDomain(
+ [in,ref] policy_handle *handle
+ );
+
/************************/
/* Function 0x2b */
- NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_USER();
+
+ /*
+ w2k3 return NT_STATUS_NOT_IMPLEMENTED for this
+ */
+ NTSTATUS samr_TestPrivateFunctionsUser(
+ [in,ref] policy_handle *handle
+ );
/************************/
@@ -799,7 +854,10 @@
/************************/
/* Function 0x2d */
- NTSTATUS samr_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN();
+ NTSTATUS samr_RemoveMemberFromForeignDomain(
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid
+ );
/************************/
/* Function 0x2e */
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index d4e04cda2c..9465dd135b 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -324,6 +324,100 @@ static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *domain_handle, const char *name,
+ uint32 *rid)
+{
+ NTSTATUS status;
+ struct samr_LookupNames n;
+ struct samr_Name sname;
+
+ init_samr_Name(&sname, name);
+
+ n.in.handle = domain_handle;
+ n.in.num_names = 1;
+ n.in.names = &sname;
+ status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
+ if (NT_STATUS_IS_OK(status)) {
+ *rid = n.out.rids.ids[0];
+ }
+
+ return status;
+}
+
+static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *domain_handle,
+ const char *name, struct policy_handle *user_handle)
+{
+ NTSTATUS status;
+ struct samr_OpenUser r;
+ uint32 rid;
+
+ status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ r.in.handle = domain_handle;
+ r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ r.in.rid = rid;
+ r.out.acct_handle = user_handle;
+ status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
+ }
+
+ return status;
+}
+
+
+static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct samr_ChangePasswordUser r;
+ BOOL ret = True;
+ struct samr_Hash hash1, hash2, hash3, hash4;
+ const char *test_pass1 = "";
+ const char *test_pass2 = "newpass";
+ struct policy_handle user_handle;
+
+ status = test_OpenUser_byname(p, mem_ctx, handle, TEST_USERNAME, &user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ printf("Testing ChangePasswordUser\n");
+
+ nt_lm_owf_gen(test_pass1, hash1.hash, hash2.hash);
+ nt_lm_owf_gen(test_pass2, hash3.hash, hash4.hash);
+
+ r.in.handle = &user_handle;
+ r.in.unknown1 = 1;
+ r.in.hash1 = &hash1;
+ r.in.hash2 = &hash2;
+ r.in.unknown2 = 1;
+ r.in.hash3 = &hash3;
+ r.in.hash4 = &hash4;
+ r.in.unknown3 = 1;
+ r.in.hash5 = &hash3;
+ r.in.unknown4 = 1;
+ r.in.hash6 = &hash3;
+
+ status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+ if (!test_Close(p, mem_ctx, &user_handle)) {
+ ret = False;
+ }
+
+ return ret;
+}
+
+
static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *alias_handle)
{
@@ -382,6 +476,27 @@ static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *user_handle)
+{
+ struct samr_TestPrivateFunctionsUser r;
+ NTSTATUS status;
+ BOOL ret = True;
+
+ printf("Testing TestPrivateFunctionsUser\n");
+
+ r.in.handle = user_handle;
+
+ status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
+ printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+ return ret;
+}
+
+
static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
@@ -403,6 +518,10 @@ static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
ret = False;
}
+ if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
+ ret = False;
+ }
+
return ret;
}
@@ -434,32 +553,10 @@ static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
-static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *domain_handle, const char *name,
- uint32 *rid)
-{
- NTSTATUS status;
- struct samr_LookupNames n;
- struct samr_Name sname;
-
- init_samr_Name(&sname, name);
-
- n.in.handle = domain_handle;
- n.in.num_names = 1;
- n.in.names = &sname;
- status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
- if (NT_STATUS_IS_OK(status)) {
- *rid = n.out.rids.ids[0];
- }
-
- return status;
-}
-
static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, const char *name)
{
NTSTATUS status;
- struct samr_OpenUser r;
struct samr_DeleteUser d;
struct policy_handle acct_handle;
uint32 rid;
@@ -469,11 +566,7 @@ static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
goto failed;
}
- r.in.handle = handle;
- r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
- r.in.rid = rid;
- r.out.acct_handle = &acct_handle;
- status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
+ status = test_OpenUser_byname(p, mem_ctx, handle, name, &acct_handle);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
@@ -696,6 +789,10 @@ static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
}
+ if (!test_ChangePasswordUser(p, mem_ctx, domain_handle)) {
+ ret = False;
+ }
+
if (!test_user_ops(p, mem_ctx, user_handle)) {
ret = False;
}
@@ -1196,6 +1293,33 @@ static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct samr_GetDisplayEnumerationIndex r;
+ BOOL ret = True;
+ uint16 levels[] = {1, 2, 3, 4, 5};
+ int i;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
+
+ r.in.handle = handle;
+ r.in.level = levels[i];
+ init_samr_Name(&r.in.name, TEST_USERNAME);
+
+ status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("GetDisplayEnumerationIndex level %u failed - %s\n",
+ levels[i], nt_errstr(status));
+ ret = False;
+ }
+ }
+
+ return ret;
+}
+
static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
@@ -1294,7 +1418,6 @@ void add_string_to_array(TALLOC_CTX *mem_ctx,
/* Test whether querydispinfo level 5 and enumdomgroups return the same
set of group names. */
-
static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
@@ -1426,6 +1549,26 @@ static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *domain_handle)
+{
+ struct samr_TestPrivateFunctionsDomain r;
+ NTSTATUS status;
+ BOOL ret = True;
+
+ printf("Testing TestPrivateFunctionsDomain\n");
+
+ r.in.handle = domain_handle;
+
+ status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
+ printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+ return ret;
+}
+
static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle,
struct policy_handle *group_handle)
@@ -1470,6 +1613,7 @@ static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return False;
}
+
status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
if (!NT_STATUS_IS_OK(status)) {
printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
@@ -1532,6 +1676,31 @@ static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
+/*
+ its not totally clear what this does. It seems to accept any sid you like.
+*/
+static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *domain_handle)
+{
+ NTSTATUS status;
+ struct samr_RemoveMemberFromForeignDomain r;
+
+ r.in.handle = domain_handle;
+ r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
+
+ status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ return True;
+}
+
+
+
+
static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct dom_sid *sid)
{
@@ -1559,6 +1728,10 @@ static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return False;
}
+ if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
+ ret = False;
+ }
+
if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
ret = False;
}
@@ -1599,10 +1772,18 @@ static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
ret = False;
}
+ if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
+ ret = False;
+ }
+
if (!test_GroupList(p, mem_ctx, &domain_handle)) {
ret = False;
}
+ if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
+ ret = False;
+ }
+
if (!policy_handle_empty(&user_handle) &&
!test_DeleteUser(p, mem_ctx, &user_handle)) {
ret = False;