Bug Report
Component: pkg/utils/ldap — getUserAttributeFilter
Affected version: reva v2.43.0 (shipped with OpenCloud v6.1.0)
Priority: High — blocks user authentication with external read-only LDAP
Description
When OpenCloud performs a user lookup via GetUserByClaim with claim "uid",
the function getUserAttributeFilter incorrectly maps the logical attribute
"uid" to i.User.Schema.UIDNumber (a numeric POSIX attribute) instead of
i.User.Schema.Username (the string uid attribute).
This causes LDAP filters like (uidNumber=jdoe) to be generated instead of
the correct (uid=jdoe), resulting in failed user lookups for all users on
external LDAP setups using the standard inetOrgPerson/person schema.
Confirmed via trace log
DBG LDAP Search
filter=(&(&(objectClass=person)(memberOf=cn=users,ou=groups,dc=example,dc=com))
(objectclass=inetOrgPerson)(uidNumber=jdoe))
line=pkg/utils/ldap/identity.go:265
service=users
DBG GetUserByClaim
error="error: not found:
(&(&(objectClass=person)(memberOf=cn=users,ou=groups,dc=example,dc=com))
(objectclass=inetOrgPerson)(uidNumber=jdoe))"
line=pkg/user/manager/ldap/ldap.go:156
service=users
The filter (uidNumber=jdoe) is clearly wrong — uidNumber is a numeric
POSIX attribute and jdoe is a string username. The correct filter must be
(uid=jdoe).
Root Cause
Bug 1 — Wrong attribute mapping in pkg/utils/ldap/ldap.go:
// BUGGY (~line 432)
func (i *Identity) getUserAttributeFilter(attribute, value, tenantID string) (string, error) {
switch attribute {
case "uid":
attribute = i.User.Schema.UIDNumber // ← WRONG: numeric POSIX attribute
...
Should be:
case "uid":
attribute = i.User.Schema.Username // ← CORRECT: string uid attribute
Bug 2 — Wrong value escaping for non-UUID attributes, directly below the switch:
// This treats every attribute value as a UUID — wrong for mail, uid, username
value, err := filterEscapeAttribute(i.User.Schema.ID, i.User.Schema.IDIsOctetString, value)
UUID parsing should only apply for case "userid" when IDIsOctetString is
true. For all other cases plain ldap.EscapeFilter(value) is correct.
Configuration (external read-only LDAP)
OC_LDAP_URI=ldap://192.168.x.x:3890
OC_LDAP_SERVER_WRITE_ENABLED=false
OC_LDAP_USER_BASE_DN=ou=people,dc=example,dc=com
OC_LDAP_USER_OBJECTCLASS=person
OC_LDAP_USER_FILTER='(&(objectClass=person)(memberOf=cn=users,ou=groups,dc=example,dc=com))'
OC_LDAP_USER_SCHEMA_ID=entryuuid
OC_LDAP_DISABLE_USER_MECHANISM=none
# OC_LDAP_USER_SCHEMA_USERNAME not set → defaults to "uid" ✓
This is the standard setup described in the OpenCloud documentation for
connecting an external read-only LDAP server. The bug affects all deployments
using this recommended configuration.
Impact
- User authentication fails completely for all users
- No workaround available via environment variables
(UIDNumber is not configurable via env)
- Affects any external LDAP with
inetOrgPerson/person schema
where uidNumber is not populated
Missing Test Coverage
getUserAttributeFilter has no unit tests. The existing ldap_test.go only
covers getUserFindFilter. Suggested additions:
{"uid lookup", "uid", "jdoe", "(&...(uid=jdoe)...)"},
{"mail lookup", "mail", "jdoe@example.com", "(&...(mail=jdoe@example.com)...)"},
{"username lookup", "username","jdoe", "(&...(uid=jdoe)...)"},
{"invalid field", "invalid", "jdoe", error},
These tests would have caught both bugs at introduction.
References
/cc @rhafer
Bug Report
Component:
pkg/utils/ldap—getUserAttributeFilterAffected version: reva v2.43.0 (shipped with OpenCloud v6.1.0)
Priority: High — blocks user authentication with external read-only LDAP
Description
When OpenCloud performs a user lookup via
GetUserByClaimwith claim"uid",the function
getUserAttributeFilterincorrectly maps the logical attribute"uid"toi.User.Schema.UIDNumber(a numeric POSIX attribute) instead ofi.User.Schema.Username(the string uid attribute).This causes LDAP filters like
(uidNumber=jdoe)to be generated instead ofthe correct
(uid=jdoe), resulting in failed user lookups for all users onexternal LDAP setups using the standard
inetOrgPerson/personschema.Confirmed via trace log
The filter
(uidNumber=jdoe)is clearly wrong —uidNumberis a numericPOSIX attribute and
jdoeis a string username. The correct filter must be(uid=jdoe).Root Cause
Bug 1 — Wrong attribute mapping in
pkg/utils/ldap/ldap.go:Should be:
Bug 2 — Wrong value escaping for non-UUID attributes, directly below the switch:
UUID parsing should only apply for
case "userid"whenIDIsOctetStringistrue. For all other cases plain
ldap.EscapeFilter(value)is correct.Configuration (external read-only LDAP)
This is the standard setup described in the OpenCloud documentation for
connecting an external read-only LDAP server. The bug affects all deployments
using this recommended configuration.
Impact
(
UIDNumberis not configurable via env)inetOrgPerson/personschemawhere
uidNumberis not populatedMissing Test Coverage
getUserAttributeFilterhas no unit tests. The existingldap_test.goonlycovers
getUserFindFilter. Suggested additions:{"uid lookup", "uid", "jdoe", "(&...(uid=jdoe)...)"}, {"mail lookup", "mail", "jdoe@example.com", "(&...(mail=jdoe@example.com)...)"}, {"username lookup", "username","jdoe", "(&...(uid=jdoe)...)"}, {"invalid field", "invalid", "jdoe", error},These tests would have caught both bugs at introduction.
References
pkg/utils/ldap/ldap.go—getUserAttributeFilter(~line 430)pkg/utils/ldap/ldap_test.go— missing coverage/cc @rhafer