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: Arbitrary and Duplicate Text Fields #67

Open
13 of 22 tasks
dwmunster opened this issue Oct 21, 2021 · 26 comments
Open
13 of 22 tasks

Feature Request: Arbitrary and Duplicate Text Fields #67

dwmunster opened this issue Oct 21, 2021 · 26 comments
Labels
backend Issues that require a backend change enhancement New feature or request

Comments

@dwmunster
Copy link

dwmunster commented Oct 21, 2021

Overview

As an LLDAP admin, I would like to be able to define arbitrary text fields that may be repeated to extend the user object schema.

Details

I would like to see the following:

  • the ability to define arbitrary fields with string data
  • the ability to restrict the ability for users to change these fields
  • the ability to have a list or repeated values for the field

Context

I am interested in using LLDAP as a user DB for my mail server and to replace my OpenLDAP instance with something much more manageable. However, my users may have more than one email address assigned to them. Currently, I have that implemented with a repeated mailalias attribute. For example, my user looks something like the following:

dn: uid=user,ou=people,dc=domain,dc=tld
objectClass: mailAccount
objectClass: person
objectClass: uidObject
objectClass: top
uid: user
mail: user@domain.tld
mailenable: TRUE
sn: SN
cn: CN
mailalias: user@domain1.tld
mailalias: user@domain2.tld
mailalias: user2@domain1.tld

Restricting the ability for users to change the mailalias attributes is also crucial to prevent users from impersonating other users and sending mail from arbitrary addresses.

Other use cases include:

  • SSH Public Keys
  • Home directories

Task breakdown:

  • Prepare DB and migration
  • Create Schema data structure + default schema
  • Migrate first and last name to attributes
  • Implement read in the domain
  • Implement read in graphql
  • Implement read in LDAP
  • Implement write in domain
  • Implement write in graphql
  • Implement write in LDAP
  • Implement front-end read/write
  • Implement schema manipulation features
    • domain
    • graphql
    • frontend
  • Implement aliases
    • Query from LDAP
    • create/delete/query domain
    • create/delete/query graphql
    • create/delete/display frontend
  • Custom LDAP object classes
    • backend
    • frontend
@nitnelave nitnelave added the enhancement New feature or request label Oct 22, 2021
@nitnelave
Copy link
Member

We talked about it a bit on Discord. It'll probably end up getting implemented without a schema: if you request the field, it's there, but otherwise you can't know about it. Moreover, we'll probably only have unstructured strings only, but we'll support repeated or single (if it makes a difference).

In terms of prioritization though, it'll come after the V1 project, so not for a while.

@nitnelave nitnelave added the backend Issues that require a backend change label Jul 15, 2022
@nitnelave
Copy link
Member

Here's an RFC for this feature: https://docs.google.com/document/d/1BdizgwX6Pvy5hqH8_HzSg3LCa66tQSDhrTsdhF80ySY/edit?usp=drivesdk

@Samonitari
Copy link

Samonitari commented Oct 13, 2022

Wow!

I was searching for ldap-ui when I stumbled upon this project, which seems pretty awesome.
The only thing stopping me from using this form my family mail/matrix/nextcloud/etc self-host is - mostly - mailAlias attribute.

OTOH, reading the RFC, what use does objectClass filtering will have, if any filtering will always return all users (or groups) if all new items are added for all users (groups)
Seems like adding new, quasi-objectclasses to all users or all groups is quite a limitation, kinda defeats the whole auxilliary class paradigm.
For example, I only host mail for immediate family, meaning they would have PostfixBookMailAccount as auxilliay objectClass, but I host matrix for the larger family.

I have to have filtering based on different objectClass I think... I know it is not intended as a full (Open)LDAP replacement, I am not asking for groupOfUrls, ppolicy and the like.
Could you improve on the RFC possibly?

@nitnelave
Copy link
Member

@Samonitari The objectclass is just so that you can customize the output to match whatever your service expects (e.g. "Oh I only work with PosixUser" -> all the users are now PosixUsers).

The classes in LDAP allow to change the structure of objects, and in LLDAP you only ever have 2 structures, users and groups.

For your usecase, there is a simpler solution: have 2 groups, mailUsers and matrixUsers, and add your users to each group as needed. Then you can filter on these groups.

@Samonitari
Copy link

For your usecase, there is a simpler solution: have 2 groups, mailUsers and matrixUsers, and add your users to each group as needed. Then you can filter on these groups.

Fair enough.

I am still wrapping my head around a few things to solve differently (or at all) with LLDAP.
Can I reach you in like matrix or something (or could I write an email)?

@Samonitari
Copy link

Samonitari commented Oct 13, 2022

BTW, Nextcloud's Mail app have support for getting aliases from a - arbitrarily named - LDAP attribute, which makes handling multiple mail identities for a single mailbox a breeze. You automatically get your identities with your provisioned mail accounts.

Just some context for what this feature means 😜

@nitnelave
Copy link
Member

Can I reach you in like matrix or something (or could I write an email)?

Feel free to join the Discord :)

@blysik
Copy link

blysik commented Apr 5, 2023

This could also be used to get ssh keys in? I'm currently using glauth for ldap, and rely on it to make ssh public keys available.

@nitnelave
Copy link
Member

nitnelave commented Apr 5, 2023 via email

@abn0mad
Copy link

abn0mad commented May 9, 2023

Is there a timeline for this feature?

LLDAP is a truly wonderful project, many thanks for all the team's efforts.
The addition of custom fields, however, is sorely needed for compatibility with other apps such as sftpgo and its external (ldap) authentication hook which requires a sshpublickey and homedir field to operate.

Again, many thanks for the fantastic project and all the effort, very much appreciated. :)

@nitnelave nitnelave mentioned this issue May 9, 2023
@nitnelave
Copy link
Member

It is the top priority, but I don't have a timeline for my free time :)

If you want to help me build confidence to get started, you can contribute new integration tests for the integrations you care about. See the gitea integration test here: https://github.com/lldap/lldap/blob/main/server/tests/integrations.rs
The idea is to issue the same LDAP queries as the service, and to check that the output is as expected.

This issue requires a fundamental schema and query change, and I don't want to break everything.

@abn0mad
Copy link

abn0mad commented May 9, 2023

@nitnelave that's totally understandable, and again, thank you for all the hard work on the project. Happy to hear that it is a priority. I hope to include both LLDAP and Kanidm in a series of tutorials and guides that I plan to write on setting up FOSS-based networks and servers. Hopefully, that will attract some organisations to sponsor both projects, as they are well-deserved of more support.

I'll see what I can do with the integration test suggestion, if I can help I surely shall, but it will take me some time to get my head around the code. (Bit of a noob with Rust to be honest : (

Thanks again for reading and answering and all the hard work; hope I can contribute in the near future :)

@nitnelave
Copy link
Member

For all those watching this issue, as you can see there's been some activity. I created a bunch of tasks to show the roadmap of what's left to implement, you can follow along ;)

@nitnelave
Copy link
Member

Alright, the feature should be functionally complete, but I don't have the frontend updated yet. It's going to be slightly non-trivial, so it'll come little by little.

If there are some brave souls, you can use the graphql API (with the playground or with a client library, or even just curl) to create custom attributes, and add them to users and groups. Any testing would be much appreciated!

With that, a bunch of integrations are unlocked: PAM with sssd, windows with samba, ssh keys stored in LLDAP...
It'll probably take a little effort to figure out the exact configuration, but as a community we should be able to figure it out :)

@vincentDcmps
Copy link

Hi thanks for your work, I just try to add an attribute uidNumber and set on user admin via graphql but when I request information via LDAPsearch I can't get this attribute, this function is not implemented yet?

@nitnelave
Copy link
Member

@vincentDcmps can you try specifically requesting the attribute by name in the LDAP query?

@vincentDcmps
Copy link

vincentDcmps commented Nov 16, 2023

yes see answer of graphql query

{
  "data": {
    "user": {
      "id": "admin",
      "attributes": [
        {
          "name": "uidNumber",
          "value": [
            "10000"
          ]
        }
      ],
      "groups": [
        {
          "id": 1
        },
        {
          "id": 4
        }
      ]
    }
  }
}

and with this

ldapsearch  -H ldap://192.168.1.42:3890 -D uid=admin,ou=people,dc=ducamps,dc=eu -w 'REPLACE_WITH_PASSWORD' uidNumber 
# extended LDIF
#
# LDAPv3
# base <dc=ducamps,dc=eu> (default) with scope subtree
# filter: (objectclass=*)
# requesting: uidNumber
#

# admin, people, ducamps.eu
dn: uid=admin,ou=people,dc=ducamps,dc=eu

# lldap_admin, groups, ducamps.eu
dn: cn=lldap_admin,ou=groups,dc=ducamps,dc=eu

# lldap_password_manager, groups, ducamps.eu
dn: cn=lldap_password_manager,ou=groups,dc=ducamps,dc=eu

# lldap_strict_readonly, groups, ducamps.eu
dn: cn=lldap_strict_readonly,ou=groups,dc=ducamps,dc=eu

# toto, groups, ducamps.eu
dn: cn=toto,ou=groups,dc=ducamps,dc=eu

# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.319 false MAUCAQUEAA==
pagedresults: estimate=5 cookie=

# numResponses: 6
# numEntries: 5

log message:

2023-11-16T18:37:26.923734457+00:00  WARN     │  ┕━ 🚧 [warn]: Ignoring unrecognized group attribute: uidnumber\n\

@nitnelave
Copy link
Member

Oh, I think I know what's going on: we create the attribute with the exact name, keeping the case, but we try to find it in a case insensitive way by converting the input to lowercase. If you delete your attribute and recreate it as "uidnumber" (no uppercase), does it work? If so, I already have a WIP PR that'll fix this.

@vincentDcmps
Copy link

indeed this works with attribute in lowercase thanks

@nitnelave
Copy link
Member

We now have an (experimental) CLI frontend for the custom attributes: https://github.com/Zepmann/lldap-cli
Thanks @Zepmann !

Feel free to try it out, it should greatly simplify handling of attributes (but it's not user friendly, only admin friendly)

@Zepmann
Copy link
Contributor

Zepmann commented Dec 28, 2023

Feel free to try it out, it should greatly simplify handling of attributes (but it's not user friendly, only admin friendly)

I prefer the term user-centric. 😉

If there are any questions about the usage of LLDAP-CLI, please let me know by tagging me in. To get you started, consider these commands:

$ lldap-cli -D admin -w somepassword schema attribute user list
$ lldap-cli -D admin -w somepassword user attribute list someuser
$ lldap-cli -D admin -w somepassword user attribute values someuser mail

$ lldap-cli -D admin -w somepassword schema attribute user add mailAlias string -l -v -e
$ lldap-cli -D admin -w somepassword user update add someuser mailAlias someuser1@example.com
$ lldap-cli -D admin -w somepassword user update add someuser mailAlias someuser2@example.com
$ lldap-cli -D admin -w somepassword user attribute values someuser mailAlias

Replace admin and somepassword with valid LLDAP credentials of an administrator account.

The first set of command shows you which user attributes are in the schema, which user attributes have a value for user someuser, and what the value of the mail attribute is for someuser.

The last set of command defines new user attribute mailAlias in the schema, gives it two values for user someuser (since it is a list, it can have multiple values), and shows the values as configured.

@jakob42
Copy link
Contributor

jakob42 commented Jan 6, 2024

I'm a bit unclear about whats already in the current 0.5 release. I thought custom attributes would be already included, but it doesn't seem to work for me with the commands Zepmann had here as an example:

$ lldap-cli schema attribute user add mailalias string -l -v -e
ERROR: Unknown type \AttributeType\
Unknown field \addUserAttribute\ on type \Mutation\

Do I need a dev version to test this feature?

@Zepmann
Copy link
Contributor

Zepmann commented Jan 6, 2024

@jakob42

Custom attributes only work in the current development version. There hasn't yet been a stable release of LLDAP that includes it.

@nitnelave
Copy link
Member

I was waiting until we have a UI for it before releasing it. Now that we have the CLI tool, it's not the best but I'll make a stable release. It has been already tested by several people, and no major issues remain. I'll still want to fix #763 before releasing though.

@Zepmann
Copy link
Contributor

Zepmann commented Jan 6, 2024

@nitnelave

You can always make a stable release in which you label some features experimental, such as custom attributes. This will temper expectations, especially since this new feature is only usable with community-contributed tooling for now and has not been extensively tested.

@jakob42
Copy link
Contributor

jakob42 commented Jan 6, 2024

Thanks @nitnelave! No need to hurry on my account, I'll either patiently wait or get a dev version. :-)

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

No branches or pull requests

8 participants