@@ -196,22 +196,39 @@ func checkRestricted(l *ldap.Conn, ls *Source, userDN string) bool {
196
196
}
197
197
198
198
// List all group memberships of a user
199
- func (source * Source ) listLdapGroupMemberships (l * ldap.Conn , uid string ) []string {
199
+ func (source * Source ) listLdapGroupMemberships (l * ldap.Conn , uid string , applyGroupFilter bool ) []string {
200
200
var ldapGroups []string
201
- groupFilter := fmt .Sprintf ("(%s=%s)" , source .GroupMemberUID , ldap .EscapeFilter (uid ))
201
+ var searchFilter string
202
+
203
+ groupFilter , ok := source .sanitizedGroupFilter (source .GroupFilter )
204
+ if ! ok {
205
+ return ldapGroups
206
+ }
207
+
208
+ groupDN , ok := source .sanitizedGroupDN (source .GroupDN )
209
+ if ! ok {
210
+ return ldapGroups
211
+ }
212
+
213
+ if applyGroupFilter {
214
+ searchFilter = fmt .Sprintf ("(&(%s)(%s=%s))" , groupFilter , source .GroupMemberUID , ldap .EscapeFilter (uid ))
215
+ } else {
216
+ searchFilter = fmt .Sprintf ("(%s=%s)" , source .GroupMemberUID , ldap .EscapeFilter (uid ))
217
+ }
218
+
202
219
result , err := l .Search (ldap .NewSearchRequest (
203
- source . GroupDN ,
220
+ groupDN ,
204
221
ldap .ScopeWholeSubtree ,
205
222
ldap .NeverDerefAliases ,
206
223
0 ,
207
224
0 ,
208
225
false ,
209
- groupFilter ,
226
+ searchFilter ,
210
227
[]string {},
211
228
nil ,
212
229
))
213
230
if err != nil {
214
- log .Error ("Failed group search using filter[%s]: %v" , groupFilter , err )
231
+ log .Error ("Failed group search in LDAP with filter [%s]: %v" , searchFilter , err )
215
232
return ldapGroups
216
233
}
217
234
@@ -238,9 +255,7 @@ func (source *Source) mapLdapGroupsToTeams() map[string]map[string][]string {
238
255
}
239
256
240
257
// getMappedMemberships : returns the organizations and teams to modify the users membership
241
- func (source * Source ) getMappedMemberships (l * ldap.Conn , uid string ) (map [string ][]string , map [string ][]string ) {
242
- // get all LDAP group memberships for user
243
- usersLdapGroups := source .listLdapGroupMemberships (l , uid )
258
+ func (source * Source ) getMappedMemberships (usersLdapGroups []string , uid string ) (map [string ][]string , map [string ][]string ) {
244
259
// unmarshall LDAP group team map from configs
245
260
ldapGroupsToTeams := source .mapLdapGroupsToTeams ()
246
261
membershipsToAdd := map [string ][]string {}
@@ -260,6 +275,14 @@ func (source *Source) getMappedMemberships(l *ldap.Conn, uid string) (map[string
260
275
return membershipsToAdd , membershipsToRemove
261
276
}
262
277
278
+ func (source * Source ) getUserAttributeListedInGroup (entry * ldap.Entry ) string {
279
+ if strings .ToLower (source .UserUID ) == "dn" {
280
+ return entry .DN
281
+ }
282
+
283
+ return entry .GetAttributeValue (source .UserUID )
284
+ }
285
+
263
286
// SearchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
264
287
func (source * Source ) SearchEntry (name , passwd string , directBind bool ) * SearchResult {
265
288
// See https://tools.ietf.org/search/rfc4513#section-5.1.2
@@ -375,58 +398,30 @@ func (source *Source) SearchEntry(name, passwd string, directBind bool) *SearchR
375
398
firstname := sr .Entries [0 ].GetAttributeValue (source .AttributeName )
376
399
surname := sr .Entries [0 ].GetAttributeValue (source .AttributeSurname )
377
400
mail := sr .Entries [0 ].GetAttributeValue (source .AttributeMail )
378
- uid := sr .Entries [0 ].GetAttributeValue (source .UserUID )
379
- if source .UserUID == "dn" || source .UserUID == "DN" {
380
- uid = sr .Entries [0 ].DN
381
- }
382
401
383
- // Check group membership
384
- if source .GroupsEnabled && source .GroupFilter != "" {
385
- groupFilter , ok := source .sanitizedGroupFilter (source .GroupFilter )
386
- if ! ok {
387
- return nil
388
- }
389
- groupDN , ok := source .sanitizedGroupDN (source .GroupDN )
390
- if ! ok {
391
- return nil
392
- }
402
+ teamsToAdd := make (map [string ][]string )
403
+ teamsToRemove := make (map [string ][]string )
393
404
394
- log .Trace ("Fetching groups '%v' with filter '%s' and base '%s'" , source .GroupMemberUID , groupFilter , groupDN )
395
- groupSearch := ldap .NewSearchRequest (
396
- groupDN , ldap .ScopeWholeSubtree , ldap .NeverDerefAliases , 0 , 0 , false , groupFilter ,
397
- []string {source .GroupMemberUID },
398
- nil )
405
+ // Check group membership
406
+ if source .GroupsEnabled {
407
+ userAttributeListedInGroup := source .getUserAttributeListedInGroup (sr .Entries [0 ])
408
+ usersLdapGroups := source .listLdapGroupMemberships (l , userAttributeListedInGroup , true )
399
409
400
- srg , err := l .Search (groupSearch )
401
- if err != nil {
402
- log .Error ("LDAP group search failed: %v" , err )
403
- return nil
404
- } else if len (srg .Entries ) < 1 {
405
- log .Error ("LDAP group search failed: 0 entries" )
410
+ if source .GroupFilter != "" && len (usersLdapGroups ) == 0 {
406
411
return nil
407
412
}
408
413
409
- isMember := false
410
- Entries:
411
- for _ , group := range srg .Entries {
412
- for _ , member := range group .GetAttributeValues (source .GroupMemberUID ) {
413
- if (source .UserUID == "dn" && member == sr .Entries [0 ].DN ) || member == uid {
414
- isMember = true
415
- break Entries
416
- }
417
- }
418
- }
419
-
420
- if ! isMember {
421
- log .Error ("LDAP group membership test failed" )
422
- return nil
414
+ if source .GroupTeamMap != "" || source .GroupTeamMapRemoval {
415
+ teamsToAdd , teamsToRemove = source .getMappedMemberships (usersLdapGroups , userAttributeListedInGroup )
423
416
}
424
417
}
425
418
426
419
if isAttributeSSHPublicKeySet {
427
420
sshPublicKey = sr .Entries [0 ].GetAttributeValues (source .AttributeSSHPublicKey )
428
421
}
422
+
429
423
isAdmin := checkAdmin (l , source , userDN )
424
+
430
425
var isRestricted bool
431
426
if ! isAdmin {
432
427
isRestricted = checkRestricted (l , source , userDN )
@@ -436,12 +431,6 @@ func (source *Source) SearchEntry(name, passwd string, directBind bool) *SearchR
436
431
Avatar = sr .Entries [0 ].GetRawAttributeValue (source .AttributeAvatar )
437
432
}
438
433
439
- teamsToAdd := make (map [string ][]string )
440
- teamsToRemove := make (map [string ][]string )
441
- if source .GroupsEnabled && (source .GroupTeamMap != "" || source .GroupTeamMapRemoval ) {
442
- teamsToAdd , teamsToRemove = source .getMappedMemberships (l , uid )
443
- }
444
-
445
434
if ! directBind && source .AttributesInBind {
446
435
// binds user (checking password) after looking-up attributes in BindDN context
447
436
err = bindUser (l , userDN , passwd )
@@ -520,19 +509,29 @@ func (source *Source) SearchEntries() ([]*SearchResult, error) {
520
509
return nil , err
521
510
}
522
511
523
- result := make ([]* SearchResult , len (sr .Entries ))
512
+ result := make ([]* SearchResult , 0 , len (sr .Entries ))
524
513
525
- for i , v := range sr .Entries {
514
+ for _ , v := range sr .Entries {
526
515
teamsToAdd := make (map [string ][]string )
527
516
teamsToRemove := make (map [string ][]string )
528
- if source .GroupsEnabled && (source .GroupTeamMap != "" || source .GroupTeamMapRemoval ) {
529
- userAttributeListedInGroup := v .GetAttributeValue (source .UserUID )
530
- if source .UserUID == "dn" || source .UserUID == "DN" {
531
- userAttributeListedInGroup = v .DN
517
+
518
+ if source .GroupsEnabled {
519
+ userAttributeListedInGroup := source .getUserAttributeListedInGroup (v )
520
+
521
+ if source .GroupFilter != "" {
522
+ usersLdapGroups := source .listLdapGroupMemberships (l , userAttributeListedInGroup , true )
523
+ if len (usersLdapGroups ) == 0 {
524
+ continue
525
+ }
526
+ }
527
+
528
+ if source .GroupTeamMap != "" || source .GroupTeamMapRemoval {
529
+ usersLdapGroups := source .listLdapGroupMemberships (l , userAttributeListedInGroup , false )
530
+ teamsToAdd , teamsToRemove = source .getMappedMemberships (usersLdapGroups , userAttributeListedInGroup )
532
531
}
533
- teamsToAdd , teamsToRemove = source .getMappedMemberships (l , userAttributeListedInGroup )
534
532
}
535
- result [i ] = & SearchResult {
533
+
534
+ user := & SearchResult {
536
535
Username : v .GetAttributeValue (source .AttributeUsername ),
537
536
Name : v .GetAttributeValue (source .AttributeName ),
538
537
Surname : v .GetAttributeValue (source .AttributeSurname ),
@@ -541,16 +540,22 @@ func (source *Source) SearchEntries() ([]*SearchResult, error) {
541
540
LdapTeamAdd : teamsToAdd ,
542
541
LdapTeamRemove : teamsToRemove ,
543
542
}
544
- if ! result [i ].IsAdmin {
545
- result [i ].IsRestricted = checkRestricted (l , source , v .DN )
543
+
544
+ if ! user .IsAdmin {
545
+ user .IsRestricted = checkRestricted (l , source , v .DN )
546
546
}
547
+
547
548
if isAttributeSSHPublicKeySet {
548
- result [ i ] .SSHPublicKey = v .GetAttributeValues (source .AttributeSSHPublicKey )
549
+ user .SSHPublicKey = v .GetAttributeValues (source .AttributeSSHPublicKey )
549
550
}
551
+
550
552
if isAtributeAvatarSet {
551
- result [ i ] .Avatar = v .GetRawAttributeValue (source .AttributeAvatar )
553
+ user .Avatar = v .GetRawAttributeValue (source .AttributeAvatar )
552
554
}
553
- result [i ].LowerName = strings .ToLower (result [i ].Username )
555
+
556
+ user .LowerName = strings .ToLower (user .Username )
557
+
558
+ result = append (result , user )
554
559
}
555
560
556
561
return result , nil
0 commit comments