Search

Hello,

I'm trying to write a custom event and so far I'm making good progress :-)

However, I've got the following problem:

I want to try binding to an LDAP server using the credentials given by the user and if it fails, display an error message. This is the relevant part of my event trigger code:

$con = ldap_connect($server);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);

// try to bind as a given user
if (ldap_bind($con, $userdn, $password) === false) {
  $result->appendChild(new XMLElement('message', __('Error E104 - Current password is wrong.')));
  return $result;
}

In my php script this works flawlessly, however in Symphony when I submit the form with a wrong password I get a Symphony Warning Page: "Symphony Warning ... ldapbind(): Unable to bind to server: Invalid credentials" instead of my custom error message. Why do I get this? Does ldapbind throw an exception or something like that; should I use a try-catch-clause or how do I fix this?

I'd be glad to get some help.

Regards,
Mark

PS. I'd also like to make sure that this Warning Page never shows up at all because it displays my source code including comments, ldap credentials, etc...

Could you use @ to suppress the warning? I'm guessing here...

Since 2.0.7, Symphony halts on all E_WARNING errors. As of Symphony 2.2, Symphony will raise an E_WARNING as a exception, so you can wrap a try/catch around that line.

It does seem odd, as the php manual seems to suggest that ldap_bind doesn't emit any warnings, but it seems like it most definitely is.

Yeah, a try/catch clause has fixed the problem.

@brendo
That's what I was wondering about, too... the php manual suggests that ldap_bind just returns a true/false and nothing else.

@goldmar - would you mind sharing your code? I assume you are working on an ldap override for the back end users?

I'd be very interested in the LDAP solution as well!

Well, it's nothing that complicated... and it does not have anything to do with Symphony users or backend.

We use LDAP for central authentication service (CAS) and user management of Email (Postfix and Zarafa), our ECM system (Alfresco) and more to come. And since our website is based on Symphony CMS I've decided to code a simple Symphony event that makes it possible to change the User Password in LDAP.

If anybody is still interested, post a quick reply and I'll share the event code.

I'm still interested. :-)

Here you go :-)

Also, as a disclaimer, please note that I did not write it from scratch but instead used this code from www.warden.pl as a template.

<?php

require_once(TOOLKIT . '/class.event.php');

Class eventchange_password extends Event{

    const ROOTELEMENT = 'change-password';

    public static function about(){
        return array(
                 'name' => 'Change Password',
                 'author' => array(
                        'name' => 'Mark Goldenstein',
                        'website' => 'http://www.leweba.de/',
                        'email' => 'nospam@hotmail.com'),
                 'version' => '1.0',
                 'release-date' => '2011-02-09T16:18:45+00:00',
                 'trigger-condition' => 'action[change-password]'); 
    }

    public static function allowEditorToParse(){
        return false;
    }

    public function load(){
        if(isset($_POST['action']['change-password'])) return $this->__trigger();
    }

    public static function documentation(){
        return new XMLElement('p', 'This is an event that makes it possible to change an LDAP password.');
    }

    protected function __trigger(){
        $result = new XMLElement('change-password');
        $result->setAttribute('result', 'error');

        $user = $_POST['user'];
        $oldPassword = $_POST['oldPassword'];
        $newPassword = $_POST['newPassword'];
        $newPasswordCnf = $_POST['newPasswordCnf'];

        $post_values = new XMLElement('post-values');
        $post_values->appendChild(new XMLElement('user', $user));
        $post_values->appendChild(new XMLElement('oldPassword', $oldPassword));
        $result->appendChild($post_values);

        $server = "localhost";
        $dn = "ou=Users,dc=yourcompany,dc=com";
        $proxyuser = "YOUR USER";
        $proxypass = "YOUR PASSWORD";
        $webmaster = "youremail@yourhost.com";

        $con = ldap_connect($server);
        ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);

        $findWhat = array ("cn","mail");
        $findWhere = $dn;
        $findFilter = "(uid=$user)";

        // bind as proxyuser and find user by uid
        try {
            ldap_bind($con, $proxyuser, $proxypass);
        } catch (Exception $e) {
            $result->appendChild(new XMLElement('message', 'Please contact the system administrator.'));
            return $result;
        }

        $sr = ldap_search($con,$dn,$findFilter,$findWhat);
        $records = ldap_get_entries($con, $sr);
        // error if found more than one user
        if ($records["count"] != "1") {
            $result->appendChild(new XMLElement('message', 'Wrong credentials.'));
            return $result;
        } else {
            // $result->appendChild(new XMLElement('message', 'Found user <strong>'.$records[0]["cn"][0].'</strong>.'));
        }

        // try to bind as that user
        try {
            ldap_bind($con, $records[0]["dn"], $oldPassword);
        } catch (Exception $e) {
            $result->appendChild(new XMLElement('message', 'Wrong credentials.'));
            return $result;
        }

        if ($newPassword != $newPasswordCnf ) {
            $result->appendChild(new XMLElement('message', 'Your new passwords don't match!'));
            return $result;
        }
        if (strlen($newPassword) < 8 ) {
            $result->appendChild(new XMLElement('message', 'Your new password is too short!'));
            return $result;
        }
        if (!preg_match("/[0-9]/",$newPassword)) {
            $result->appendChild(new XMLElement('message', 'Your new password must contain at least one digit.'));
            return $result;
        }
        if (!preg_match("/[a-zA-Z]/",$newPassword)) {
            $result->appendChild(new XMLElement('message', 'Your new password must contain at least one letter.'));
            return $result;
        }

        // change the password finally
        $entry = array();
        $entry["userPassword"] = "{SHA}".base64_encode(pack("H*",sha1($newPassword)));
        if (ldap_modify($con,$records[0]["dn"],$entry) === false){
            $result->appendChild(new XMLElement('message', 'Your password cannot be changed. Please contact the system administrator.'));
        }
        else {
            $result->setAttribute('result', 'success');
            $result->appendChild(new XMLElement('message', 'Your password has been successfully changed.'));
            mail($records[0]["mail"][0],"Password Change Notification: ".$user,"Your LDAP password has just been changed.");
            mail($webmaster,"Password Change Notification: ".$user,"The password of user ".$user." has just been changed.");
        }

        return $result;
    }       

}

And here is the corresponding template:

    <form id="contact" action="" method="post">
      <xsl:for-each select="events/change-password">
        <p class="{@result}">
          <xsl:copy-of select="message/node()"/>
        </p>
      </xsl:for-each>
      <fieldset>
        <div id="formheader">
          <label class="required">Username <input type="text" name="user" value="{events/change-password/post-values/user}" /></label>
          <label class="required">Old password <input type="password" name="oldPassword" value="{events/change-password/post-values/oldPassword}" /></label>
          <label class="required">New password <input type="password" name="newPassword" value="" /></label>
          <label class="required">New password (repeat) <input type="password" name="newPasswordCnf" value="" /></label>
        </div>
        <input id="submit" type="submit" name="action[change-password]" value="Submit" />
      </fieldset>
    </form>

Thanks for sharing, @goldmar. I'm looking forward to trying this out.

Hello, is there some news about testing with LDAP ???

I need it for Symphony user in frontend to make login to our company Windows AD server. Is it possible with this LDAP code(of course with some chnages) and template ???

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details