Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQUEST] Return schema in RootDSE for better compatibility with Apache Directory Studio Browser #893

Open
GCTWorks opened this issue Apr 8, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@GCTWorks
Copy link

GCTWorks commented Apr 8, 2024

Motivation
I want to be able to use Apache Directory Studio Browser to browse LLDAP server

Describe the solution you'd like
When creating the connection to LLDAP in Apache Directory Studio, you must enter the baseDN manually because LLDAP is "Missing schema location in RootDSE" and the baseDN(s) cannot be fetched.

I can make this work half way by creating two connections and manually identifying one baseDN as ou=people,dc=example,dc=com or ou=groups,dc=example,dc=com. However, they must be separate connections. It would be nice if there was an OU one level up or some other way to identify the baseDN. Even better would be for that baseDN to be fetchable by the Apache Directory Studio.

@GCTWorks GCTWorks added the enhancement New feature or request label Apr 8, 2024
@nitnelave
Copy link
Member

I don't know that much about rootDSE and how to respond with the schema. In the spirit of my limited time and to avoid reading the RFC, could you provide an example of a rootDSE response you'd like to see?

@GCTWorks
Copy link
Author

GCTWorks commented Apr 9, 2024

I am not too sure myself. I actually only extremely recently made myself familiar with LDAP because I wanted to use your tool in my homelab, and I had needs for work.

Some searching came up with what I think might be a good explanation of rootDSE here: link

What I think this means is that there is no schema returned when it (Apache Directory Studio) tries to fetch the root of the directory server.

What this results in is the following error message.
image

Also, if there is no "namespaceless" root, then Apache Directory Studio is restricted to a connection to LLDAP that has a baseDN of ou=people,dc=example,dc=com or ou=groups,dc=example,dc=com, but not both in the same connection. I think it is looking for a level above.

I hope this clarifies. I could also be way off base as I am very very new to this stuff and may not have any idea what I am talking about, but I am trying to learn.

By the way... I really like your LLDAP tool. It is amazing for small homelabs to dip feet into LDAP. My friends and I that are on the homelab journey together are enjoying its use. I appreciate the hard work.

@nitnelave
Copy link
Member

@Firstyear hey, do you know what's needed in the rootDSE for this? I made the minimum effort to be compliant, but this is stretching my knowledge.

I guess I need to declare and implement the DC level above the OUs, and declare a schema?

@Firstyear
Copy link

I'll save you the trouble of reading the (whole) RFC:

https://www.rfc-editor.org/rfc/rfc4512#section-4.4

"""
To discover the DN of the subschema (sub)entry holding the subschema
controlling a particular entry, a client reads that entry's
'subschemaSubentry' operational attribute. To read schema attributes
from the subschema (sub)entry, clients MUST issue a Search operation
[RFC4511] where baseObject is the DN of the subschema (sub)entry,
scope is baseObject, filter is "(objectClass=subschema)" [RFC4515],
and the attributes field lists the names of the desired schema
attributes (as they are operational). Note: the
"(objectClass=subschema)" filter allows LDAP servers that gateway to
X.500 to detect that subentry information is being requested.
"""

So this really glosses over whats going on.

In the rootdse you have:

# ldapsearch -H ldap://172.17.0.2:3389 -x -b '' -s base \* +
...
dn:
objectClass: top
subschemaSubentry: cn=schema
...

subschemaSubentry is operational, so only return it on + or when requested.

The client then searches with that as the base dn, you just respond with a single entry with a ton of attributes representing the schema.

These entries are defined in https://www.rfc-editor.org/rfc/rfc4512#section-4.2 again with the usual level of "specific but not clear" as we would expect from an LDAP rfc.

And easy way to "cheat" and check this would be to look at what something else does. So here's an ldif I prepared for you.

ldapsearch -H ldap://172.17.0.2:3389 -x -b 'cn=schema' -s base '(objectClass=subschema)' \+

# schema
dn: cn=schema
objectClasses: ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass X-ORIGIN 'RFC 4512' )
objectClasses: ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName X-ORIGIN 'RFC 4512' )
objectClasses: ( 2.5.20.1 NAME 'subschema' AUXILIARY MAY ( dITStructureRules $ nameForms $ dITContentRules $ objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) X-ORIGIN 'RFC 4512' )
objectClasses: ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' SUP top AUXILIARY X-ORIGIN 'RFC 4512' )
...
attributeTypes: ( 2.16.840.1.113730.3.1.2384 NAME 'passwordTPRDelayValidFrom' DESC '389 Directory Server password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.582 NAME 'nsDS5ReplicaCredentials' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may  run sudo' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'SUDO' )
attributeTypes: ( 2.16.840.1.113730.3.1.2274 NAME 'nsslapd-instancedir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113719.1.301.4.24.1 NAME 'krbHostServer'  EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributeTypes: ( 1.3.18.0.2.4.1139 NAME 'printer-info' DESC 'Descriptive information about this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )
....
matchingRules: ( 2.5.13.17 NAME 'octetStringMatch' DESC 'The octetStringMatch rule compares an assertion value of the Octet String syntax to an attribute value of a syntax (e.g., the Octet String or JPEG syntax) whose cor
responding ASN.1 type is the OCTET STRING ASN.1 type.  The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same length and corresponding octets (by position) are the same.' SYNTAX
 1.3.6.1.4.1.1466.115.121.1.40 )
matchingRules: ( 2.5.13.18 NAME 'octetStringOrderingMatch' DESC 'The octetStringOrderingMatch rule compares an assertion value of the Octet String syntax to an attribute value of a syntax (e.g., the Octet String or JPEG s
yntax) whose corresponding ASN.1 type is the OCTET STRING ASN.1 type.  The rule evaluates to TRUE if and only if the attribute value appears earlier in the collation order than the assertion value.  The rule compares octe
t strings from the first octet to the last octet, and from the most significant bit to the least significant bit within the octet.  The first occurrence of a different bit determines the ordering of the strings.  A zero b
it precedes a one bit.  If the strings contain different numbers of octets but the longer string is identical to the shorter string up to the length of the shorter string, then the shorter string precedes the longer strin
g.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
...
ldapSyntaxes: ( 2.16.840.1.113730.3.7.1 DESC 'SpaceInsensitiveString' )
ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )
ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )
ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )

@nitnelave
Copy link
Member

Oh, geez, it's more complicated than I thought... I was hoping for adding a couple of lines to the hardcoded rootDSE 😅

Thanks a lot!

@Firstyear
Copy link

but for once it's not twice as complicated as it should be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants