r267: added IDL and test code for samr_ChangePasswordUser(),
authorAndrew Tridgell <tridge@samba.org>
Sun, 18 Apr 2004 04:06:15 +0000 (04:06 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:51:18 +0000 (12:51 -0500)
samr_GetDisplayEnumerationIndex(), samr_TestPrivateFunctionsDomain(),
samr_TestPrivateFunctionsUser() and samr_RemoveMemberFromForeignDomain()

source/librpc/idl/samr.idl
source/torture/rpc/samr.c

index 6d2b8cfbe6d1859689270f637a088208b8782d65..41071a1f9c7d029b2e038f4f30f7a10409d823c9 100644 (file)
 
        NTSTATUS samr_GetAliasMembership(
                [in,ref]      policy_handle *handle,
-               [in,ref]  lsa_SidArray  *sids,
+               [in,ref]      lsa_SidArray  *sids,
                [out]         samr_Ids *rids
                );
 
 
        /************************/
        /* 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     */
                [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
+               );
 
 
        /************************/
 
        /************************/
        /* Function    0x2d     */
-       NTSTATUS samr_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN();
+       NTSTATUS samr_RemoveMemberFromForeignDomain(
+               [in,ref]    policy_handle *handle,
+               [in,ref]    dom_sid2 *sid
+               );
 
        /************************/
        /* Function    0x2e     */
index d4e04cda2c8546aa317fdd6b6876920b6cfb4867..9465dd135bfffebd9d3b94349c5b849e03e5114b 100644 (file)
@@ -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;