Skip to content

Commit bba75b7

Browse files
committed
LdapAdapter: Keep track of already processed group to account for possible circular references
1 parent c6c4516 commit bba75b7

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/Security/Authentication/Negotiate/src/Internal/LdapAdapter.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static async Task RetrieveClaimsAsync(LdapSettings settings, ClaimsIdenti
6868

6969
if (!settings.IgnoreNestedGroups)
7070
{
71-
GetNestedGroups(settings.LdapConnection, identity, distinguishedName, groupCN, logger, retrievedClaims);
71+
GetNestedGroups(settings.LdapConnection, identity, distinguishedName, groupCN, logger, retrievedClaims, new HashSet<string>());
7272
}
7373
else
7474
{
@@ -96,8 +96,10 @@ public static async Task RetrieveClaimsAsync(LdapSettings settings, ClaimsIdenti
9696
}
9797
}
9898

99-
private static void GetNestedGroups(LdapConnection connection, ClaimsIdentity principal, string distinguishedName, string groupCN, ILogger logger, IList<string> retrievedClaims)
99+
private static void GetNestedGroups(LdapConnection connection, ClaimsIdentity principal, string distinguishedName, string groupCN, ILogger logger, IList<string> retrievedClaims, HashSet<string> processedGroups)
100100
{
101+
retrievedClaims.Add(groupCN);
102+
101103
var filter = $"(&(objectClass=group)(sAMAccountName={groupCN}))"; // This is using ldap search query language, it is looking on the server for someUser
102104
var searchRequest = new SearchRequest(distinguishedName, filter, SearchScope.Subtree, null);
103105
var searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
@@ -109,8 +111,10 @@ private static void GetNestedGroups(LdapConnection connection, ClaimsIdentity pr
109111
logger.LogWarning($"More than one response received for query: {filter} with distinguished name: {distinguishedName}");
110112
}
111113

112-
var group = searchResponse.Entries[0]; //Get the object that was found on ldap
113-
retrievedClaims.Add(groupCN);
114+
var group = searchResponse.Entries[0]; // Get the object that was found on ldap
115+
var groupDN = group.DistinguishedName;
116+
117+
processedGroups.Add(groupDN);
114118

115119
var memberof = group.Attributes["memberof"]; // You can access ldap Attributes with Attributes property
116120
if (memberof != null)
@@ -119,7 +123,14 @@ private static void GetNestedGroups(LdapConnection connection, ClaimsIdentity pr
119123
{
120124
var nestedGroupDN = $"{Encoding.UTF8.GetString((byte[])member)}";
121125
var nestedGroupCN = nestedGroupDN.Split(',')[0].Substring("CN=".Length);
122-
GetNestedGroups(connection, principal, distinguishedName, nestedGroupCN, logger, retrievedClaims);
126+
127+
if (processedGroups.Contains(nestedGroupDN))
128+
{
129+
// We need to keep track of already processed groups because circular references are possible with AD groups
130+
return;
131+
}
132+
133+
GetNestedGroups(connection, principal, distinguishedName, nestedGroupCN, logger, retrievedClaims, processedGroups);
123134
}
124135
}
125136
}

0 commit comments

Comments
 (0)