In our D6 LDAP provisioning setup, where we take Drupal accounts and provision them into an LDAP, the account attributes include this set of values:

objectClass: inetOrgPerson
objectClass: posixAccount

Having both seems to be necessary. I've tried replicating this in D7 but I'm being foiled by vague errors (LDAP Error Code 65 most often). One thing I think might be the culprit is not setting up the mapping in the LDAP User config properly, but I've been going around and around on this for a couple days now and can't figure out how to do it. In the "Provisioning From Drupal To LDAP Mappings" table, I've tried various permutations of this. Can someone explain explicitly how you set 3 values for the same token? Generally, I've set:
Source Value Target LDAP Token
--user tokens-- inetOrgPerson => [objectClass]
--user tokens-- posixAccount => [objectClass]

But having 2 elements with the same Target Token just saves the last one, the first two are eliminated. I've tried [objectClass:1] and [objectClass:2] but that also fails. And I've tried one element with the value of "inetOrgPerson,posixAccount" but that also fails.

Using just one setting for an objectClass doesn't seem to work, either. In the debug log from the LDAP server, I get this nugget:

Feb 20 17:00:56 aulv02 slapd[1293]: is_entry_objectclass("uid=mkemp,ou=members,dc=site,dc=org", "2.5.17.0") no objectClass attribute
Feb 20 17:00:56 aulv02 slapd[1293]: No objectClass for entry (uid=mkemp,ou=members,dc=site,dc=org)

Somehow it just seems the "objectClass" is elusive.

Can anyone explain how to do this, and/or see what the data being sent to LDAP is, and/or get more explicit errors from LDAP?

Comments

taquil’s picture

Issue summary: View changes

More info

jitesh doshi’s picture

Same exact problem here. Please help.

+1
+1
+1
...

Paul B’s picture

I think it works if you add a "[.]"

inetOrgPerson[.] => [objectClass:1]
posixAccount[.] => [objectClass:2]

taquil’s picture

Doing it that way fails for me also, showing this error:
Warning: ldap_add(): Value array must have consecutive indices 0, 1, ... in LdapServer->createLdapEntry() (line 416 of /var/www/d7test/sites/all/modules/ldap/ldap_servers/LdapServer.class.php).
LDAP returns an error #32, which means "the target object cannot be found." So I don't think that's the answer. I think you have to go [objectClass:0] then [objectClass:1], not 1 then 2. But even that results in a 65 error, since the objectClass isn't included in the data.

However, I have worked out a rough fix. Down in the LdapServer.class.php file in the function createLdapEntry, where it actually does the LDAP account creation (ldap_add) there is a debug statement that's commented out. Uncommenting it shows the array of data, called $attributes, being passed to LDAP. My LDAP user account schema requires the objectClass of both posixAccount and inetOrgPerson, as well as a gidNumber and a uidNumber. Despite being mapped, they don't show up in the $attributes array. I've removed those values from the LDAP mapping and hard-coded them into the array after the check for $attributes['dn'] being set:

$attributes['objectClass'] = array('inetOrgPerson','posixAccount');
$attributes['gidNumber'] = array(10000);

I added a bit to look up the highest uidNumber in the LDAP ou for my users, then set that value + 1:

{find uidNumbers in use, build an array $uid_numbers, sort}
$attributes['uidNumber'] = array_pop($uid_numbers) + 1;

What's interesting is that the $attributes array is missing any mappings where I'm using the "--user tokens--" source and the values provided include constants (strings, numbers, etc.). For instance, I have a user token field just setting the value of "10000" for the target token [gidNumber] but it's not present in the debug printout of $attributes.

An exception is the target token [displayName] which uses the source value "[field.field_fname] [field.field_lname]" with a space in between. Any user tokens that use only a [field.xxx] or [property.xxx] value are good.

All these values are set to be synced to LDAP on LDAP Entry Creation as well as "On Sync to LDAP" in the mapping table. The createLdapEntry function is called from within the groupAddGroup function, passing in the $attributes array, but that array seems to be put through some modifications from when it's initially passed into that function from somewhere else. Will see if there's an issue on this already.

Anyway, there's a kludge for you.

johnbarclay’s picture

Title: Multiple objectClass Tokens in Drupal->LDAP Provisioning » LDAP User: Multiple objectClass Tokens in Drupal->LDAP Provisioning
Version: 7.x-2.0-beta3 » 7.x-2.x-dev
StatusFileSize
new32.31 KB

attached is a screenshot from the UI. It shows how to deal with this.

jitesh doshi’s picture

Yes, but it doesn't work.

In fact none of the attributes added via "user tokens" ever get passed to the ldap_add call (except "[dn]").

taquil’s picture

StatusFileSize
new138.04 KB
new230.23 KB

I put back the original version of the module and tried that, and it's becoming apparent that the problem isn't necessarily the multiple use targets, but the tokens. Attached are screenshots of my latest mapping setup, and the results when adding a user. The string-only user tokens are omitted from the $attributes array for some reason. As this includes the objectClasses, the whole thing fails. The mailing address fields and such will be added to the user registration form when I build it out.

The LDAP's object inheritance schema seems to go
top -> organizationalPerson -> inetOrgPerson
top -> posixAccount
with both inetOrgPerson and posixAccount being required to create a user.

jitesh doshi’s picture

The observation about string-only user-token values is correct. Meaning to say if the user-token value does not contain any tokens, then the attribute and the value are both discarded. So I fixed it with the following code change in ldap_servers/ldap_servers.tokens.inc ...

 function ldap_servers_token_replace($resource, $text, $resource_type = 'ldap_entry') { // user_account

   $desired_tokens = ldap_servers_token_tokens_needed_for_template($text);
+  if(empty($desired_tokens)) {
+    // if $text contained no tokens, return it as-is.
+    return $text;
+  }

Patch is attached.

johnbarclay’s picture

Status: Active » Needs review

This looks good.

taquil’s picture

Yep, that got it. Thanks for working through all that. Big ups to Jitesh and John.

johnbarclay’s picture

Component: User interface » Code
Category: support » bug
Status: Needs review » Fixed

#7 is committed. The same change needs to be made in the 7.x-1.x token branch. In general there are a lot of places where empty(x) could replace count(x) == 0 in the ldap project.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

correction