diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-05-01 08:05:17 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:16:24 -0500 |
commit | bb6e2059ee0b07d15ef3f924a137321d5fd6aa0f (patch) | |
tree | 44a80422a0b93012d5908b4839a097c2de22a628 | |
parent | 14b73135430d7636e418746529ba2d38f8e9de6f (diff) | |
download | samba-bb6e2059ee0b07d15ef3f924a137321d5fd6aa0f.tar.gz samba-bb6e2059ee0b07d15ef3f924a137321d5fd6aa0f.tar.bz2 samba-bb6e2059ee0b07d15ef3f924a137321d5fd6aa0f.zip |
r6544: Use common structures between SAMR, NETLGON and the Krb5 PAC.
Fill out the group list for the SamLogon reply, so clients get the
supplementary groups.
Andrew Bartlett
(This used to be commit d9c31e60a72c345e3a23a7eb742906bcfc18721c)
-rw-r--r-- | source4/auth/auth_util.c | 10 | ||||
-rw-r--r-- | source4/librpc/idl/krb5pac.idl | 3 | ||||
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 3 | ||||
-rw-r--r-- | source4/librpc/idl/samr.idl | 18 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 24 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 26 | ||||
-rw-r--r-- | source4/torture/rpc/samsync.c | 45 | ||||
-rw-r--r-- | source4/torture/rpc/xplogin.c | 4 |
8 files changed, 98 insertions, 35 deletions
diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c index 791d12fae6..ebd0b74227 100644 --- a/source4/auth/auth_util.c +++ b/source4/auth/auth_util.c @@ -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]); } diff --git a/source4/librpc/idl/krb5pac.idl b/source4/librpc/idl/krb5pac.idl index c5b64993f0..a8a0ca0697 100644 --- a/source4/librpc/idl/krb5pac.idl +++ b/source4/librpc/idl/krb5pac.idl @@ -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; diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index c97a640d18..0e601b372a 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -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; diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index 0a94756868..3cf2aeaf7e 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -432,12 +432,12 @@ 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 ); @@ -813,19 +813,19 @@ /************************/ /* 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 ); /************************/ diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 141aeef1bf..6c32ac8b2c 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -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(); diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 968328fe9d..9934a502de 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -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; } } diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index d77c5a0d5e..412b27c8ec 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -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", diff --git a/source4/torture/rpc/xplogin.c b/source4/torture/rpc/xplogin.c index f55f6684bc..d54dfdf310 100644 --- a/source4/torture/rpc/xplogin.c +++ b/source4/torture/rpc/xplogin.c @@ -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; |