[GH-ISSUE #330] Allow browsing with tools like LDAP Admin #125

Closed
opened 2026-02-27 08:15:23 +03:00 by kerem · 11 comments
Owner

Originally created by @Roemer on GitHub (Oct 13, 2022).
Original GitHub issue: https://github.com/lldap/lldap/issues/330

Sometimes it is easier to browse the LDAP tree with tools like LDAP Admin (https://sourceforge.net/projects/ldapadmin/files/ldapadmin/). Right now it fails doing so but maybe it is an easy fix to get that working. I remember GLAuth had the same problem initially but that somehow got fixed and it is now browsable with those tools.

Originally created by @Roemer on GitHub (Oct 13, 2022). Original GitHub issue: https://github.com/lldap/lldap/issues/330 Sometimes it is easier to browse the LDAP tree with tools like LDAP Admin (https://sourceforge.net/projects/ldapadmin/files/ldapadmin/). Right now it fails doing so but maybe it is an easy fix to get that working. I remember GLAuth had the same problem initially but that somehow got fixed and it is now browsable with those tools.
Author
Owner

@nitnelave commented on GitHub (Oct 13, 2022):

Can you run LLDAP with --verbose and paste the logs after trying to see stuff with ldapadmin? (only until you get the first error/missing info in ldapadmin, I don't need pages and pages of logs).

<!-- gh-comment-id:1277599156 --> @nitnelave commented on GitHub (Oct 13, 2022): Can you run LLDAP with `--verbose` and paste the logs after trying to see stuff with ldapadmin? (only until you get the first error/missing info in ldapadmin, I don't need pages and pages of logs).
Author
Owner

@Roemer commented on GitHub (Oct 13, 2022):

When connecting with LDAP Admin, you need to fetch the DNs (dc=example,dc=com). When trying that, I do not get them back and get the following debug messages:

2022-10-13T14:21:19.465012300+00:00 INFO     LDAP session [ 139ms | 0.11% / 100.00% ]
2022-10-13T14:21:19.465511600+00:00 INFO     ┝━ LDAP request [ 138ms | 0.11% / 99.53% ]
2022-10-13T14:21:19.465530500+00:00 DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 8, op: BindRequest(LdapBindRequest { dn: "cn=admin,ou=people,dc=example,dc=com", cred: Simple("********") }), ctrl: [] }
2022-10-13T14:21:19.465534900+00:00 DEBUG    │  ┝━ do_bind [ 138ms | 0.04% / 99.42% ]
2022-10-13T14:21:19.465539600+00:00 DEBUG    │  │  ┝━ 🐛 [debug]: DN: cn=admin,ou=people,dc=example,dc=com
2022-10-13T14:21:19.465569100+00:00 DEBUG    │  │  ┝━ bind [ 138ms | 0.11% / 99.17% ]
2022-10-13T14:21:19.465845900+00:00 DEBUG    │  │  │  ┕━ passwords_match [ 137ms | 99.06% ]
2022-10-13T14:21:19.603244600+00:00 DEBUG    │  │  ┝━ get_user_groups [ 288µs | 0.21% ]
2022-10-13T14:21:19.603253600+00:00 DEBUG    │  │  │  ┝━ 🐛 [debug]:  | user_id: UserId("admin")
2022-10-13T14:21:19.603299600+00:00 DEBUG    │  │  │  ┝━ 🐛 [debug]:  | query: SELECT "groups"."group_id", "display_name", "creation_date", "uuid" FROM "groups" INNER JOIN "memberships" ON "groups"."group_id" = "memberships"."group_id" WHERE "user_id" = ?
2022-10-13T14:21:19.603736900+00:00 DEBUG    │  │  │  ┕━ 🐛 [debug]:  | return: {GroupDetails { group_id: GroupId(1), display_name: "lldap_admin", creation_date: 2022-10-13T06:04:20.646535Z, uuid: Uuid("b919b01f-597e-3532-97f9-915f64e91038") }}
2022-10-13T14:21:19.603744300+00:00 DEBUG    │  │  ┕━ 🐛 [debug]: Success!
2022-10-13T14:21:19.603768900+00:00 DEBUG    │  ┕━ 🐛 [debug]:  | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None })
2022-10-13T14:21:19.605320700+00:00 INFO     ┝━ LDAP request [ 479µs | 0.35% ]
2022-10-13T14:21:19.605362600+00:00 DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 10, op: SearchRequest(LdapSearchRequest { base: "", scope: Base, aliases: Never, sizelimit: 0, timelimit: 60, typesonly: false, filter: Present("objectClass"), attrs: ["namingContexts"] }), ctrl: [] }
2022-10-13T14:21:19.605370300+00:00 DEBUG    │  ┝━ 🐛 [debug]: rootDSE request
2022-10-13T14:21:19.605429800+00:00 DEBUG    │  ┝━ 🐛 [debug]:  | response: SearchResultEntry(LdapSearchResultEntry { dn: "", attributes: [LdapPartialAttribute { atype: "objectClass", vals: [[116, 111, 112]] }, LdapPartialAttribute { atype: "vendorName", vals: [[76, 76, 68, 65, 80]] }, LdapPartialAttribute { atype: "vendorVersion", vals: [[108, 108, 100, 97, 112, 95, 48, 46, 50, 46, 48]] }, LdapPartialAttribute { atype: "supportedLDAPVersion", vals: [[51]] }, LdapPartialAttribute { atype: "supportedExtension", vals: [[49, 46, 51, 46, 54, 46, 49, 46, 52, 46, 49, 46, 52, 50, 48, 51, 46, 49, 46, 49, 49, 46, 49]] }, LdapPartialAttribute { atype: "defaultnamingcontext", vals: [[100, 99, 61, 101, 120, 97, 109, 112, 108, 101, 44, 100, 99, 61, 99, 111, 109]] }] })
2022-10-13T14:21:19.605754600+00:00 DEBUG    │  ┕━ 🐛 [debug]:  | response: SearchResultDone(LdapResult { code: Success, matcheddn: "", message: "", referral: [] })
2022-10-13T14:21:19.607639200+00:00 INFO     ┕━ LDAP request [ 15.3µs | 0.01% ]
2022-10-13T14:21:19.607650900+00:00 DEBUG       ┕━ 🐛 [debug]:  | msg: LdapMsg { msgid: 11, op: UnbindRequest, ctrl: [] }
<!-- gh-comment-id:1277697417 --> @Roemer commented on GitHub (Oct 13, 2022): When connecting with LDAP Admin, you need to fetch the DNs (dc=example,dc=com). When trying that, I do not get them back and get the following debug messages: ``` 2022-10-13T14:21:19.465012300+00:00 INFO LDAP session [ 139ms | 0.11% / 100.00% ] 2022-10-13T14:21:19.465511600+00:00 INFO ┝━ LDAP request [ 138ms | 0.11% / 99.53% ] 2022-10-13T14:21:19.465530500+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 8, op: BindRequest(LdapBindRequest { dn: "cn=admin,ou=people,dc=example,dc=com", cred: Simple("********") }), ctrl: [] } 2022-10-13T14:21:19.465534900+00:00 DEBUG │ ┝━ do_bind [ 138ms | 0.04% / 99.42% ] 2022-10-13T14:21:19.465539600+00:00 DEBUG │ │ ┝━ 🐛 [debug]: DN: cn=admin,ou=people,dc=example,dc=com 2022-10-13T14:21:19.465569100+00:00 DEBUG │ │ ┝━ bind [ 138ms | 0.11% / 99.17% ] 2022-10-13T14:21:19.465845900+00:00 DEBUG │ │ │ ┕━ passwords_match [ 137ms | 99.06% ] 2022-10-13T14:21:19.603244600+00:00 DEBUG │ │ ┝━ get_user_groups [ 288µs | 0.21% ] 2022-10-13T14:21:19.603253600+00:00 DEBUG │ │ │ ┝━ 🐛 [debug]: | user_id: UserId("admin") 2022-10-13T14:21:19.603299600+00:00 DEBUG │ │ │ ┝━ 🐛 [debug]: | query: SELECT "groups"."group_id", "display_name", "creation_date", "uuid" FROM "groups" INNER JOIN "memberships" ON "groups"."group_id" = "memberships"."group_id" WHERE "user_id" = ? 2022-10-13T14:21:19.603736900+00:00 DEBUG │ │ │ ┕━ 🐛 [debug]: | return: {GroupDetails { group_id: GroupId(1), display_name: "lldap_admin", creation_date: 2022-10-13T06:04:20.646535Z, uuid: Uuid("b919b01f-597e-3532-97f9-915f64e91038") }} 2022-10-13T14:21:19.603744300+00:00 DEBUG │ │ ┕━ 🐛 [debug]: Success! 2022-10-13T14:21:19.603768900+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None }) 2022-10-13T14:21:19.605320700+00:00 INFO ┝━ LDAP request [ 479µs | 0.35% ] 2022-10-13T14:21:19.605362600+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 10, op: SearchRequest(LdapSearchRequest { base: "", scope: Base, aliases: Never, sizelimit: 0, timelimit: 60, typesonly: false, filter: Present("objectClass"), attrs: ["namingContexts"] }), ctrl: [] } 2022-10-13T14:21:19.605370300+00:00 DEBUG │ ┝━ 🐛 [debug]: rootDSE request 2022-10-13T14:21:19.605429800+00:00 DEBUG │ ┝━ 🐛 [debug]: | response: SearchResultEntry(LdapSearchResultEntry { dn: "", attributes: [LdapPartialAttribute { atype: "objectClass", vals: [[116, 111, 112]] }, LdapPartialAttribute { atype: "vendorName", vals: [[76, 76, 68, 65, 80]] }, LdapPartialAttribute { atype: "vendorVersion", vals: [[108, 108, 100, 97, 112, 95, 48, 46, 50, 46, 48]] }, LdapPartialAttribute { atype: "supportedLDAPVersion", vals: [[51]] }, LdapPartialAttribute { atype: "supportedExtension", vals: [[49, 46, 51, 46, 54, 46, 49, 46, 52, 46, 49, 46, 52, 50, 48, 51, 46, 49, 46, 49, 49, 46, 49]] }, LdapPartialAttribute { atype: "defaultnamingcontext", vals: [[100, 99, 61, 101, 120, 97, 109, 112, 108, 101, 44, 100, 99, 61, 99, 111, 109]] }] }) 2022-10-13T14:21:19.605754600+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: SearchResultDone(LdapResult { code: Success, matcheddn: "", message: "", referral: [] }) 2022-10-13T14:21:19.607639200+00:00 INFO ┕━ LDAP request [ 15.3µs | 0.01% ] 2022-10-13T14:21:19.607650900+00:00 DEBUG ┕━ 🐛 [debug]: | msg: LdapMsg { msgid: 11, op: UnbindRequest, ctrl: [] } ```
Author
Owner

@Roemer commented on GitHub (Oct 13, 2022):

If i manually enter the DN and try to get the data, I get Could not parse base DN: "" in LDAP Admin and the following log in LLDAP:

2022-10-13T14:23:37.574201900+00:00 INFO     LDAP session [ 113ms | 0.16% / 100.00% ]
2022-10-13T14:23:37.574833600+00:00 INFO     ┝━ LDAP request [ 112ms | 0.16% / 99.72% ]
2022-10-13T14:23:37.574853900+00:00 DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 12, op: BindRequest(LdapBindRequest { dn: "cn=admin,ou=people,dc=example,dc=com", cred: Simple("********") }), ctrl: [] }
2022-10-13T14:23:37.574858400+00:00 DEBUG    │  ┝━ do_bind [ 112ms | 0.05% / 99.57% ]
2022-10-13T14:23:37.574862700+00:00 DEBUG    │  │  ┝━ 🐛 [debug]: DN: cn=admin,ou=people,dc=example,dc=com
2022-10-13T14:23:37.574897100+00:00 DEBUG    │  │  ┝━ bind [ 112ms | 0.12% / 99.33% ]
2022-10-13T14:23:37.575215800+00:00 DEBUG    │  │  │  ┕━ passwords_match [ 112ms | 99.21% ]
2022-10-13T14:23:37.687079900+00:00 DEBUG    │  │  ┝━ get_user_groups [ 208µs | 0.18% ]
2022-10-13T14:23:37.687089700+00:00 DEBUG    │  │  │  ┝━ 🐛 [debug]:  | user_id: UserId("admin")
2022-10-13T14:23:37.687120800+00:00 DEBUG    │  │  │  ┝━ 🐛 [debug]:  | query: SELECT "groups"."group_id", "display_name", "creation_date", "uuid" FROM "groups" INNER JOIN "memberships" ON "groups"."group_id" = "memberships"."group_id" WHERE "user_id" = ?
2022-10-13T14:23:37.687443200+00:00 DEBUG    │  │  │  ┕━ 🐛 [debug]:  | return: {GroupDetails { group_id: GroupId(1), display_name: "lldap_admin", creation_date: 2022-10-13T06:04:20.646535Z, uuid: Uuid("b919b01f-597e-3532-97f9-915f64e91038") }}
2022-10-13T14:23:37.687449200+00:00 DEBUG    │  │  ┕━ 🐛 [debug]: Success!
2022-10-13T14:23:37.687460500+00:00 DEBUG    │  ┕━ 🐛 [debug]:  | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None })
2022-10-13T14:23:37.689097400+00:00 INFO     ┝━ LDAP request [ 116µs | 0.10% / 0.10% ]
2022-10-13T14:23:37.689111+00:00 DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 13, op: SearchRequest(LdapSearchRequest { base: "", scope: Base, aliases: Never, sizelimit: 0, timelimit: 0, typesonly: false, filter: Present("objectclass"), attrs: ["isGlobalCatalogReady"] }), ctrl: [] }
2022-10-13T14:23:37.689116500+00:00 DEBUG    │  ┝━ do_search [ 5.10µs | 0.00% ]
2022-10-13T14:23:37.689129600+00:00 DEBUG    │  ┕━ 🐛 [debug]:  | response: SearchResultDone(LdapResult { code: OperationsError, matcheddn: "", message: "Could not parse base DN: \"\"", referral: [] })
2022-10-13T14:23:37.690840500+00:00 INFO     ┕━ LDAP request [ 12.8µs | 0.01% ]
2022-10-13T14:23:37.690851700+00:00 DEBUG       ┕━ 🐛 [debug]:  | msg: LdapMsg { msgid: 14, op: UnbindRequest, ctrl: [] }
<!-- gh-comment-id:1277700290 --> @Roemer commented on GitHub (Oct 13, 2022): If i manually enter the DN and try to get the data, I get `Could not parse base DN: ""` in LDAP Admin and the following log in LLDAP: ``` 2022-10-13T14:23:37.574201900+00:00 INFO LDAP session [ 113ms | 0.16% / 100.00% ] 2022-10-13T14:23:37.574833600+00:00 INFO ┝━ LDAP request [ 112ms | 0.16% / 99.72% ] 2022-10-13T14:23:37.574853900+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 12, op: BindRequest(LdapBindRequest { dn: "cn=admin,ou=people,dc=example,dc=com", cred: Simple("********") }), ctrl: [] } 2022-10-13T14:23:37.574858400+00:00 DEBUG │ ┝━ do_bind [ 112ms | 0.05% / 99.57% ] 2022-10-13T14:23:37.574862700+00:00 DEBUG │ │ ┝━ 🐛 [debug]: DN: cn=admin,ou=people,dc=example,dc=com 2022-10-13T14:23:37.574897100+00:00 DEBUG │ │ ┝━ bind [ 112ms | 0.12% / 99.33% ] 2022-10-13T14:23:37.575215800+00:00 DEBUG │ │ │ ┕━ passwords_match [ 112ms | 99.21% ] 2022-10-13T14:23:37.687079900+00:00 DEBUG │ │ ┝━ get_user_groups [ 208µs | 0.18% ] 2022-10-13T14:23:37.687089700+00:00 DEBUG │ │ │ ┝━ 🐛 [debug]: | user_id: UserId("admin") 2022-10-13T14:23:37.687120800+00:00 DEBUG │ │ │ ┝━ 🐛 [debug]: | query: SELECT "groups"."group_id", "display_name", "creation_date", "uuid" FROM "groups" INNER JOIN "memberships" ON "groups"."group_id" = "memberships"."group_id" WHERE "user_id" = ? 2022-10-13T14:23:37.687443200+00:00 DEBUG │ │ │ ┕━ 🐛 [debug]: | return: {GroupDetails { group_id: GroupId(1), display_name: "lldap_admin", creation_date: 2022-10-13T06:04:20.646535Z, uuid: Uuid("b919b01f-597e-3532-97f9-915f64e91038") }} 2022-10-13T14:23:37.687449200+00:00 DEBUG │ │ ┕━ 🐛 [debug]: Success! 2022-10-13T14:23:37.687460500+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None }) 2022-10-13T14:23:37.689097400+00:00 INFO ┝━ LDAP request [ 116µs | 0.10% / 0.10% ] 2022-10-13T14:23:37.689111+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 13, op: SearchRequest(LdapSearchRequest { base: "", scope: Base, aliases: Never, sizelimit: 0, timelimit: 0, typesonly: false, filter: Present("objectclass"), attrs: ["isGlobalCatalogReady"] }), ctrl: [] } 2022-10-13T14:23:37.689116500+00:00 DEBUG │ ┝━ do_search [ 5.10µs | 0.00% ] 2022-10-13T14:23:37.689129600+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: SearchResultDone(LdapResult { code: OperationsError, matcheddn: "", message: "Could not parse base DN: \"\"", referral: [] }) 2022-10-13T14:23:37.690840500+00:00 INFO ┕━ LDAP request [ 12.8µs | 0.01% ] 2022-10-13T14:23:37.690851700+00:00 DEBUG ┕━ 🐛 [debug]: | msg: LdapMsg { msgid: 14, op: UnbindRequest, ctrl: [] } ```
Author
Owner

@nitnelave commented on GitHub (Oct 13, 2022):

Yeah, I see, it's querying a few global properties that are not implemented. It should be rather easy to implement, but it's not very high on my priority list. The web UI is supposed to be the simpler way to access the data.

<!-- gh-comment-id:1277705078 --> @nitnelave commented on GitHub (Oct 13, 2022): Yeah, I see, it's querying a few global properties that are not implemented. It should be rather easy to implement, but it's not very high on my priority list. The web UI is supposed to be the simpler way to access the data.
Author
Owner

@nitnelave commented on GitHub (Oct 19, 2022):

Once #345 is pushed, can you check if that solves your issues? If the tool relies on querying the schema, though, that's going to be much harder to fix (and I'm not sure I want to).

<!-- gh-comment-id:1284202487 --> @nitnelave commented on GitHub (Oct 19, 2022): Once #345 is pushed, can you check if that solves your issues? If the tool relies on querying the schema, though, that's going to be much harder to fix (and I'm not sure I want to).
Author
Owner

@Roemer commented on GitHub (Oct 19, 2022):

Awesome yes, it is now browsable which already helps a lot. Only issue is that the ous are not visible and all entries basically are an endless tree always containing themselves :) See the screenshot:
image

<!-- gh-comment-id:1284543116 --> @Roemer commented on GitHub (Oct 19, 2022): Awesome yes, it is now browsable which already helps a lot. Only issue is that the `ou`s are not visible and all entries basically are an endless tree always containing themselves :) See the screenshot: ![image](https://user-images.githubusercontent.com/393641/196798548-1a943045-7b0d-4633-b377-a97440b18719.png)
Author
Owner

@Roemer commented on GitHub (Oct 19, 2022):

Also it seems that quite some attributes are now shown or missing:

  • memberof for the user (maybe that's the issue why this does not work in Jenkins as well?)
  • group only has an objectclass of groupOfUniqueNames
<!-- gh-comment-id:1284561747 --> @Roemer commented on GitHub (Oct 19, 2022): Also it seems that quite some attributes are now shown or missing: - `memberof` for the user (maybe that's the issue why this does not work in Jenkins as well?) - group only has an `objectclass` of `groupOfUniqueNames`
Author
Owner

@nitnelave commented on GitHub (Oct 20, 2022):

To be fair, I don't care that much how it renders in the LDAP viewer. I'd have to add special code to handle the OUs, debug why it thinks there's nesting, why memberOf is not returned and so on, but that's not really a priority.

I fixed the rootDse response (the metadata about the whole server) because it was easy, but the rest I'm not that interested. I would maybe accept PRs if they don't complicate the code too much.

But to be honest: what's the point? You have a web frontend that's the golden standard, and you even have a semi functional readonly LDAP viewer. Why do you need more than that?

<!-- gh-comment-id:1284992305 --> @nitnelave commented on GitHub (Oct 20, 2022): To be fair, I don't care that much how it renders in the LDAP viewer. I'd have to add special code to handle the OUs, debug why it thinks there's nesting, why memberOf is not returned and so on, but that's not really a priority. I fixed the rootDse response (the metadata about the whole server) because it was easy, but the rest I'm not that interested. I would maybe accept PRs if they don't complicate the code too much. But to be honest: what's the point? You have a web frontend that's the golden standard, and you even have a semi functional readonly LDAP viewer. Why do you need more than that?
Author
Owner

@Roemer commented on GitHub (Oct 20, 2022):

The Web-UI shows a very abstracted form of all the data. To configure LDAP for a service, it is the easiest to just see the "raw" data of the objects (which attributes are available, which values are they set to, which objectclasses exist, ...). But I am totally fine with the current stage. Once I have my vscode-dev-container running I can give it a go to improve that further.

<!-- gh-comment-id:1285091365 --> @Roemer commented on GitHub (Oct 20, 2022): The Web-UI shows a very abstracted form of all the data. To configure LDAP for a service, it is the easiest to just see the "raw" data of the objects (which attributes are available, which values are they set to, which objectclasses exist, ...). But I am totally fine with the current stage. Once I have my vscode-dev-container running I can give it a go to improve that further.
Author
Owner

@nitnelave commented on GitHub (Oct 20, 2022):

I agree that some improvements are needed for the front-end: I want to put (at least for the admin) more LDAP information there. There's some work that'll wait until #67 is done, since it'll expose some of the LDAP schema for configuration and display.

<!-- gh-comment-id:1285226531 --> @nitnelave commented on GitHub (Oct 20, 2022): I agree that some improvements are needed for the front-end: I want to put (at least for the admin) more LDAP information there. There's some work that'll wait until #67 is done, since it'll expose some of the LDAP schema for configuration and display.
Author
Owner

@nitnelave commented on GitHub (Oct 20, 2022):

I'm closing this issue for now since the very basic functionality is there, we can open more specific issues later on if needed.

<!-- gh-comment-id:1285227288 --> @nitnelave commented on GitHub (Oct 20, 2022): I'm closing this issue for now since the very basic functionality is there, we can open more specific issues later on if needed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/lldap-lldap#125
No description provided.