[PATCH] Adds support for Resource SID Compression a new Windows Server 2012 KDC feature

Markus Baier Markus_Baier at baier-network.de
Mon Apr 1 09:25:56 MDT 2013


Hello,

after studying the MS-KILE - v20130118 technical documentation
especially page 46
I have written a improved version of the patch.

Now it takes care, if the ResourceGroupDomainSid and the DomainSid
are different.
Than it emulates the compatibility mode, which
a Windows Server 2012 KDC use if the resource sid compression
feature is disabled on the KDC.

If the two SIDs are diffrent, I copy the RIDs from the
ResourceGroupIds field as SIDs in the ExtraSids field.
But if the ResourceGroupDomainSid and the DomainSid are identical,
then I only copy the RIDs from the ResourceGroupIds field
into the GroupIDs field to reduce the needed memory size.


Best Regards
Markus Baier


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

diff -u -r -N a/source3/winbindd/winbindd_pam.c
b/source3/winbindd/winbindd_pam.c
--- a/source3/winbindd/winbindd_pam.c	2013-03-31 00:28:57.202896272 +0100
+++ b/source3/winbindd/winbindd_pam.c	2013-04-01 17:01:39.547430803 +0200
@@ -626,6 +626,56 @@

 	*info3 = &logon_info->info3;

+	/* Check if PAC_LOGON_INFO contains Resource Groups.
+	   Therefore we check if the H Flag in the user_flags mask is set.
+	   A Windows Server 2012 KDC sends doamin local Groups
+	   as Resource Groups when the new "resource sid compression" feature
+	   is enabled. The feature is enabled by default. */
+	if ((*info3)->base.user_flags & NETLOGON_RESOURCE_GROUPS) { //Check if
the H Flag in the user_flags mask is set
+		if (dom_sid_equal((*info3)->base.domain_sid,
logon_info->res_group_dom_sid)) { //Check if the ResourceGroupDomain sid
is the same as the LogonDomainID sid
+			uint32_t i;
+			uint32_t groups_count_total;
+			struct samr_RidWithAttribute *new_rids;
+
+			groups_count_total = (*info3)->base.groups.count +
logon_info->res_groups.count; //Calculate the new total numbers of rids
in the array
+			new_rids = talloc_realloc(mem_ctx,(*info3)->base.groups.rids,struct
samr_RidWithAttribute, groups_count_total); //Expand the array
+			if (new_rids == NULL) {
+				DEBUG(10, ("talloc_realloc: Failed to expand array for new rids\n"));
+				DEBUGADD(10, ("Copy the rid from ResourceGroupIds to GroupIds not
possible\n"));
+				talloc_free(new_rids);
+			} else {
+				(*info3)->base.groups.rids = new_rids;
+				/* Start to copy the ResourceGroupIds into the GroupIds array */
+				for (i=0; i < logon_info->res_groups.count; i++) {
+					new_rids[(*info3)->base.groups.count + i].rid =
logon_info->res_groups.rids[i].rid; //Copy the rid from ResourceGroupIds
to GroupIds
+					new_rids[(*info3)->base.groups.count + i].attributes =
logon_info->res_groups.rids[i].attributes; //Copy the attributes from
ResourceGroupIds to GroupIds
+				}
+				(*info3)->base.groups.count = groups_count_total; //Update the
GroupCount field with the new number of groups
+			}
+		} else {
+                        uint32_t i;
+                        uint32_t groups_count_total;
+                        struct netr_SidAttr *user_sids;
+
+                        groups_count_total = (*info3)->sidcount +
logon_info->res_groups.count; //Calculate the new total numbers of SID
in the user_sids array
+			user_sids = talloc_realloc(mem_ctx, (*info3)->sids, struct
netr_SidAttr, groups_count_total); //Expand the array
+                        if (user_sids == NULL) {
+                                DEBUG(10, ("talloc_realloc: Failed to
expand array for new sids\n"));
+                                DEBUGADD(10, ("Combine the sid from
ResourceGroupIds not possible\n"));
+                                talloc_free(user_sids);
+                        } else {
+				(*info3)->sids = user_sids;
+				/* Start to copy the ResourceGroupIds into the SID array */
+				for (i=0; i < logon_info->res_groups.count; i++) {
+					user_sids[(*info3)->sidcount + i].sid = talloc(mem_ctx, struct
dom_sid);
+					sid_compose(user_sids[(*info3)->sidcount + i].sid,
(*info3)->base.domain_sid, logon_info->res_groups.rids[i].rid);
+					user_sids[(*info3)->sidcount + i].attributes =
logon_info->res_groups.rids[i].attributes;
+				}
+				(*info3)->sidcount = groups_count_total; //Update the sidcount
field with the new number of SIDs
+			}
+		}
+	}
+
 	DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of
%s\n",
 		principal_s));




More information about the samba-technical mailing list