I'm using this module for a current project and need to be able to provide an interface where users can change their passwords on an Active Directory install.

To this end, I've added a one-off function for modifying a user's password and another for modifying other attributes.

My patch doesn't include any code that adds stuff to the interface that uses these functions, I just have them there for my own purposes and am calling these functions in some custom code in my project. I know that the LdapServer class is a temporary thing, but I figured I should post my changes here in case the code might be useful elsewhere later, though it would be nice to have these functions in the class while it's there. I've tested my function for changing the password against an Active Directory installation on Windows Server 2003, but nothing else. The patch is taken against the 7.x-1.x branch.

I'd suggest just leaving them as functions rather than adding functionality to the interface that supports modifying user attributes and passwords, leaving it to other developers to call these functions as they need them in their projects. Otherwise, this issue queue might get swamped with a bunch of support requests saying they've enabled the features for modifying attributes and passwords but can't get it to work because they don't know how to properly configure their OS's ldap client settings or their LDAP server.

CommentFileSizeAuthor
LdapServer.class_.php_.diff1.35 KBankur

Comments

johnbarclay’s picture

Assigned: Unassigned » johnbarclay

thanks. Completely agree about such functions here for the short term. If nothing else, you won't have to maintain a patch on your server.

I'm doing as you suggested and adding it to the ldap server base class. I'm leaving it marked as needs review so others will give feedback. I will put this out with unstable6 when I switch over to git.

johnbarclay’s picture

I ended up adding these to the ldap_servers.functions.inc file and added an $ldap_server parameter as an argument. Hope this works for you.


/**
  * Modify an LDAP Entry
  */
  function ldap_user_modify($userdn, $attributes, $ldap_server) {
    $status = ldap_modify($ldap_server->connection, $userdn, $attributes);
    if (!$status) {
      watchdog(
        'ldap_servers',
        'Error: user_modify() failed to modify ldap entry w/ base DN "!dn" with values: !values',
        array('!dn' => $userdn, '!value' => var_export($attributes, TRUE)),
        WATCHDOG_ERROR
      );
    }

    return $status;
  }

  /**
   * Modify a password
   */
  function ldap_password_modify($userdn, $new_password, $ldap_server) {

    $new_password = "\"" . $new_password . "\"";
    $len = strlen($new_password);
    $new_pass = NULL;
    for ($i = 0; $i < $len; $i++) {
      $new_pass .= "{$new_password{$i}}\000";
    }

    $status = ldap_mod_replace($ldap_server->connection, $userdn, array('unicodePwd' => $new_pass));
    if (!$status) {
      watchdog(
        'ldap_servers',
        'Error: password_modify() failed to modify ldap password w/ base DN "!dn"',
        array('!dn' => $userdn),
        WATCHDOG_ERROR
      );
    }

    return $status;
  }

ankur’s picture

Status: Needs review » Needs work

Hi johnbarclay,

I gave these a try and get errors.

These utility functions attempt to use the server object's "connection" attribute in the LdapServer class, where it is declared as a "protected" attribute. I'm not sure if it is better to just implement a get function for a server object's connection, make the attribute public, or to just implement these functions as methods of the LdapServer class.

johnbarclay’s picture

Status: Needs work » Needs review

OK. I made the $connection property public and pushed it to head. Please let me know if this solves your problem. I'm leaving this as needs review even though it is committed in case there is additional feedback.

johnbarclay’s picture

Title: add functions for modifying ldap user entries and passwords » LDAP Server: add functions for modifying ldap user entries and passwords
ankur’s picture

These look to be working now.

There's only one last detail that might need to be revisited: currently, these functions only work if you have called ->connect() and ->bind() on the LdapServer objects that you are passing to these functions. Should these utility functions automatically call those class methods or should the caller of these utility functions be required to do that themselves before passing the LdapServer object to these utility functions? Failure to connect and bind will result in a cryptic segmentation fault.

I'm fine either way, but I'm thinking that somewhere in the file comments or API documentation, someone calling these functions will need to know about the connect() and bind() methods in the LdapSever class.

Depending on your opinion, I can submit a patch that does either, or I can add some kind of error handling that results in an error being logged and a message more useful than the typical PHP error message for a segmentation fault.

Thanks for putting these functions in BTW.

johnbarclay’s picture

A patch for some notes, automatic binding, and better error messaging would be greatly appreciated.

Automatic binding and connecting should depend on the binding method the server has selected:

$server->bind_method = LDAP_SERVERS_BIND_METHOD_USER

$server->bind_method = LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT
$server->bind_method = LDAP_SERVERS_BIND_METHOD_ANON
$server->bind_method = LDAP_SERVERS_BIND_METHOD_ANON_USER

With the last 3 I don't see any reason not to bind and connect automatically. The first one will need to throw an error first because it will be unpredicatable what an anonymous bind will do.

For all 4 a good watchdog error when it fails is good and an obscure one for the user that lets them know the details are in the logs.

johnbarclay’s picture

Status: Needs review » Needs work
ankur’s picture

Assigned: johnbarclay » ankur

At some point, I plan on doing this. However, if anyone else needs this more urgently, feel free to roll a patch.

Anisorf’s picture

Hi,
I also need this kind of functionality but in a more general way, i have to make modification on my LDAP server but on almost all attributes (even custom ones). Unfortunately i do not have the knowledge to help on this, but i must do it so i must learn how to.I wanted to know is there a plan to add this kind of functionality to LDAP module? and if yes, when more or less it'll be ready?.
Thanks in advance.

johnbarclay’s picture

I don't think there are any specific plans or commitment on this, but I think there are some modules floating around to do some of this:

Here are some notes:

#167304: A great use of form real estate but how!!

I would search around the sandbox for "ldap" to see some of the sandbox modules for this.

Writing a feeds processor that targets ldap entries would seem like the ideal method. Then any other ldap fetcher could be used to get the data to the ldap.

Anisorf’s picture

Thanks johnbarclay for your replay.
I was reading the feeds doc, and it seems to me that i can use feeds to read the data from ldap but i do not see the way to write data to ldap, pls correct me if i'm wrong...My site should be able to query ldap and than modify some of the values of the ldap attributes.
I found this for D6 http://drupal.org/project/ldapcm, i'll see what is better to try to make a custom submodule able to modify entries using the php ldap functions or to try to adapt the ldapcm module.
Any suggestion will be more than appreciate.
Thanks in advance.

johnbarclay’s picture

Another approach would be to write an ldap processor for feeds. Thus the chain would be:

ldap query fetcher (already written)
ldap parser (already written)
ldap entry processor (you would write this module).

The advantage of this over writing a separate submodule would be:
- leverage all the functionality of feeds (guids, batch, cron, UI, etc.)
- learn about feeds. Its quite handy for a lot of tasks.
- others can use the entry processor and help refine it.

Anisorf’s picture

Thanks again johnbarclay, you are on great help to me, now i look much better to the feeds api.

johnbarclay’s picture

for simpler processor examples, look in the "Processor" section of #856644: Contributed plugin modules for Feeds

johnbarclay’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev
Status: Needs work » Postponed

Don't see this going anywhere until the Drupal 8 version unless some patches are presented.

musicalvegan0’s picture

In reviewing the patch referenced in comment #2, I can find where the function ldap_mod_replace is declared in the the ldap module. Was the adLDAP library removed from the module? If so, re-adding it would be the first step to integrating Active Directory password manipulation, unless, of course, there is a function native to the module that can handle password changing.

Thoughts?

musicalvegan0’s picture

Ugh, nevermind. ldap_mod_replace is provided by the PHP library, not adLDAP. Sorry.

johnbarclay’s picture

Title: LDAP Server: add functions for modifying ldap user entries and passwords » LDAP User: add functions for modifying ldap user entries and passwords
Status: Postponed » Fixed

This feature request is implemented in ldap_user 7.x-2.x-dev. Lets close it and start separate issues for bugs.

Status: Fixed » Closed (fixed)

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