r6544: Use common structures between SAMR, NETLGON and the Krb5 PAC.
authorAndrew Bartlett <abartlet@samba.org>
Sun, 1 May 2005 08:05:17 +0000 (08:05 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:24 +0000 (13:16 -0500)
Fill out the group list for the SamLogon reply, so clients get the
supplementary groups.

Andrew Bartlett
(This used to be commit d9c31e60a72c345e3a23a7eb742906bcfc18721c)

source4/auth/auth_util.c
source4/librpc/idl/krb5pac.idl
source4/librpc/idl/netlogon.idl
source4/librpc/idl/samr.idl
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/samr/dcesrv_samr.c
source4/torture/rpc/samsync.c
source4/torture/rpc/xplogin.c

index 791d12fae6de4ce6bc0742292a02f7d467f4ce3c..ebd0b742270a5619e17ff14cbb5b545469f3c432 100644 (file)
@@ -338,16 +338,16 @@ NTSTATUS make_server_info_netlogon_validation(TALLOC_CTX *mem_ctx,
        server_info->primary_group_sid = dom_sid_add_rid(server_info, base->domain_sid, base->primary_gid);
        NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
 
-       server_info->n_domain_groups = base->group_count;
-       if (base->group_count) {
-               server_info->domain_groups = talloc_array(server_info, struct dom_sid*, base->group_count);
+       server_info->n_domain_groups = base->groups.count;
+       if (base->groups.count) {
+               server_info->domain_groups = talloc_array(server_info, struct dom_sid*, base->groups.count);
                NT_STATUS_HAVE_NO_MEMORY(server_info->domain_groups);
        } else {
                server_info->domain_groups = NULL;
        }
 
-       for (i = 0; i < base->group_count; i++) {
-               server_info->domain_groups[i] = dom_sid_add_rid(server_info, base->domain_sid, base->groupids[i].rid);
+       for (i = 0; i < base->groups.count; i++) {
+               server_info->domain_groups[i] = dom_sid_add_rid(server_info, base->domain_sid, base->groups.rids[i].rid);
                NT_STATUS_HAVE_NO_MEMORY(server_info->domain_groups[i]);
        }
 
index c5b64993f0889a2172e7c5a62d08816a40b0505d..a8a0ca06974b6429572c62f51d07b75e196c3304 100644 (file)
@@ -26,8 +26,7 @@ interface krb5pac
                uint32 unknown[5];
                netr_SamInfo3 info3;
                dom_sid2 *res_group_dom_sid;
-               uint32 res_groups_count;
-               [size_is(res_groups_count)] netr_GroupMembership *res_groups[];
+               samr_RidWithTypeArray res_groups;
        } PAC_LOGON_INFO;
 
        const uint8 PAC_TYPE_LOGON_INFO = 1;
index c97a640d186773abe172e1477236756277751916..0e601b372a278f1c0993e49c6c32b5026ff0fb57 100644 (file)
@@ -156,8 +156,7 @@ interface netlogon
                uint16 bad_password_count;
                uint32 rid;
                uint32 primary_gid;
-               uint32 group_count;
-               [size_is(group_count)] netr_GroupMembership *groupids[];
+               samr_RidWithTypeArray groups;
                uint32 user_flags;
                netr_UserSessionKey key;
                netr_String logon_server;
index 0a94756868d55cb66cc7ac054acd08da846c2d54..3cf2aeaf7eb18e8ca1aa573f4650c8a665b3832b 100644 (file)
        typedef struct {
                uint32 count;
                [size_is(count)] uint32 *rids[];
-               [size_is(count)] uint32 *unknown[];
-       } samr_ridArray;
+               [size_is(count)] uint32 *types[];
+       } samr_RidTypeArray;
 
        NTSTATUS samr_QueryGroupMember(
                [in,ref]  policy_handle *group_handle,
-               [out]     samr_ridArray *rids
+               [out]     samr_RidTypeArray *rids
                );
 
 
        /************************/
        /* Function    0x27     */
 
-       typedef struct {
+       typedef [public] struct {
                uint32 rid;
                uint32 type;
-       } samr_RidType;
+       } samr_RidWithType;
 
-       typedef struct {
+       typedef [public] struct {
                uint32     count;
-               [size_is(count)] samr_RidType *rid[];
-       } samr_RidArray;
+               [size_is(count)] samr_RidWithType *rids[];
+       } samr_RidWithTypeArray;
 
        NTSTATUS samr_GetGroupsForUser(
                [in,ref]   policy_handle *user_handle,
-               [out]      samr_RidArray  *rids
+               [out]      samr_RidWithTypeArray  *rids
                );
 
        /************************/
index 141aeef1bfac7e104b9c062281dbb6dc75d9bd49..6c32ac8b2c2c722e069ac3768f3866659ef78703 100644 (file)
@@ -522,8 +522,28 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
        sam->bad_password_count = sam->bad_password_count;
        sam->rid = server_info->account_sid->sub_auths[server_info->account_sid->num_auths-1];
        sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
-       sam->group_count = 0;
-       sam->groupids = NULL;
+
+       sam->groups.count = 0;
+       sam->groups.rids = NULL;
+
+       if (server_info->n_domain_groups > 0) {
+               int i;
+               sam->groups.rids = talloc_array(mem_ctx, struct samr_RidWithType,
+                                               server_info->n_domain_groups);
+
+               if (sam->groups.rids == NULL)
+                       return NT_STATUS_NO_MEMORY;
+
+               for (i=0; i<server_info->n_domain_groups; i++) {
+                       
+                       struct dom_sid *group_sid = server_info->domain_groups[i];
+                       sam->groups.rids[sam->groups.count].rid =
+                               group_sid->sub_auths[group_sid->num_auths-1];
+                       sam->groups.rids[sam->groups.count].type = 7;
+                       sam->groups.count += 1;
+               }
+       }
+
        sam->user_flags = 0; /* TODO: w2k3 uses 0x120 - what is this? */
        sam->acct_flags = server_info->acct_flags;
        sam->logon_server.string = lp_netbios_name();
index 968328fe9d92775ff84cdfd06c7cac1228a37a2c..9934a502dec043dc825910d74d18415cac311bea 100644 (file)
@@ -1741,7 +1741,7 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC
        struct samr_account_state *a_state;
        struct ldb_message **res;
        struct ldb_message_element *el;
-       struct samr_ridArray *array;
+       struct samr_RidTypeArray *array;
        const char * const attrs[2] = { "member", NULL };
        int ret;
 
@@ -1757,7 +1757,7 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       array = talloc(mem_ctx, struct samr_ridArray);
+       array = talloc(mem_ctx, struct samr_RidTypeArray);
 
        if (array == NULL)
                return NT_STATUS_NO_MEMORY;
@@ -1776,9 +1776,9 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC
                if (array->rids == NULL)
                        return NT_STATUS_NO_MEMORY;
 
-               array->unknown = talloc_array(mem_ctx, uint32_t,
-                                               el->num_values);
-               if (array->unknown == NULL)
+               array->types = talloc_array(mem_ctx, uint32_t,
+                                           el->num_values);
+               if (array->types == NULL)
                        return NT_STATUS_NO_MEMORY;
 
                for (i=0; i<el->num_values; i++) {
@@ -1797,7 +1797,7 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC
                        if (array->rids[i] == 0)
                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
 
-                       array->unknown[i] = 7; /* Not sure what this is.. */
+                       array->types[i] = 7; /* RID type of some kind, not sure what the value means. */
                }
        }
 
@@ -2809,7 +2809,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
        struct ldb_message **res;
        struct dom_sid *domain_sid;
        const char * const attrs[2] = { "objectSid", NULL };
-       struct samr_RidArray *array;
+       struct samr_RidWithTypeArray *array;
        int count;
 
        DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
@@ -2829,19 +2829,19 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
        if (count < 0)
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
 
-       array = talloc(mem_ctx, struct samr_RidArray);
+       array = talloc(mem_ctx, struct samr_RidWithTypeArray);
        if (array == NULL)
                return NT_STATUS_NO_MEMORY;
 
        array->count = 0;
-       array->rid = NULL;
+       array->rids = NULL;
 
        if (count > 0) {
                int i;
-               array->rid = talloc_array(mem_ctx, struct samr_RidType,
+               array->rids = talloc_array(mem_ctx, struct samr_RidWithType,
                                            count);
 
-               if (array->rid == NULL)
+               if (array->rids == NULL)
                        return NT_STATUS_NO_MEMORY;
 
                for (i=0; i<count; i++) {
@@ -2854,9 +2854,9 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
                                continue;
                        }
 
-                       array->rid[array->count].rid =
+                       array->rids[array->count].rid =
                                group_sid->sub_auths[group_sid->num_auths-1];
-                       array->rid[array->count].type = 7;
+                       array->rids[array->count].type = 7;
                        array->count += 1;
                }
        }
index d77c5a0d5eb13151ec46453e9a58ea0743ec6ca9..412b27c8ec0e50213606892023b77a4f8edf5245 100644 (file)
@@ -409,6 +409,7 @@ static BOOL samsync_handle_user(TALLOC_CTX *mem_ctx, struct samsync_state *samsy
        struct samr_QueryUserInfo q;
        struct policy_handle user_handle;
 
+       struct samr_GetGroupsForUser getgroups;
        if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
                printf("SamSync needs domain information before the users\n");
                return False;
@@ -431,9 +432,27 @@ static BOOL samsync_handle_user(TALLOC_CTX *mem_ctx, struct samsync_state *samsy
        TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle);
 
        nt_status = dcerpc_samr_QueryUserInfo(samsync_state->p_samr, mem_ctx, &q);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               printf("QueryUserInfo level %u failed - %s\n", 
+                      q.in.level, nt_errstr(nt_status));
+               ret = False;
+       }
+
+       getgroups.in.user_handle = &user_handle;
+       
+       nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               printf("GetGroupsForUser failed - %s\n",
+                      nt_errstr(nt_status));
+               ret = False;
+       }
+
        if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &user_handle)) {
                printf("samr_handle_Close failed - %s\n", 
                       nt_errstr(nt_status));
+               ret = False;
+       }
+       if (!ret) {
                return False;
        }
 
@@ -608,6 +627,32 @@ static BOOL samsync_handle_user(TALLOC_CTX *mem_ctx, struct samsync_state *samsy
                      || (info3->base.last_logoff == 0x7fffffffffffffffLL))) {
                        TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff);
                }
+
+               TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count);
+               if (getgroups.out.rids->count == info3->base.groups.count) {
+                       int i, j;
+                       int count = getgroups.out.rids->count;
+                       BOOL *matched = talloc_zero_array(mem_ctx, BOOL, getgroups.out.rids->count);
+                               
+                       for (i = 0; i < count; i++) {
+                               for (j = 0; j < count; j++) {
+                                       if ((getgroups.out.rids->rids[i].rid == 
+                                            info3->base.groups.rids[j].rid)
+                                           && (getgroups.out.rids->rids[i].type == 
+                                               info3->base.groups.rids[j].type)) {
+                                                       matched[i] = True;
+                                               }
+                               }
+                       }
+
+                       for (i = 0; i < getgroups.out.rids->count; i++) {
+                               if (matched[i] == False) {
+                                       ret = False;
+                                       printf("Could not find group RID %u found in getgroups in NETLOGON reply\n",
+                                              getgroups.out.rids->rids[i].rid); 
+                               }
+                       }
+               }
                return ret;
        } else {
                printf("Could not validate password for user %s\\%s: %s\n",
index f55f6684bc032b69421b81d40b8d7cdeac2183de..d54dfdf310cf04a4b82f2a6c2a9c0818de1dee7f 100644 (file)
@@ -700,7 +700,7 @@ static NTSTATUS test_getgroups(struct smbcli_transport *transport,
                l.in.rids = talloc_array(mem_ctx, uint32_t, g.out.rids->count);
 
                for (i=0; i<g.out.rids->count; i++)
-                       l.in.rids[i] = g.out.rids->rid[i].rid;
+                       l.in.rids[i] = g.out.rids->rids[i].rid;
 
                status = dcerpc_samr_LookupRids(p, mem_ctx, &l);
                if (!NT_STATUS_IS_OK(status)) {
@@ -896,7 +896,7 @@ static NTSTATUS test_getallsids(struct smbcli_transport *transport,
                for (i=0; i<g.out.rids->count; i++) {
                        sids.sids[i+2].sid = dom_sid_add_rid(mem_ctx,
                                                             domain_sid,
-                                                            g.out.rids->rid[i].rid);
+                                                            g.out.rids->rids[i].rid);
                }
                ga.in.sids = &sids;
                ga.out.rids = &rids;