| Project: | Lightweight Directory Access Protocol |
| Version: | 7.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | johnbarclay |
| Status: | closed (fixed) |
Issue Summary
I was unable to get the ldap_authorization module to work. After looking at a wireshark trace I found that when Binding Method is set to "Service Account Bind", all of the ldap_authorization searches are performed in with the security context of the authenticated user, NOT as the Service Account -- which was what I expected. The result is that ldap authenticated users MUST have read access to all the objects (in my case the member attribute of groups).
In my case the directory administrator has the policy of not granting users access to see all group members. He is willing to grant read access to the "drupal" service account. However, with the current code (7.x-1.x-dev), it is not possible for the ldap searches to be sent as the "drupal" service account -- only as the ldap authenticated user.
The core problem appears to be the fact that the of the same ldap_server object for the authentication (ldap_authenticate.inc:333) as is used for general lookups (ldap_authorization.inc:143, 391, etc).
My wireshark trace verifies that when my "Service Bind Account" config, the ldap server will recieve the following ldap messages ALL ON THE SAME LDAP CONECTION:
1. bindRequest(name: cn=drupal,dc=example,dc=com)
2. searchRequest(baseObject: ou=users,dc=example,dc=com, filter: (cn=bob))
3. bindRequest(name: cn=bob,ou=users,dc=example,dc=com) <== ldap_authenticate.inc:333. Note that from this point on all searches on this connection from "bob", not from "drupal"
4. searchRequest(baseObject: ou=users,dc=example,dc=com, filter: (cn=bob)) <== ldap_authorization.inc:143. Not sure why you need to do this again since it's exactly the same as #2 (above)
5. Several search requests looking to find (member='cn=bob,ou=users,dc=example,dc=com') in groups. <== code block starting on ldap_authorization.inc:387
In my case all authorization searches in step 5 fail because "bob" does not have read access to read group members. The drupal user does.
Conclusion: Bug. Descriptions for "Service Account Binding" lead user to believe that the configured service account (not the user's account) will be used for LDAP activities. A desireable configuration, but not working for authorization services.
Server and LDAP Module
| OK | SERVER_SOFTWARE | Microsoft-IIS/7.5 |
| OK | PHP version | 5.2.17 |
| OK | PHP ldap extension data | LDAP Support: enabled RCS Version: $Id: ldap.c 293036 2010-01-03 09:23:27Z sebastian $ Total Links: 0/unlimited API Version: 2004 Vendor Name: OpenLDAP Vendor Version: 0 |
| OK | mcrypt extension loaded | no |
| OK | open ssl extension loaded | yes |
| OK | Drupal | 7.8 |
| OK | ldap_servers | status: 1, schema_version: 7101, v: 7.x-1.0-beta5+33-dev |
| OK | ldap_authentication | status: 1, schema_version: 7100, v: 7.x-1.0-beta5+33-dev |
| OK | ldap_authorization | status: 1, schema_version: 7102, v: 7.x-1.0-beta5+33-dev |
User Settings
| OK | Who can register accounts? | Visitors, but administrator approval is required |
General Settings
| OK | ssl required | 0 |
| OK | encryption | Not available. |
Server: ADLDS Directory
| OK | sid | 192.168.100.183 |
| OK | name | ADLDS Directory |
| OK | status | 1 |
| OK | ldap_type | ad |
| OK | address | 192.168.100.183 |
| OK | port | 389 |
| OK | tls | 0 |
| OK | bind_method | 1 |
| OK | basedn | Array ( [0] => ou=users,dc=example,dc=com ) |
| OK | binddn | cn=drupal,ou=users,dc=example,dc=com |
| OK | user_dn_expression | |
| OK | user_attr | cn |
| OK | mail_attr | |
| OK | mail_template | |
| OK | unique_persistent_attr | |
| OK | allow_conflicting_drupal_accts | 0 |
| OK | ldapToDrupalUserPhp | |
| OK | testingDrupalUsername | |
| OK | ldaps in address | n |
| OK | binddn present | yes |
| OK | basedn count | 1 |
LDAP Authentication Settings
| OK | authenticationMode | Mixed mode. Drupal authentication is tried first. On failure, LDAP authentication is performed. |
| OK | allowOnlyIfTextInDn | empty |
| OK | excludeIfTextInDn | empty |
| OK | allowTestPhp | empty |
| OK | loginConflictResolve | Associate local account with the LDAP entry. This option is useful for creating accounts and assigning roles before an ldap user authenticates. |
| OK | acctCreation | Create accounts automatically for ldap authenticated users. Account creation settings at /admin/config/people/accounts/settings will only affect non-ldap authenticated accounts. |
LDAP Authorization Mapping
| OK | consumer_type | drupal_role |
| OK | status | y |
| OK | only_ldap_authenticated | y |
| OK | derive_from_dn | n |
| OK | derive_from_dn_attr | |
| OK | derive_from_attr | n |
| OK | derive_from_entry | y |
| OK | derive_from_entry_attr | member |
| OK | synchronization_modes | user_logon |
| OK | synchronization_actions | revoke_ldap_provisioned, create_consumers, regrant_ldap_provisioned |
| OK | mappings | mappings present |
Comments
#1
Thanks for catching this and the detailed trace and notes. Its very helpful. Bumped this up to critical because ldap authorization will simply not work on some ldaps with this behavior. If this is the case, this is a big problem. I'll look into this first chance I get. A patch is also welcome.
#2
thanks again for the detailed tracing. I committed the attached patch. Since the server array is static, the connection and binding were retained in the server object. I added some code to unbind if the authentication type was an anonymous user or service account.
Can you give this a try and confirm this solves the problem?
#3
#4
Automatically closed -- issue fixed for 2 weeks with no activity.