Get "memberOf" in LDAP3 search for a specific user - ldap

I have an example result from LDAP like this:
USERID123, Users, UserProvisioning, Production, ztb.icb.company.com
dn: CN=USERID123, ,OU=Users,OU=UserProvisioning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: USERID123
sn: Mueller
c: DE
l: Frankfurt
title: M.Sc.
telephoneNumber: +49 69 136 27289
givenName: Lukas
distinguishedName: CN=USERID123,OU=Users,OU=UserProvisioning,OU=Production,DC=zt
b,DC=icb,DC=company,DC=com
instanceType: 4
whenCreated: 20191023230941.0Z
whenChanged: 20200907052944.0Z
displayName: Mueller, Lukas
uSNCreated: 21302914
memberOf: CN=GG_APP-013979-DQI-KYC-PROD-CONSUMER-GCRR,OU=Groups,OU=UserProvisi
oning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com
memberOf: CN=GG_APP-013479-DQI-KYC-DEV-CONSUMER-GCRR,OU=Groups,OU=UserProvisi
oning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com
memberOf: CN=GG_APP-011479-DQI-KYC-TUD-CONSUMER-GCRR,OU=Groups,OU=UserProvisi
oning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com
I am trying to get all "memberOf" for the User "USERID123" in Python LDAP3.
I tried the following:
if conn.bind():
conn.search(
search_base='OU=Groups,OU=UserProvisioning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com',
search_filter='(objectClass=group)',
search_scope='SUBTREE',
attributes=['memberOf']
)
for entry in conn.entries:
print(entry.memberOf.values)
But I am not able to recreate the query in conn.search to find the "memberOf" for a specific user. How can I do this query to get my desired results in a ldap3 query?

You can see all the values of memberOf in the "example result from LDAP".
If you are really asking for all the groups the user is a Member of then your search would be more like:
conn.search( search_base='OU=Groups,OU=UserProvisioning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com',
search_filter='&((objectClass=group)(member=CN=USERID123,OU=Users,OU=UserProvisioning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com))',
search_scope='SUBTREE',
attributes=['member']
Or if using Microsoft Active Directory use this filter:
(member:1.2.840.113556.1.4.1941:=(CN=USERID123,OU=Users,OU=UserProvisioning,OU=Production,DC=ztb,DC=icb,DC=company,DC=com))

Related

Remove Duplicate Attributes for a (Core) SINGLE-VALUE NO-USER-MODIFICATION Attribute in LDAP

I recently set up a FreeIPA server (4.9.8) on Centos and a replica. Somehow—I don't even know how this is possible—all of my groups have ended up with two identical sets of core attributes:
dn: cn=<group name>,cn=groups,cn=accounts,dc=<domain>,dc=com
modifiersName: cn=MemberOf Plugin,cn=plugins,cn=config
modifiersName: cn=MemberOf Plugin,cn=plugins,cn=config
I have tried to ldapmodify the attributes deleting or replacing the values; I've tried deleting the groups completely but whatever I try it throws an error complaining that a single-value attribute has multiple values. It might be compounded by the fact that almost all the groups also belong to another group so it's impossible to delete one without trying to make a modification to the membership of that main group and vice versa.
I found the attribute in the core schema for the directory and it is SINGLE-ATTRIBUTE NO-USER-MODIFICATION.
Any thoughts on how to resolve this?
I see, modifiersName is a SINGLE-VALUE with NO-USERMODIFICATION. No chance to modify without delete object.
At least to query similar cases with multi Attributes with different (or same) values can can use the following awk script, if you like.
Firstly: you should export your objects in ad ldif file (REPORT.ldif)
grep '^dn:\|^cn:' REPORT.ldif | awk
'BEGINN {L1="",L2="";TYP="";DN_PREF="dn:";DN=""}
{
if (TYP==$1) {
printf("\n%s %s\n%s %s\n%s %s\n--------",
DN_PREF,DN,
$1,$2,
L1,L2);
}
if (TYP==$1) {
DN=$2;
}
L1=$1;
L2=$2;
}'
Ouput:
dn ...
cn value1
cn value2
Cn ...
--------
dn ...
cn ...
cn ...
--------
...

access to gitlab based on ldap-groups

I am trying to setup gitlab on linux machine. And i am stuck on LDAP configuration in /etc/gitlab/gitlab.rb file.
I want to allow access for members of both black and green teams, deny access to everyone else.
my conf looks like this:
gitlab_rails['ldap_enabled'] = true
###! **remember to close this block with 'EOS' below**
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
main:
label: 'LDAP'
host: 'hidden'
port: 'hidden'
uid: 'sAMAccountName'
method: 'plain'
bind_dn: 'hidden'
password: 'hidden'
active_directory: true
# allow_username_or_email_login: true
# block_auto_created_users: false
base: "cn=Black Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com"
base: "cn=Green Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com"
# user_filter: ''
# attributes:
# username:['uid', 'userid', 'sAMAccountName']
# email: ['mail', 'email', 'userPrincipalName']
# name: 'cn'
# first_name: 'givenName'
# last_name: 'sn'
# ## EE only
# admin_group: ''
# sync_ssh_keys: false
EOS
but it doesnt work. Most probably because such configuration grant access for group, but not members of group. Is there any way to allow sub-group/sub-items/sub-elements grant access as well?
I know we can do something like this:
base: ''
user_filter: '(|(memberOf=cn=Black Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com)(memberOf=cn=Green Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com))'
which will be: "allow everyone, and trim results to only members of black & green teams"
and it works correctly so far, but after adding few more teams filter will become veeeeeery long, and it will be not easy to update in case of more complicated filters.
Therefore i am interested in solution which allows every member of listed groups (in "base" fields).
Is it possible to define multiple groups via "base" field?
Is it possible to allow access for members of groups listed in "base" fields ?
I do not think you can do that to base field and should only have 1 base, but would multi-line help make the very long filter more editable?
Newline are treated as spaces, so might be helpful if you see group name per line.
user_filter: '(|(memberOf=cn=Black Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com)
(memberOf=cn=Green Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com))
(memberOf=cn=Another Team,OU=hidden2,OU=hidden3,OU=hidden4,OU=hidden5,OU=hidden6,DC=ad,DC=companyname,DC=com))'

Search Inside LDAP Server

I was wondering if someone know, when i search an entity over the Ldap server, would I get also it's sub folders and the data inside. for example I have the following:
*dn:EPC-SubscriberGroupId=AllInOne, EPC-SubscriberGroupsName=EPC-SubscriberGroups,
applicationName=EPC-EpcNode, nodeName=jambala changetype:add
objectClass: EPC-SubscriberGroup EPC-SubscriberGroupDescription:Voice
and Data flat rate EPC-SubscribedServices:PeerToPeer
EPC-SubscribedServices:Skype EPC-SubscribedServices:Chat
dn:EPC-Name=EPC-SubscriberQualification,
EPC-SubscriberGroupId=AllInOne,
EPC-SubscriberGroupsName=EPC-SubscriberGroups,
applicationName=EPC-EpcNode,nodeName=jambala changetype:add
objectClass: EPC-SubscriberQualification
EPC-SubscriberQualificationData:QosProfileId:10000*
So if I will set a query that will try to fetch the entity Epc-SubscriberGroup of SubscriberGroupAllInOne, I will also retrieve the sub folder ( object ) EPC-SubscriberQualification
Hope it's clear enough.
You will get the entry or entries that match the search filter depending on what's in the search filter and what scope you specified for the search. You will get the attributes that you ask for. You will not get subentries.

Is there a way to do an LDAP query to get records where a particular attribute is the same?

I am trying to find an example LDAP query where I can find records where a particular attribute matches one or more other records. For instance, a user object where the userid is different, but the employee ids are the same. Is this even possible?
From a single LDAP query no. Unless you know the emplyeeID value you are looking for.
We created an LDAP tool, Duplicate Attribute Value Locater Tool, that will do this.
-jim
It's not possible to do sub queries within the filter itself. In this case, as long as I understand correctly, you'd like to find users that match :
objectClass of User
match on the value of employeeID
Out of the above subset, find all with a DISTINCT 'userid'
If you knew what userid to look for, or NOT look for, you could expand the inital AND clause to include finding, or not finding, that attribute :
userid not equal to 12345 :
(&(objectClass=person)(employeeID=JSmith)(!(userid=12345)))
userid equal to 12345 :
(&(objectClass=person)(employeeID=JSmith)(userid=12345)
I found this example for 'myattribute'. Needs some polish, and depending on the size of your directory, it could take a while to run. If that's the case, I'd break it up by attribute sections {attr=aa*, attr=ab*, attr=ac*, etc.}.
ldapsearch -x -h ldapserver.domain.com -b ou=myldap,o=mydomain.com "(&(myattribute=aa*))" myattribute | grep '^myattribute:' | sort | uniq -c| sort -n|awk '$1 > 1 { print }'

Using DN in Search Filter

In my LDAP Client program sometimes I have to include the DN value within the search filter. But this DN is changing frequently and every I have to change this filter in my code.
When I googled it for that I got something like this
Suppose you want to pull all users of ObjectType = Person from the R&D and HR ous, but not any users from Marketing and PM. The filter would be:
(&(objectClass=person)(|(ou:dn:=ResearchAndDevelopment)(ou:dn:=HumanResources)))
Can anybody explain this more in detail?
You should check RFC 2254 (The String Representation of LDAP Search Filters).
LDAP filters use polish notation for the boolean operators. So the operator is written before its operands:
(&(condition1)(condition2)(condition3)...)
The example above means that you want all LDAP entries which satisfy condition1 AND condition2 AND condition3 and so on.
Then there are condition themselves. They are very simple and can consist only of few types:
present condition - (attrName=*)
simple condition - (attrName>=value) / (attrName<=value) / (attrNamevalue=value) / (attrName~=value)
substring condition - (attrName=*value*) / (attrName=*value) / (attrName=value*)
extensible condition - (attrName:dn:=value) / (attrName:matchingRule:=value)
The extensible condition with the :dn: keyword means, that you want attributes from the entry DN to be considered as well. So for your case entry cn=John Doe,ou=HumanResources,ou=Users,dc=example,dc=com would match the filter (ou:dn:=HumanResource).
Translating your example filter to an English sentence would be:
Find me all LDAP entries which have objectClass equal to person and have either ResearchAndDevelopment or HumanResources in their ou attribute or somewhere on their DN.
You can use dn into base and set search scope as base.
That is, set dn value into base, and set search scope as base(search scope is one of base, sub and one).
If you really need to search by the whole DN, you can search with:
(distinguishedName=CN=MyCommonName,OU=SomeEnv,...,DC=SomeDir)