[GH-ISSUE #858] [BUG] Search for custom list attribute fails #308

Closed
opened 2026-02-27 08:16:34 +03:00 by kerem · 9 comments
Owner

Originally created by @ghtyrant on GitHub (Mar 9, 2024).
Original GitHub issue: https://github.com/lldap/lldap/issues/858

Describe the bug
I have defined a custom list attribute (mailAlias) on my user schema using lldap-cli:

$ lldap-cli schema attribute user add mailAlias string -l -v
$ lldap-cli user update add myuser mailalias postmaster@example.com
$ lldap-cli user update add myuser mailalias postmaster@example2.com
$ lldap-cli schema attribute user list
Name           Type        Is list  Is visible  Is editable
----           ----        -------  ----------  -----------
avatar         JPEG_PHOTO  false    true        true
creation_date  DATE_TIME   false    true        false
display_name   STRING      false    true        true
first_name     STRING      false    true        true
last_name      STRING      false    true        true
mail           STRING      false    true        true
mailalias      STRING      true     true        false
user_id        STRING      false    true        false
uuid           STRING      false    true        false
$ lldap-cli user attribute list myuser
creation_date
display_name
last_name
mail
mailalias
user_id
uuidfirst_name

It has some values in it:

$ lldap-cli user attribute values myuser mailalias
postmaster@example.com
postmaster@example2.com
(...)

When I try to search for a user with a certain mailAlias, the search returns nothing:

$ ldapsearch -H ldap://localhost:3890 -D uid=admin,ou=people,dc=example,dc=com -W -b "ou=people,dc=example,dc=com" mailAlias=postmaster@example.com
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <ou=people,dc=example,dc=com> with scope subtree
# filter: mailAlias=postmaster@example.com
# requesting: ALL
#

# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.319 false MAUCAQAEAA==
pagedresults: cookie=

# numResponses: 1

Expected behavior
I expect ldapsearch to return myuser. I'm trying to use this in Postfix, so I can define multiple mail aliases per user.

Logs

2024-03-09T18:52:08.364873368+00:00  INFO     LDAP session [ 91.4ms | 0.08% / 100.00% ]
2024-03-09T18:52:08.364901424+00:00  INFO     ┝━ LDAP request [ 90.9ms | 0.09% / 99.43% ]
2024-03-09T18:52:08.364913131+00:00  DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 1, op: BindRequest(LdapBindRequest { dn: "uid=admin,ou=people,dc=example,dc=com", cred: LdapBindCred::Simple }), ctrl: [] }                                                                                                                                                                                                
2024-03-09T18:52:08.364916048+00:00  DEBUG    │  ┝━ do_bind [ 90.8ms | 0.04% / 99.34% ] dn: uid=admin,ou=people,dc=example,dc=com
2024-03-09T18:52:08.364923864+00:00  DEBUG    │  │  ┝━ bind [ 90.6ms | 0.01% / 99.10% ]                                                                                                                 
2024-03-09T18:52:08.364927943+00:00  DEBUG    │  │  │  ┝━ get_password_file_for_user [ 87.1µs | 0.10% ] user_id: UserId(CaseInsensitiveString("admin"))                                                
2024-03-09T18:52:08.365148659+00:00  DEBUG    │  │  │  ┕━ passwords_match [ 90.5ms | 98.99% ] username: admin                                                                                           
2024-03-09T18:52:08.455664200+00:00  DEBUG    │  │  ┝━ get_user_groups [ 180µs | 0.20% ] user_id: "admin"                                                                                               
2024-03-09T18:52:08.456070108+00:00  DEBUG    │  │  │  ┕━ 🐛 [debug]:  | return: {GroupDetails { group_id: GroupId(1), display_name: GroupName("lldap_admin"), creation_date: 2024-03-06T23:06:51.819128537, uuid: Uuid("202aee70-254a-39c4-a855-79937905e3f8"), attributes: [] }}                                                                                                                              
2024-03-09T18:52:08.456076507+00:00  DEBUG    │  │  ┕━ 🐛 [debug]: Success!                                                                                                                             
2024-03-09T18:52:08.456082688+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None })                                                                                                                                                                                                    
2024-03-09T18:52:08.456234117+00:00  INFO     ┝━ LDAP request [ 441µs | 0.05% / 0.48% ]                                                                                                                 
2024-03-09T18:52:08.456242301+00:00  DEBUG    │  ┝━ 🐛 [debug]:  | msg: LdapMsg { msgid: 2, op: SearchRequest(LdapSearchRequest { base: "ou=people,dc=example,dc=com", scope: Subtree, aliases: Never, sizelimit: 0, timelimit: 0, typesonly: false, filter: Equality("mailAlias", "postmaster@example.com"), attrs: [] }), ctrl: [] }                                                                                  
2024-03-09T18:52:08.456243464+00:00  DEBUG    │  ┝━ do_search [ 394µs | 0.19% / 0.43% ]                                                                                                                 
2024-03-09T18:52:08.456526771+00:00  DEBUG    │  │  ┝━ 🐛 [debug]:  | request.base: "ou=people,dc=example,dc=com" | scope: Users
2024-03-09T18:52:08.456528181+00:00  DEBUG    │  │  ┕━ get_user_list [ 219µs | 0.02% / 0.24% ]
2024-03-09T18:52:08.456534160+00:00  DEBUG    │  │     ┝━ 🐛 [debug]:  | filters: AttributeEquality(AttributeName(CaseInsensitiveString("mailalias")), Serialized("\u{12}"))
2024-03-09T18:52:08.456537820+00:00  DEBUG    │  │     ┕━ list_users [ 203µs | 0.22% ] filters: Some(AttributeEquality(AttributeName(CaseInsensitiveString("mailalias")), Serialized("\u{12}"))) | _get_groups: false
2024-03-09T18:52:08.457127364+00:00  DEBUG    │  │        ┕━ 🐛 [debug]:  | return: []
2024-03-09T18:52:08.457135892+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | response: SearchResultDone(LdapResult { code: Success, matcheddn: "", message: "", referral: [] })
2024-03-09T18:52:08.457224011+00:00  INFO     ┕━ LDAP request [ 7.48µs | 0.01% ]
2024-03-09T18:52:08.457227565+00:00  DEBUG       ┕━ 🐛 [debug]:  | msg: LdapMsg { msgid: 3, op: UnbindRequest, ctrl: [] }

I am using lldap:latest via Docker.

Originally created by @ghtyrant on GitHub (Mar 9, 2024). Original GitHub issue: https://github.com/lldap/lldap/issues/858 **Describe the bug** I have defined a custom list attribute (`mailAlias`) on my user schema using lldap-cli: ``` $ lldap-cli schema attribute user add mailAlias string -l -v $ lldap-cli user update add myuser mailalias postmaster@example.com $ lldap-cli user update add myuser mailalias postmaster@example2.com ``` ``` $ lldap-cli schema attribute user list Name Type Is list Is visible Is editable ---- ---- ------- ---------- ----------- avatar JPEG_PHOTO false true true creation_date DATE_TIME false true false display_name STRING false true true first_name STRING false true true last_name STRING false true true mail STRING false true true mailalias STRING true true false user_id STRING false true false uuid STRING false true false ``` ``` $ lldap-cli user attribute list myuser creation_date display_name last_name mail mailalias user_id uuidfirst_name ``` It has some values in it: ``` $ lldap-cli user attribute values myuser mailalias postmaster@example.com postmaster@example2.com (...) ``` When I try to search for a user with a certain mailAlias, the search returns nothing: ``` $ ldapsearch -H ldap://localhost:3890 -D uid=admin,ou=people,dc=example,dc=com -W -b "ou=people,dc=example,dc=com" mailAlias=postmaster@example.com Enter LDAP Password: # extended LDIF # # LDAPv3 # base <ou=people,dc=example,dc=com> with scope subtree # filter: mailAlias=postmaster@example.com # requesting: ALL # # search result search: 2 result: 0 Success control: 1.2.840.113556.1.4.319 false MAUCAQAEAA== pagedresults: cookie= # numResponses: 1 ``` **Expected behavior** I expect `ldapsearch` to return `myuser`. I'm trying to use this in Postfix, so I can define multiple mail aliases per user. **Logs** ``` 2024-03-09T18:52:08.364873368+00:00 INFO LDAP session [ 91.4ms | 0.08% / 100.00% ] 2024-03-09T18:52:08.364901424+00:00 INFO ┝━ LDAP request [ 90.9ms | 0.09% / 99.43% ] 2024-03-09T18:52:08.364913131+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 1, op: BindRequest(LdapBindRequest { dn: "uid=admin,ou=people,dc=example,dc=com", cred: LdapBindCred::Simple }), ctrl: [] } 2024-03-09T18:52:08.364916048+00:00 DEBUG │ ┝━ do_bind [ 90.8ms | 0.04% / 99.34% ] dn: uid=admin,ou=people,dc=example,dc=com 2024-03-09T18:52:08.364923864+00:00 DEBUG │ │ ┝━ bind [ 90.6ms | 0.01% / 99.10% ] 2024-03-09T18:52:08.364927943+00:00 DEBUG │ │ │ ┝━ get_password_file_for_user [ 87.1µs | 0.10% ] user_id: UserId(CaseInsensitiveString("admin")) 2024-03-09T18:52:08.365148659+00:00 DEBUG │ │ │ ┕━ passwords_match [ 90.5ms | 98.99% ] username: admin 2024-03-09T18:52:08.455664200+00:00 DEBUG │ │ ┝━ get_user_groups [ 180µs | 0.20% ] user_id: "admin" 2024-03-09T18:52:08.456070108+00:00 DEBUG │ │ │ ┕━ 🐛 [debug]: | return: {GroupDetails { group_id: GroupId(1), display_name: GroupName("lldap_admin"), creation_date: 2024-03-06T23:06:51.819128537, uuid: Uuid("202aee70-254a-39c4-a855-79937905e3f8"), attributes: [] }} 2024-03-09T18:52:08.456076507+00:00 DEBUG │ │ ┕━ 🐛 [debug]: Success! 2024-03-09T18:52:08.456082688+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: BindResponse(LdapBindResponse { res: LdapResult { code: Success, matcheddn: "", message: "", referral: [] }, saslcreds: None }) 2024-03-09T18:52:08.456234117+00:00 INFO ┝━ LDAP request [ 441µs | 0.05% / 0.48% ] 2024-03-09T18:52:08.456242301+00:00 DEBUG │ ┝━ 🐛 [debug]: | msg: LdapMsg { msgid: 2, op: SearchRequest(LdapSearchRequest { base: "ou=people,dc=example,dc=com", scope: Subtree, aliases: Never, sizelimit: 0, timelimit: 0, typesonly: false, filter: Equality("mailAlias", "postmaster@example.com"), attrs: [] }), ctrl: [] } 2024-03-09T18:52:08.456243464+00:00 DEBUG │ ┝━ do_search [ 394µs | 0.19% / 0.43% ] 2024-03-09T18:52:08.456526771+00:00 DEBUG │ │ ┝━ 🐛 [debug]: | request.base: "ou=people,dc=example,dc=com" | scope: Users 2024-03-09T18:52:08.456528181+00:00 DEBUG │ │ ┕━ get_user_list [ 219µs | 0.02% / 0.24% ] 2024-03-09T18:52:08.456534160+00:00 DEBUG │ │ ┝━ 🐛 [debug]: | filters: AttributeEquality(AttributeName(CaseInsensitiveString("mailalias")), Serialized("\u{12}")) 2024-03-09T18:52:08.456537820+00:00 DEBUG │ │ ┕━ list_users [ 203µs | 0.22% ] filters: Some(AttributeEquality(AttributeName(CaseInsensitiveString("mailalias")), Serialized("\u{12}"))) | _get_groups: false 2024-03-09T18:52:08.457127364+00:00 DEBUG │ │ ┕━ 🐛 [debug]: | return: [] 2024-03-09T18:52:08.457135892+00:00 DEBUG │ ┕━ 🐛 [debug]: | response: SearchResultDone(LdapResult { code: Success, matcheddn: "", message: "", referral: [] }) 2024-03-09T18:52:08.457224011+00:00 INFO ┕━ LDAP request [ 7.48µs | 0.01% ] 2024-03-09T18:52:08.457227565+00:00 DEBUG ┕━ 🐛 [debug]: | msg: LdapMsg { msgid: 3, op: UnbindRequest, ctrl: [] } ``` I am using `lldap:latest` via Docker.
kerem 2026-02-27 08:16:34 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@ghtyrant commented on GitHub (Mar 10, 2024):

After some digging I guess this is related to https://github.com/lldap/lldap/issues/763, with the conclusion that this is simply unsupported.

Is there any way to implement something like mail alias lookup any other ways? Postfix is the last service I'd have to migrate to LLDAP to finally get rid of OpenLDAP.

<!-- gh-comment-id:1987303088 --> @ghtyrant commented on GitHub (Mar 10, 2024): After some digging I guess this is related to https://github.com/lldap/lldap/issues/763, with the conclusion that this is simply unsupported. Is there any way to implement something like mail alias lookup any other ways? Postfix is the last service I'd have to migrate to LLDAP to finally get rid of OpenLDAP.
Author
Owner

@nitnelave commented on GitHub (Mar 10, 2024):

I don't think this is #763, you're not doing a substring query but an equality query, which should be supported.

This looks like a genuine bug, and I'm suspicious of the serialized representation. I'll need to have a look.

<!-- gh-comment-id:1987338430 --> @nitnelave commented on GitHub (Mar 10, 2024): I don't think this is #763, you're not doing a substring query but an equality query, which should be supported. This looks like a genuine bug, and I'm suspicious of the serialized representation. I'll need to have a look.
Author
Owner

@ghtyrant commented on GitHub (Mar 11, 2024):

Happy to hear that it's "just" a bug 😊 Let me know if I can help in any way.

<!-- gh-comment-id:1987888758 --> @ghtyrant commented on GitHub (Mar 11, 2024): Happy to hear that it's "just" a bug 😊 Let me know if I can help in any way.
Author
Owner

@nitnelave commented on GitHub (Mar 12, 2024):

oh, nevermind, I thought it was about an attribute substring... No, in this case it is about issue #763 and it's not supported. I don't know how postfix is configured, and how many aliases you have per user, but it could be doable to implement the list "by hand" by adding lots of attributes: mailAlias1, mailAlias2, etc... Then the filter would become (|(mailAlias1={email})(mailAlias2={email})...)

Would that work for you? I know it's not ideal, but that's a workaround that would work now.

<!-- gh-comment-id:1990926740 --> @nitnelave commented on GitHub (Mar 12, 2024): oh, nevermind, I thought it was about an attribute substring... No, in this case it _is_ about issue #763 and it's not supported. I don't know how postfix is configured, and how many aliases you have per user, but it could be doable to implement the list "by hand" by adding lots of attributes: mailAlias1, mailAlias2, etc... Then the filter would become `(|(mailAlias1={email})(mailAlias2={email})...)` Would that work for you? I know it's not ideal, but that's a workaround that would work now.
Author
Owner

@jakob42 commented on GitHub (Mar 12, 2024):

I'm also interested in using lldap with postfix after release. I'll try to cook something up with maybe semicolon delimited lists of emails in a single string... 🤔

<!-- gh-comment-id:1992301741 --> @jakob42 commented on GitHub (Mar 12, 2024): I'm also interested in using lldap with postfix after release. I'll try to cook something up with maybe semicolon delimited lists of emails in a single string... 🤔
Author
Owner

@ghtyrant commented on GitHub (Mar 12, 2024):

Too bad 😞

Your workaround works, of course. Thanks!

<!-- gh-comment-id:1992375870 --> @ghtyrant commented on GitHub (Mar 12, 2024): Too bad 😞 Your workaround works, of course. Thanks!
Author
Owner

@CluelessTechnologist commented on GitHub (Aug 17, 2024):

I'm glad I found this issue, I thought I was going insane when mailalias stopped working as soon as I added more than one alias to it.

I'm using Docker-mailserver with @nitnelave's workaround and it's working fine. Since it's for personal use I don't have much use for more than 10+ mail aliases anyway.

My schema config:

   lldap-cli schema attribute user add mailAlias1 string -l -v
   lldap-cli schema attribute user add mailAlias2 string -l -v
   lldap-cli schema attribute user add mailAlias3 string -l -v
   lldap-cli schema attribute user add mailAlias4 string -l -v
   lldap-cli schema attribute user add mailAlias5 string -l -v
   lldap-cli schema attribute user add mailAlias6 string -l -v
   lldap-cli schema attribute user add mailAlias7 string -l -v
   lldap-cli schema attribute user add mailAlias8 string -l -v
   lldap-cli schema attribute user add mailAlias9 string -l -v
   lldap-cli schema attribute user add mailAlias10 string -l -v

My mailserver config:

LDAP_QUERY_FILTER_ALIAS: (&(objectClass=inetOrgPerson)(|(mailAlias=%s)(mailAlias1=%s)(mailAlias2=%s)(mailAlias3=%s)(mailAlias4=%s)(mailAlias5=%s)(mailAlias6=%s)(mailAlias7=%s)(mailAlias8=%s)(mailAlias9=%s)(mailAlias10=%s)))
LDAP_QUERY_FILTER_DOMAIN: (mail=*@%s)
LDAP_QUERY_FILTER_SENDERS: (&(objectClass=inetOrgPerson)(|(mail=%s)(mailAlias=%s)(mailAlias1=%s)(mailAlias2=%s)(mailAlias3=%s)(mailAlias4=%s)(mailAlias5=%s)(mailAlias6=%s)(mailAlias7=%s)(mailAlias8=%s)(mailAlias9=%s)(mailAlias10=%s)))

Of course it would be nice if lldap supported multiple values in the mailalias field, but from reading https://github.com/lldap/lldap/issues/763, I gather it would be too complex to implement and go against the purpose of the project, a light LDAP implementation.

<!-- gh-comment-id:2294903745 --> @CluelessTechnologist commented on GitHub (Aug 17, 2024): I'm glad I found this issue, I thought I was going insane when mailalias stopped working as soon as I added more than one alias to it. I'm using [Docker-mailserver](https://github.com/lldap/lldap/blob/main/example_configs/mailserver.md) with @nitnelave's workaround and it's working fine. Since it's for personal use I don't have much use for more than 10+ mail aliases anyway. My schema config: ``` lldap-cli schema attribute user add mailAlias1 string -l -v lldap-cli schema attribute user add mailAlias2 string -l -v lldap-cli schema attribute user add mailAlias3 string -l -v lldap-cli schema attribute user add mailAlias4 string -l -v lldap-cli schema attribute user add mailAlias5 string -l -v lldap-cli schema attribute user add mailAlias6 string -l -v lldap-cli schema attribute user add mailAlias7 string -l -v lldap-cli schema attribute user add mailAlias8 string -l -v lldap-cli schema attribute user add mailAlias9 string -l -v lldap-cli schema attribute user add mailAlias10 string -l -v ``` My mailserver config: ``` LDAP_QUERY_FILTER_ALIAS: (&(objectClass=inetOrgPerson)(|(mailAlias=%s)(mailAlias1=%s)(mailAlias2=%s)(mailAlias3=%s)(mailAlias4=%s)(mailAlias5=%s)(mailAlias6=%s)(mailAlias7=%s)(mailAlias8=%s)(mailAlias9=%s)(mailAlias10=%s))) LDAP_QUERY_FILTER_DOMAIN: (mail=*@%s) LDAP_QUERY_FILTER_SENDERS: (&(objectClass=inetOrgPerson)(|(mail=%s)(mailAlias=%s)(mailAlias1=%s)(mailAlias2=%s)(mailAlias3=%s)(mailAlias4=%s)(mailAlias5=%s)(mailAlias6=%s)(mailAlias7=%s)(mailAlias8=%s)(mailAlias9=%s)(mailAlias10=%s))) ``` Of course it would be nice if **lldap** supported multiple values in the mailalias field, but from reading https://github.com/lldap/lldap/issues/763, I gather it would be too complex to implement and go against the purpose of the project, _a light LDAP implementation_.
Author
Owner

@fracklaus commented on GitHub (Mar 9, 2025):

First of all, thank you for developing lldap, which is the best solution I have found to easily manage an ldap server.

However, I also came across this issue when trying to setup my mail server with lldap.
The workaround with multiple alias fields works only partially for me:

  • It works in postfix and dovecot
  • it fails when deploying mail accounts in nextcloud: nextcloud offers to enter one multi-valued field for mail aliases, it is not possible to enter multiple ldap fields.

This means that next to mailalias01 to mailalias10 fields, I also have to enter the aliases in a multi-value field for nextcloud. Since I now have to enter the data twice, the process is cumbersome and errorprone.

@nitnelave Do you have any ideas how this could be solved? When searching in multi-valued fields will not be supported, can we e.g. have an option that a read-only multi-valued field is propagated from multiple sigle-valued fields automatically? E.g, mailAlias = [ mailAlias01, mailAliad02, ..., mailAlias10 ]?

<!-- gh-comment-id:2708737124 --> @fracklaus commented on GitHub (Mar 9, 2025): First of all, thank you for developing lldap, which is the best solution I have found to easily manage an ldap server. However, I also came across this issue when trying to setup my mail server with lldap. The workaround with multiple alias fields works only partially for me: - It works in postfix and dovecot - it fails when deploying mail accounts in nextcloud: nextcloud offers to enter one multi-valued field for mail aliases, it is not possible to enter multiple ldap fields. This means that next to mailalias01 to mailalias10 fields, I also have to enter the aliases in a multi-value field for nextcloud. Since I now have to enter the data twice, the process is cumbersome and errorprone. @nitnelave Do you have any ideas how this could be solved? When searching in multi-valued fields will not be supported, can we e.g. have an option that a read-only multi-valued field is propagated from multiple sigle-valued fields automatically? E.g, mailAlias = [ mailAlias01, mailAliad02, ..., mailAlias10 ]?
Author
Owner

@nitnelave commented on GitHub (Mar 9, 2025):

Well, there are 2 solutions to the problem: the canonical one is actually supporting multi value fields. There's a design proposal for that, but it's a non trivial amount of tricky work and no one to do that right now.

Thankfully, your other idea (to distribute multi-value fields into single-value ones) is going to be feasible soon-ish (weeks, maybe a few months). There's ongoing work to provide a plugin API, and then you can write a simple Lua plugin that would listen to modifications to the multi-value field and distribute that to the single-value ones.

<!-- gh-comment-id:2708771043 --> @nitnelave commented on GitHub (Mar 9, 2025): Well, there are 2 solutions to the problem: the canonical one is actually supporting multi value fields. There's a design proposal for that, but it's a non trivial amount of tricky work and no one to do that right now. Thankfully, your other idea (to distribute multi-value fields into single-value ones) is going to be feasible soon-ish (weeks, maybe a few months). There's ongoing work to provide a plugin API, and then you can write a simple Lua plugin that would listen to modifications to the multi-value field and distribute that to the single-value ones.
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#308
No description provided.