[GH-ISSUE #707] Feature request: CLI support #253

Open
opened 2026-02-27 08:16:11 +03:00 by kerem · 16 comments
Owner

Originally created by @Zepmann on GitHub (Oct 19, 2023).
Original GitHub issue: https://github.com/lldap/lldap/issues/707

Currently it is not possible to configure lldap on the command line. It would be nice to have a command line tool that could perform the same functions as the web interface. It could provide a stepping stone to scripting without involving web techniques, or it could be used to entirely replace the web interface if a user does not want/need to use it.

I created such a tool in Bash using curl and jq. It relies on the GraphQL API and lldap_set_password, and supports almost everything the web interface does. I haven't added support for avatars yet, since it is not really part of my use case. Everything else works. It works similarly to docker-mailserver's setup tool. By default it gets all the parameters from lldap's configuration file. All required options can also be provided or overruled on the command line or through environment variables (important for most use cases: an admin password or web token), and passwords can be provided by the user through a non-echoing prompt.

If interested I am willing to share my Bash tool. I see this project mainly relies on Rust, so I do not know how much interest there would be for what I offer. Just let me know. If there is an interest, I will also consider adding avatar support to make it have 100% feature parity with the web interface. 😄

Originally created by @Zepmann on GitHub (Oct 19, 2023). Original GitHub issue: https://github.com/lldap/lldap/issues/707 Currently it is not possible to configure lldap on the command line. It would be nice to have a command line tool that could perform the same functions as the web interface. It could provide a stepping stone to scripting without involving web techniques, or it could be used to entirely replace the web interface if a user does not want/need to use it. I created such a tool in Bash using curl and jq. It relies on the GraphQL API and lldap_set_password, and supports almost everything the web interface does. I haven't added support for avatars yet, since it is not really part of my use case. Everything else works. It works similarly to [docker-mailserver](https://github.com/docker-mailserver/docker-mailserver)'s `setup` tool. By default it gets all the parameters from lldap's configuration file. All required options can also be provided or overruled on the command line or through environment variables (important for most use cases: an admin password or web token), and passwords can be provided by the user through a non-echoing prompt. If interested I am willing to share my Bash tool. I see this project mainly relies on Rust, so I do not know how much interest there would be for what I offer. Just let me know. If there is an interest, I will also consider adding avatar support to make it have 100% feature parity with the web interface. :smile:
Author
Owner

@Zepmann commented on GitHub (Oct 19, 2023):

Fun fact:

The compatibility with LDAP features that lldap supports is so good that OpenLDAP's ldappasswd tool can also be used to set a user's password. It was originally one of the ways that my tool allowed password change. In the spirit of what LLDAP supports and the philosophy behind it (and also because I only wanted to rely on the API and not on the LDAP protocol 😁), I removed this feature. Now only lldap's lldap_set_password is supported for this.

<!-- gh-comment-id:1771023546 --> @Zepmann commented on GitHub (Oct 19, 2023): Fun fact: The compatibility with LDAP features that lldap supports is so good that OpenLDAP's `ldappasswd` tool can also be used to set a user's password. It was originally one of the ways that my tool allowed password change. In the spirit of what LLDAP supports and the philosophy behind it (and also because I only wanted to rely on the API and not on the LDAP protocol :grin:), I removed this feature. Now only lldap's `lldap_set_password` is supported for this.
Author
Owner

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

Hey! I'm glad that you could easily build a CLI frontend :)
It seems like the frontend-agnostic API is paying off.

As for the actual tool, I don't want to commit to maintaining a bash script :/ If I were to use such a tool, I'd be using some Rust tooling to make sure I'm in sync with the exported schema, and to ensure type safety and so on.

However, I'd be delighted to list your repo as an unofficial CLI in the readme!

Note that there's an upcoming addition to the backend for which I don't have a frontend yet, the user defined attributes (#67). I have a PR almost ready that implements the last bit of the backend, and then the rest is just frontend stuff. If you add support for that in your bash script, it could make the feature available much earlier for testing!

<!-- gh-comment-id:1771049950 --> @nitnelave commented on GitHub (Oct 19, 2023): Hey! I'm glad that you could easily build a CLI frontend :) It seems like the frontend-agnostic API is paying off. As for the actual tool, I don't want to commit to maintaining a bash script :/ If I were to use such a tool, I'd be using some Rust tooling to make sure I'm in sync with the exported schema, and to ensure type safety and so on. However, I'd be delighted to list your repo as an unofficial CLI in the readme! Note that there's an upcoming addition to the backend for which I don't have a frontend yet, the user defined attributes (#67). I have a PR almost ready that implements the last bit of the backend, and then the rest is just frontend stuff. If you add support for that in your bash script, it could make the feature available much earlier for testing!
Author
Owner

@Zepmann commented on GitHub (Oct 20, 2023):

It seems like the frontend-agnostic API is paying off.

Well, kinda. Using GraphQL is an... interesting but confusing experience. Therefore this feature request still stands. It would be nice to have a CLI tool included that has the same functionality as the web interface for users who are not interested in developing with web technologies to automatically manage their user backend. So something like

some Rust tooling to make sure I'm in sync with the exported schema, and to ensure type safety and so on.

would be desirable.

#67 is pretty interesting, especially in the context of mail aliases. I miss something like that in lldap. I'll take a look if I can add basic support for it. For now I'd like to keep this issue open to track my progress.

To add to my bash CLI tool (based on the current schema):

  • List user-defined attributes. Half supported. The tool lists all attributes of either users or groups, regular and user-defined.
  • Add new attributes. Works, including setting the data type and whether the attribute is a list, visible and editable.
  • Remove existing attributes.
  • Show which attributes have values for a user/group.
  • Show attribute values of a user/group.
  • Set attribute values for users/groups.
  • Clear attribute values for users/groups.
  • Support normal attributes and lists.

Which mutation would be used to set and clear attributes vales for/from users/groups? I do not see it in the current schema, or I am interpreting it wrong. It is my first time working with GraphQL, so the issue might just be on my side. 😉

It might also be that this is still work in progress, if I read #67 correctly. In that case, I could look at the first four tasks to add partial support.

<!-- gh-comment-id:1772587471 --> @Zepmann commented on GitHub (Oct 20, 2023): > It seems like the frontend-agnostic API is paying off. Well, kinda. Using GraphQL is an... interesting but confusing experience. Therefore this feature request still stands. It would be nice to have a CLI tool included that has the same functionality as the web interface for users who are not interested in developing with web technologies to automatically manage their user backend. So something like > some Rust tooling to make sure I'm in sync with the exported schema, and to ensure type safety and so on. would be desirable. #67 is pretty interesting, especially in the context of mail aliases. I miss something like that in lldap. I'll take a look if I can add basic support for it. For now I'd like to keep this issue open to track my progress. To add to my bash CLI tool (based on the current schema): - [x] List user-defined attributes. Half supported. The tool lists all attributes of either users or groups, regular and user-defined. - [x] Add new attributes. Works, including setting the data type and whether the attribute is a list, visible and editable. - [x] Remove existing attributes. - [x] Show which attributes have values for a user/group. - [x] Show attribute values of a user/group. - [x] Set attribute values for users/groups. - [x] Clear attribute values for users/groups. - [x] Support normal attributes and lists. Which mutation would be used to set and clear attributes vales for/from users/groups? I do not see it in the current schema, or I am interpreting it wrong. It is my first time working with GraphQL, so the issue might just be on my side. :wink: It might also be that this is still work in progress, if I read #67 correctly. In that case, I could look at the first four tasks to add partial support.
Author
Owner

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

Using GraphQL is an... interesting but confusing experience.

In bash, I can definitely picture that :D Most languages have a framework that can generate some code based on the schema, so it's much simpler to use.

Re the rust tool: I agree it would be nice, but I'm most likely not going to have time any time soon.

For setting/clearing user/group attributes, it's going to be in update_user/update_group. It's not supported yet, I still have to merge a PR that adds support. The rest should be relatively stable, so you can start adding support if you want.

<!-- gh-comment-id:1772646748 --> @nitnelave commented on GitHub (Oct 20, 2023): > Using GraphQL is an... interesting but confusing experience. In bash, I can definitely picture that :D Most languages have a framework that can generate some code based on the schema, so it's much simpler to use. Re the rust tool: I agree it would be nice, but I'm most likely not going to have time any time soon. For setting/clearing user/group attributes, it's going to be in update_user/update_group. It's not supported yet, I still have to merge a PR that adds support. The rest should be relatively stable, so you can start adding support if you want.
Author
Owner

@Zepmann commented on GitHub (Oct 20, 2023):

In bash, I can definitely picture that :D Most languages have a framework that can generate some code based on the schema, so it's much simpler to use.

What helps me is that the GraphQL playground supports export of the current query + variables to a curl command. It does most of the heavy lifting. The rest is just messing around with GraphQL itself. 😛 Most of the heavy stuff is already done, including login and logout (if a username and password are provided for admin login, and not a token).

Re the rust tool: I agree it would be nice, but I'm most likely not going to have time any time soon.

Understandable. I think it is quite important to be able to use lldap in a managed environment without reinventing the wheel. Such a tool can abstract away a lot of stuff that an administrator is not interested in. This might be a good reason to keep this feature request open.

For setting/clearing user/group attributes, it's going to be in update_user/update_group. It's not supported yet, I still have to merge a PR that adds support. The rest should be relatively stable, so you can start adding support if you want.

Sounds like a plan. I will also add placeholders for the missing functionality.

<!-- gh-comment-id:1772665764 --> @Zepmann commented on GitHub (Oct 20, 2023): > In bash, I can definitely picture that :D Most languages have a framework that can generate some code based on the schema, so it's much simpler to use. What helps me is that the GraphQL playground supports export of the current query + variables to a curl command. It does most of the heavy lifting. The rest is just messing around with GraphQL itself. :stuck_out_tongue: Most of the heavy stuff is already done, including login and logout (if a username and password are provided for admin login, and not a token). > Re the rust tool: I agree it would be nice, but I'm most likely not going to have time any time soon. Understandable. I think it is quite important to be able to use lldap in a managed environment without reinventing the wheel. Such a tool can abstract away a lot of stuff that an administrator is not interested in. This might be a good reason to keep this feature request open. > For setting/clearing user/group attributes, it's going to be in update_user/update_group. It's not supported yet, I still have to merge a PR that adds support. The rest should be relatively stable, so you can start adding support if you want. Sounds like a plan. I will also add placeholders for the missing functionality.
Author
Owner

@nitnelave commented on GitHub (Oct 22, 2023):

Alright, I merged that other PR, so the backend is functionally complete! You should be able to add the functionality to create attributes and add them to users.

If/when you do, your tool can become the de facto testing tool for the feature while I figure out the web ui!

<!-- gh-comment-id:1774125015 --> @nitnelave commented on GitHub (Oct 22, 2023): Alright, I merged that other PR, so the backend is functionally complete! You should be able to add the functionality to create attributes and add them to users. If/when you do, your tool can become the de facto testing tool for the feature while I figure out the web ui!
Author
Owner

@Zepmann commented on GitHub (Nov 19, 2023):

Recently had some time to work on this. Updated the task list. I want to add at least basic attribute setting/clearing for both users and groups, and listing all user-defined attributes when querying info from a single user.

Other than the above, I also added support for adding and clearing (JPEG) avatars, making lldap-cli currently have full feature compatibility with the web interface (aside of not being able to show an avatar, which I consider acceptable on the command line).

Current dependencies are bash, curl, jq and base64.

<!-- gh-comment-id:1817961872 --> @Zepmann commented on GitHub (Nov 19, 2023): Recently had some time to work on this. Updated the task list. I want to add at least basic attribute setting/clearing for both users and groups, and listing all user-defined attributes when querying info from a single user. Other than the above, I also added support for adding and clearing (JPEG) avatars, making lldap-cli currently have full feature compatibility with the web interface (aside of not being able to show an avatar, which I consider acceptable on the command line). Current dependencies are bash, curl, jq and base64.
Author
Owner

@Zepmann commented on GitHub (Nov 27, 2023):

Had more time to work on lldap-cli. There are some final small things to do:

  • Publish a first version.
  • Add support for writing JPEG_PHOTO attributes values using JPG files. This is already supported for user avatars, but not yet for custom attributes.
  • Add support for reading JPEG_PHOTO attribute values and saving them to JPG files.
<!-- gh-comment-id:1828675512 --> @Zepmann commented on GitHub (Nov 27, 2023): Had more time to work on lldap-cli. There are some final small things to do: - [ ] Publish a first version. - [ ] Add support for writing JPEG_PHOTO attributes values using JPG files. This is already supported for user avatars, but not yet for custom attributes. - [ ] Add support for reading JPEG_PHOTO attribute values and saving them to JPG files.
Author
Owner

@nitnelave commented on GitHub (Dec 28, 2023):

Hey @Zepmann , any progress?

Do you think you could share your work as-is with what you already have? I know some people would be happy to have a CLI for LLDAP, even in bash. And who knows, maybe someone will help you out with the custom attributes!

<!-- gh-comment-id:1871034777 --> @nitnelave commented on GitHub (Dec 28, 2023): Hey @Zepmann , any progress? Do you think you could share your work as-is with what you already have? I know some people would be happy to have a CLI for LLDAP, even in bash. And who knows, maybe someone will help you out with the custom attributes!
Author
Owner

@Zepmann commented on GitHub (Dec 28, 2023):

@nitnelave, please see:

Zepmann/lldap-cli

Custom user and group attributes are fully supported. Based on some limited testing I did a small while ago, support in LLDAP seemed to be incomplete. While it is possible to use the GraphQL API to define and set custom attributes, it seemed not possible to read those attributes over LDAP. This might be a current limitation of the development version of LLDAP (which might have been corrected between the moment I tested and now), or it might be that I tested incorrectly at the time. Can you offer an update of the current state of custom attributes?

<!-- gh-comment-id:1871185517 --> @Zepmann commented on GitHub (Dec 28, 2023): @nitnelave, please see: [Zepmann/lldap-cli](https://github.com/Zepmann/lldap-cli) Custom user and group attributes are fully supported. Based on some limited testing I did a small while ago, support in LLDAP seemed to be incomplete. While it is possible to use the GraphQL API to define and set custom attributes, it seemed not possible to read those attributes over LDAP. This might be a current limitation of the development version of LLDAP (which might have been corrected between the moment I tested and now), or it might be that I tested incorrectly at the time. Can you offer an update of the current state of custom attributes?
Author
Owner

@nitnelave commented on GitHub (Dec 28, 2023):

The LLDAP implementation hasn't changed much recently. Can you point me to something that didn't work? A call to your script or a GraphQL query? I'll try to have a look

<!-- gh-comment-id:1871192233 --> @nitnelave commented on GitHub (Dec 28, 2023): The LLDAP implementation hasn't changed much recently. Can you point me to something that didn't work? A call to your script or a GraphQL query? I'll try to have a look
Author
Owner

@Zepmann commented on GitHub (Dec 28, 2023):

On the side of GraphQL and the database everything seemed to be running fine. I successfully created a new user attribute named 'mailAlias' that was a list, visible and editable. I could fill this attribute with values for a user. However, I was unable to query the attribute over LDAP.

Again, this might be my limited testing and it was a while ago. I will test it again and let you know the results.

<!-- gh-comment-id:1871203628 --> @Zepmann commented on GitHub (Dec 28, 2023): On the side of GraphQL and the database everything seemed to be running fine. I successfully created a new user attribute named 'mailAlias' that was a list, visible and editable. I could fill this attribute with values for a user. However, I was unable to query the attribute over LDAP. Again, this might be my limited testing and it was a while ago. I will test it again and let you know the results.
Author
Owner

@nitnelave commented on GitHub (Dec 28, 2023):

There's a test for custom attributes through GraphQL, do your requests look like that?

https://github.com/lldap/lldap/blob/main/server%2Fsrc%2Finfra%2Fgraphql%2Fquery.rs#L625

<!-- gh-comment-id:1871220191 --> @nitnelave commented on GitHub (Dec 28, 2023): There's a test for custom attributes through GraphQL, do your requests look like that? https://github.com/lldap/lldap/blob/main/server%2Fsrc%2Finfra%2Fgraphql%2Fquery.rs#L625
Author
Owner

@nitnelave commented on GitHub (Jan 2, 2024):

From what I can tell, your program works wonders: it can add/set new attributes, and they show up in the answer. I also tried querying with LDAP, and it works. You have to specify the attribute by name though, just requesting "*" will not show it.

<!-- gh-comment-id:1874669213 --> @nitnelave commented on GitHub (Jan 2, 2024): From what I can tell, your program works wonders: it can add/set new attributes, and they show up in the answer. I also tried querying with LDAP, and it works. You have to specify the attribute by name though, just requesting "*" will not show it.
Author
Owner

@Zepmann commented on GitHub (Jan 4, 2024):

Probably that was the scenario I tested. I queried for everything (I believe with ldapsearch without a filter). Still need to find some time to retest, though.

How much effort would it be to implement "*" support? Alternatively, I think this is fine if the need for filtering in queries is a documented limitation of LLDAP. Querying by other programs is done with a filter (e.g. a mail program looking for mail aliases from a user is not interested in other values). It is just with testing that admins sometimes request a full record, and might expect to see more compared to what they see now, and they should be familiar with the limited LDAP implementation by having read LLDAP's documentation.

<!-- gh-comment-id:1876500264 --> @Zepmann commented on GitHub (Jan 4, 2024): Probably that was the scenario I tested. I queried for everything (I believe with ldapsearch without a filter). Still need to find some time to retest, though. How much effort would it be to implement "*" support? Alternatively, I think this is fine if the need for filtering in queries is a documented limitation of LLDAP. Querying by other programs is done with a filter (e.g. a mail program looking for mail aliases from a user is not interested in other values). It is just with testing that admins sometimes request a full record, and might expect to see more compared to what they see now, and they should be familiar with the limited LDAP implementation by having read LLDAP's documentation.
Author
Owner

@nitnelave commented on GitHub (Oct 30, 2024):

Wildcards now return all the attributes.

<!-- gh-comment-id:2447275467 --> @nitnelave commented on GitHub (Oct 30, 2024): Wildcards now return all the attributes.
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#253
No description provided.