You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug: auth-basic with Active Directory produces byte-swapped objectGUID as opaque_id, causing GetUserGroups to fail
Describe the bug
When authenticating via WebDAV using Basic Auth against an Active Directory LDAP backend, the auth-basic service successfully finds and binds the user by sAMAccountName, but then fails at the GetUserGroups step with grpc getting user groups failed: 'error getting user groups', resulting in error code 15 (UNAUTHENTICATED).
The root cause is a byte order mismatch in how auth-basic constructs the user's opaque_id from the raw AD objectGUID bytes after a successful LDAP bind. The endianness fix introduced in #1901 (for the OIDC/web login path) does not appear to be applied in the auth-basic code path.
Steps to reproduce
Configure OpenCloud with an external Active Directory as LDAP backend and external Keycloak as OIDC IDP, using objectGUID as the user ID attribute (OC_LDAP_USER_SCHEMA_ID=objectGUID, OC_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING=true).
Verify that web UI login via Keycloak OIDC works correctly.
Attempt to authenticate a WebDAV connection from an external client (e.g. Windows) using the AD username and password via Basic Auth.
Expected behavior
Basic Auth with a valid AD username and password should authenticate successfully, allowing WebDAV access from external clients.
Actual behavior
auth-basic finds the user in AD by sAMAccountName and the LDAP bind succeeds, but the subsequent GetUserGroups call fails with not found. Authentication is rejected with code 15.
The root cause is that auth-basic constructs the user's opaque_id from the raw AD objectGUID bytes without applying the little-endian to UUID string conversion that AD requires for the first three UUID segments. This produces a byte-swapped opaque_id.
Example: A user whose objectGUID is correctly expressed as ba94e17e-da1a-44ba-a365-2c02a825d886 gets assigned the opaque_id 7ee194ba-1ada-ba44-a365-2c02a825d886 (byte-swapped). The GetUserGroups call then searches LDAP using this wrong ID and returns not found.
Relevant log sequence:
# auth-basic finds and binds the user successfully
{"service":"auth-basic","filter":"(&(objectclass=person)(|(sAMAccountName=<username>)))","message":"LDAP Search"}
# GetUserGroups is called with the byte-swapped opaque_id
{"service":"users","filter":"(&(objectclass=person)(objectGUID=\\ba\\94\\e1\\7e\\da\\1a\\44\\ba\\a3\\65\\2c\\02\\a8\\25\\d8\\86))","message":"LDAP Search"}
# Lookup fails because the opaque_id used is byte-swapped
{"service":"users","error":"error: not found: (&(objectclass=person)(objectGUID=\\ba\\94\\e1\\7e...))","userid":{"opaque_id":"7ee194ba-1ada-ba44-a365-2c02a825d886"},"message":"Failed to lookup user"}
# Final failure
{"service":"auth-basic","error":"ldap: grpc getting user groups failed: 'error getting user groups'","message":"authsvc: error in Authenticate"}
{"service":"proxy","error":"could not authenticate with username and password user: <username>, got code: 15","message":"failed to authenticate request"}
Setup
OpenCloud 7.0.0 rolling (2026-05-21), deployed via Docker Compose with external Active Directory (Windows Server) and Keycloak 26.6.0 as OIDC IDP.
WebDAV Basic Auth fails — the same endianness fix is not applied when auth-basic constructs the opaque_id from the raw objectGUID bytes after a successful LDAP bind.
The Keycloak token contains the correct UUID string (e.g. ba94e17e-da1a-44ba-a365-2c02a825d886), while auth-basic produces a byte-swapped opaque_id (e.g. 7ee194ba-1ada-ba44-a365-2c02a825d886). These are the same objectGUID with the first three segments' bytes reversed, which is the classic Windows AD little-endian encoding issue.
No workaround has been found that does not require either patching reva or restructuring the entire user ID scheme away from objectGUID.
A secondary issue exists where auth-app always calls GetUserByClaim(claim="username") regardless of the AUTH_APP_CS3_CLAIM=userid setting, causing app token authentication to also fail — but that is a separate bug.
Bug:
auth-basicwith Active Directory produces byte-swapped objectGUID as opaque_id, causingGetUserGroupsto failDescribe the bug
When authenticating via WebDAV using Basic Auth against an Active Directory LDAP backend, the
auth-basicservice successfully finds and binds the user bysAMAccountName, but then fails at theGetUserGroupsstep withgrpc getting user groups failed: 'error getting user groups', resulting in error code 15 (UNAUTHENTICATED).The root cause is a byte order mismatch in how
auth-basicconstructs the user'sopaque_idfrom the raw ADobjectGUIDbytes after a successful LDAP bind. The endianness fix introduced in #1901 (for the OIDC/web login path) does not appear to be applied in theauth-basiccode path.Steps to reproduce
objectGUIDas the user ID attribute (OC_LDAP_USER_SCHEMA_ID=objectGUID,OC_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING=true).Expected behavior
Basic Auth with a valid AD username and password should authenticate successfully, allowing WebDAV access from external clients.
Actual behavior
auth-basicfinds the user in AD bysAMAccountNameand the LDAP bind succeeds, but the subsequentGetUserGroupscall fails withnot found. Authentication is rejected with code 15.The root cause is that
auth-basicconstructs the user'sopaque_idfrom the raw ADobjectGUIDbytes without applying the little-endian to UUID string conversion that AD requires for the first three UUID segments. This produces a byte-swappedopaque_id.Example: A user whose
objectGUIDis correctly expressed asba94e17e-da1a-44ba-a365-2c02a825d886gets assigned the opaque_id7ee194ba-1ada-ba44-a365-2c02a825d886(byte-swapped). TheGetUserGroupscall then searches LDAP using this wrong ID and returnsnot found.Relevant log sequence:
Setup
OpenCloud 7.0.0 rolling (2026-05-21), deployed via Docker Compose with external Active Directory (Windows Server) and Keycloak 26.6.0 as OIDC IDP.
Details
Additional context
auth-basicconstructs theopaque_idfrom the rawobjectGUIDbytes after a successful LDAP bind.ba94e17e-da1a-44ba-a365-2c02a825d886), whileauth-basicproduces a byte-swappedopaque_id(e.g.7ee194ba-1ada-ba44-a365-2c02a825d886). These are the same objectGUID with the first three segments' bytes reversed, which is the classic Windows AD little-endian encoding issue.objectGUID.auth-appalways callsGetUserByClaim(claim="username")regardless of theAUTH_APP_CS3_CLAIM=useridsetting, causing app token authentication to also fail — but that is a separate bug.