Rocket.chat: Login NoSuchObjectError when LDAP_Sync_User_Data_Groups set to true

Created on 20 Oct 2019  Β·  15Comments  Β·  Source: RocketChat/Rocket.Chat

Description:

I've enabled LDAP_Sync_User_Data_Groups and after that failed every login try from every type of device _(old sessions persists and groups from LDAP are synchronized)_ or app with NoSuchObjectError. It's critical issue in #14278 for us. IDK what's wrong. When I disable LDAP_Sync_User_Data_Groups everything is OK (even with synchronized groups from LDAP).

Search filter:

(&(cn=#{groupName})(uniqueMember=uid=#{username},ou=users,dc=example,dc=org))

Expected behavior:

Working LDAP_Sync_User_Data_Groups option

Actual behavior:

Not working LDAP_Sync_User_Data_Groups = true

Server Setup Information:

  • Version of Rocket.Chat Server: 2.1.1 (not working even with 2.1.0)
  • Operating System: Debian 9/10
  • Deployment Method: tar
  • Number of Running Instances: 3
  • DB Replicaset Oplog: Yes
  • NodeJS Version: v8.15.1
  • MongoDB Version: 3.6.13

Relevant logs:

server.js:212 LDAP βž” Search.error { NoSuchObjectError: No Such Object
    at messageCallback (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1419:45)
    at Parser.onMessage (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1089:14)
    at emitOne (events.js:116:13)
    at Parser.emit (events.js:211:7)
    at Parser.write (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/messages/parser.js:111:8)
    at Socket.onData (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1076:22)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:601:20) lde_message: 'No Such Object', lde_dn: null }
Exception while invoking method 'login' { NoSuchObjectError: No Such Object
    at messageCallback (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1419:45)
    at Parser.onMessage (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1089:14)
    at emitOne (events.js:116:13)
    at Parser.emit (events.js:211:7)
    at Parser.write (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/messages/parser.js:111:8)
    at Socket.onData (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1076:22)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:601:20) lde_message: 'No Such Object', lde_dn: null }
Auth - LDAP

Most helpful comment

I am getting exactly the same error, and I believe that I understand what caused it for me, and I think that it is your case as well.

Based on logs from my LDAP server, it goes on like this:

  1. First of all, the server binds as the "admin", i.e. as the user that is configured in the site's LDAP settings.
  2. Admin tries to find the user who would like to log in.
  3. If successful, the server tries to bind as the user who tries to log in.
  4. If successful, the server acknowledges that the user has authenticated (expressed by LDAPHandler βž” info Logging user in the log)
  5. The group sync is performed, but not by admin, but by the user who is logging in. That user may not have access rights to read group membership, so it results in an error.

I see two possible bugs here:

  • Group membership should be assessed by the admin.
  • When a user is authenticated, the login probably shouldn't fail if there is a subsequent issue with group sync.

All 15 comments

I think this is related to OpenLdap and not RC.

From: https://www.openldap.org/faq/data/cache/157.html

> The "ldap_add: No such object" error is commonly returned if parent of the entry being added does not exist. Add the parent entry first...For example, if you are adding "cn=bob,dc=domain,dc=com" and you get: ldap_add: No such objectThe entry "dc=domain,dc=com" likely doesn't exist. You can use ldapsearch to see if does exist: ldapsearch -b 'dc=domain,dc=com' -s base '(objectclass=*)'If it doesn't, add it. See the Quick Start Guide (http://www.openldap.org/doc/admin/quickstart.html) for assistance.Note: if the entry being added is the same as database suffix, it's parent isn't required. Ie: if your suffix is "dc=domain,dc=com", "dc=com" doesn't need to exist to add "dc=domain,dc=com".

This error will also occur if you try to add any entry that the server is not configured to hold.For example, if your database suffix is "dc=domain,dc=com" and you attempt to add "dc=domain2,dc=com", "dc=com", "dc=domain,dc=org", "o=domain,c=us", or an other DN in the "dc=domain,dc=com" subtree, the server will return a "No such object" (or referral) error.slapd(8) will generally return "no global superior knowledge" as additional information indicating its return noSuchObject instead of a referral as the server is not configured with knowledge of a global superior server.

Also: https://www.openldap.org/faq/data/cache/343.html

>The 'no such object' error is generally returned when the target DN of the operation cannot be located. This section details reasons common to all operations. You should also look for answers specific to the operation (as indicated in the error message).

The most common reason for this error is non-existance of the named object. First, check for typos.Also note that, by default, a new directory server holds no objects (except for a few system entries). So, if you are setting up a new directory server and get this message, it may simply be that you have yet to add the object you are trying to locate.

Are you using OpenLDAP or AD?

Have you looked at https://github.com/RocketChat/Rocket.Chat/pull/14278#issuecomment-533547519 or https://github.com/RocketChat/Rocket.Chat/pull/14278#issuecomment-538729262

  • I'm using OpenLDAP on Debian linux.
  • It's not empty but now we are setting up mapping you wrote ( #14278 ).

LDAP Search not working for me:

ldapsearch -Y EXTERNAL -H ldapi:/// -b "dc=example,dc=com" -s base '(objectclass=*)'
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

Our "base" object looks like this:

dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: OrganizationName
dc: example
structuralObjectClass: organization

... so I've found an error but I don't know how to fix it.

Thank you @wreiske for help.

EDIT:
That's weird. I tried RC LDAP account with same search and there's no NoSuchObbjectError:

ldapsearch -D "uid=rocketchat-admin,ou=system,dc=example,dc=com" -W -b "dc=example,dc=com" -s base '(objectclass=*)'
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
#

# example.com
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: OrganizationName
dc: example

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

@wreiske Any news? I'm not sure what's wrong and I'm stuck on it :confused:

:-1: for a needed support @wreiske

for a needed support @wreiske

Sorry, I'm not a Rocket.Chat developer, nor is there any expectation of community members to provide timely support. You can try contacting [email protected] or poke around on open.rocket.chat.

@wreiske Thank you. I will contact them.

@wreiske you wrote this feature. Is there a possibility to relationship with not existing memberOf overlay in LDAP?

I've tried apply memberOf overlay, but it didn't help. It's crashing here https://github.com/wreiske/Rocket.Chat/blob/23b043c4947c050ef78bff0323fa0fcfe449c6de/app/ldap/server/sync.js#L34
There's a debug log

server.js:212 LDAP βž” Connection.info LDAP connected 
server.js:212 LDAP βž” Bind.info Binding UserDN <Bind user DN>
server.js:212 LDAP βž” Search.info Searching user dusatvoj 
server.js:212 LDAP βž” Search.debug searchOptions { filter: '(&(objectclass=*)(uid=dusatvoj))',   scope: 'sub',   sizeLimit: 1000,   paged: { pageSize: 250, pagePause: false } } 
server.js:212 LDAP βž” Search.debug BaseDN ou=users,dc=example,dc=com 
server.js:212 LDAP βž” Search.info Search result count 1 
server.js:212 LDAP βž” Auth.info Authenticating uid=dusatvoj,ou=users,dc=example,dc=com 
server.js:212 LDAP βž” Search.info Search result count 1 
server.js:212 LDAP βž” Auth.info Authenticated uid=dusatvoj,ou=users,dc=example,dc=com
server.js:212 LDAPHandler βž” info Querying user 
server.js:212 LDAPHandler βž” debug userQuery { 'services.ldap.id': '6475736174766f6a' } 
server.js:212 LDAPHandler βž” info Logging user 
server.js:212 LDAPSync βž” info Syncing user data 
server.js:212 LDAPSync βž” debug user { email: undefined, _id: '6o4qKzbDPfqrMfZjN' } 
server.js:212 LDAPSync βž” debug ldapUser undefined 
server.js:212 TemplateVarHandler βž” debug template found. replacing values 
server.js:212 TemplateVarHandler βž” debug replacing template var: #{cn} with value: VojtΔ›ch 
server.js:212 TemplateVarHandler βž” debug replacing template var: #{sn} with value: DuΕ‘Γ‘tko 
server.js:212 LDAPSync βž” debug User role exists for mapping accountant_external -> AccountantExternal 
server.js:212 LDAP βž” Search.error { NoSuchObjectError: No Such Object     at messageCallback (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1419:45)     at Parser.onMessage (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1089:14)     at emitOne (events.js:116:13)     at Parser.emit (events.js:211:7)     at Parser.write (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/messages/parser.js:111:8)     at Socket.onData (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1076:22)     at emitOne (events.js:116:13)     at Socket.emit (events.js:211:7)     at addChunk (_stream_readable.js:263:12)     at readableAddChunk (_stream_readable.js:250:11)     at Socket.Readable.push (_stream_readable.js:208:10)     at TCP.onread (net.js:601:20) lde_message: 'No Such Object', lde_dn: null } 
Exception while invoking method 'login' { NoSuchObjectError: No Such Object     at messageCallback (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1419:45)     at Parser.onMessage (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1089:14)     at emitOne (events.js:116:13)     at Parser.emit (events.js:211:7)     at Parser.write (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/messages/parser.js:111:8)     at Socket.onData (/opt/Rocket.Chat/programs/server/npm/node_modules/ldapjs/lib/client/client.js:1076:22)     at emitOne (events.js:116:13)     at Socket.emit (events.js:211:7)     at addChunk (_stream_readable.js:263:12)     at readableAddChunk (_stream_readable.js:250:11)     at Socket.Readable.push (_stream_readable.js:208:10)     at TCP.onread (net.js:601:20) lde_message: 'No Such Object', lde_dn: null }

... I want to repair it but I'm not an JS developer :/ ... Any help wanted

Hi @wreiske ,
this is not necessarily a problem with OpenLDAP.
I have hit this issue with ActiveDirectory as well.

All users that were synced prior to enabling LDAP role or channel mappings can login without problems.
New users can not login. If I disable the mapping, the new users can login.
Merge existing users is active, the group filter looks like this:
(&(sAMAccountName=#{username})(memberOf=#{groupName}))

The LDAP-tree is a bit more structured and the solutions from your PR did not work for me.
My filter worked flawless until I had to add new users.

Any Ideas?

I think there are try-catches missing or something like that because NoSuchObject Error could mean isUserInLDAPGroup = false. Isn't it true?

I am getting exactly the same error, and I believe that I understand what caused it for me, and I think that it is your case as well.

Based on logs from my LDAP server, it goes on like this:

  1. First of all, the server binds as the "admin", i.e. as the user that is configured in the site's LDAP settings.
  2. Admin tries to find the user who would like to log in.
  3. If successful, the server tries to bind as the user who tries to log in.
  4. If successful, the server acknowledges that the user has authenticated (expressed by LDAPHandler βž” info Logging user in the log)
  5. The group sync is performed, but not by admin, but by the user who is logging in. That user may not have access rights to read group membership, so it results in an error.

I see two possible bugs here:

  • Group membership should be assessed by the admin.
  • When a user is authenticated, the login probably shouldn't fail if there is a subsequent issue with group sync.

I confirm this diagnostic as I had the same issue, and when I changed OpenLDAP ACL in order to allow user to read groups and members I successfully got a sync :)

+1 on matejak suggestions

@matejak / @battosai30 Can you send me your ACLs? I have periodic sync without issue but I still cannot login :/

@matejak / @battosai30 Can you send me your ACLs? I have periodic sync without issue but I still cannot login :/

Of course !

database config
rootdn "gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
access to * 
     by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage 
     by dn.base="YOUR_BASE_DN" manage 
     by * break

database mdb
access to * 
     by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage 
     by dn.base="YOUR_BASE_DN" manage 
     by dn="cn=admin,YOUR_BASE_DN" manage
     by self read
     by anonymous auth
     by * none

I'm not bad about OpenLDAP but clearly not an expert of its ACL so maybe it's not a state of the art config, but as I tested it it seems to do the job (safe and not allowing too much ... ;) )

I'm sorry I figured out that I gave you a completely wrong config ....

Here the right one to use with ldapmodify :

dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to attrs=userPassword by anonymous auth by dn="cn=admin,YOUR_BASE_DN" write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to dn.base="ou=groups,YOUR_BASE_DN" by users read
olcAccess: {3}to dn.children="ou=users,YOUR_BASE_DN" by dn="cn=admin,YOUR_BASE_DN write by self read
olcAccess: {4}to dn.base="cn=ppolicy,YOUR_BASE_DN" by dn="cn=admin,YOUR_BASE_DN" write
olcAccess: {5}to * by self write by dn="cn=admin,YOUR_BASE_DN" write by * read
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Buzzele picture Buzzele  Β·  3Comments

marceloschmidt picture marceloschmidt  Β·  3Comments

mattlin picture mattlin  Β·  3Comments

djeber picture djeber  Β·  3Comments

danpospisil picture danpospisil  Β·  3Comments