Laconica with active directory and auto-registration

Here is a quick Laconica “how-to” on authenticating accounts with Active directory and then auto-create an account if this is the initial log-in.

Get adLDAP

Download adLDAP and copy adLDAP.php to the /classes folder

Add a file

Create a file named ldapauth.php in the /lib folder and paste the following code into it:

/**
  * Nothing fancy; just authenticate a user and password
  * ... and return some user data
  *
  */
function ldap_user_auth($id, $password)
{

// set the LDAP server values
$ldap_options = common_config('ldap');

// assume failure
$result = false;

if ($id!=NULL){ //prevent null bind
  //include the class and create a connection
  require_once INSTALLDIR.'/classes/adLDAP.php';
  $adldap = new adLDAP($ldap_options);
  if ($password!=NULL) { // this is a login
      if ($adldap->authenticate($id,$password)){
        // get some LDAP info
        $user_info = $adldap->user_info($id,array("sn","givenname","displayname","mail"));

        // find the first and last name
        $last_name = $user_info[0]["sn"][0];
        $first_name = $user_info[0]["givenname"][0];

        // alternate method of finding the first and last name
        $display_name = $user_info[0]["displayname"][0];
        if ($last_name == '' || $first_name == '' ) {
          list($last_name, $first_name) = split(',',$display_name);
        }

        // get the email address
        $email = $user_info[0]["mail"][0];

        // build results
        $result['fullname'] = trim($first_name) . ' ' . trim($last_name);
        $result['email'] = trim($email);
        $result['user'] = strtolower(substr($result['email'], 0, strpos($result['email'], '@')));

      }
  }
}
return $result;
}

Edit config

Add LDAP settings to config.php: supply the appropriate values for your base_dn, domain_controllers. and ad_username and ad_password

$config['ldap']['account_suffix'] = "@domain.com";
$config['ldap']['base_dn'] = "OU=OU,DC=DOMAIN,DC=COM";
$config['ldap']['domain_controllers'] = array ("ldap://dc.domain.com");
$config['ldap']['ad_username'] = 'user';
$config['ldap']['ad_password'] = 'pass';

Patch file

Patch util.php with changes to common_config()

function common_config($main, $sub = false)
{
    global $config;
    if (!$sub){ // allows an array of values; like $config['ldap']
      return isset($config[$main]) ? $config[$main] : false;
    }
    return isset($config[$main][$sub]) ? $config[$main][$sub] : false;
}

Patch util.php with changes to common_check_user()

// check if a username exists and has matching password
function common_check_user($nickname, $password)
{
  // NEVER allow blank passwords, even if they match the DB
  if (mb_strlen($password) == 0) {
  return false;
}

// patch: add check for an LDAP login
require_once INSTALLDIR.'/lib/ldapauth.php';
if ($ldap_auth = ldap_user_auth($nickname, $password)){
  $ldapauth = true;
  $nickname = $ldap_auth['user'];
}
else{
  $ldapauth = $false;
};
//end patch:

$user = User::staticGet('nickname', $nickname);

// patch: add autocreate if user is authenticated via LDAP
//if (is_null($user))
// the line above appears to be a bug: $user is never NULL
// we'll do it this way instead; investigate and fix later
if (!$user){
   if ($ldapauth){
    // auto-register the LDAP user
   if ($user = User::register(array('nickname' => $nickname,
    'password' => 'nopass',
    'email' => $ldap_auth['email'],
    'fullname' => $ldap_auth['fullname'],
    'homepage' => '',
    'bio' => '',
    'location' => '',
    'code' => 'ldap'))) {

     // if user was created then we are good to go
     return $user;
  } else {
    // ?? should have some error message in this case ??
    return false;
  }
}
// end patch

return false;
} else {
  // patch: LDAP authentication
  if ($ldapauth){
  return $user;
}
// end patch

    if (0 == strcmp(common_munge_password($password, $user->id),
      $user->password)) {
      return $user;
    } else {
      return false;
    }
  }
}

This simple hack that assumes that valid LDAP logins want to register. The data is populated from the LDAP account. Note that there seems to be a bug in the Laconica code in that the return value of User::staticGet(‘nickname’, $nickname); is never NULL.

Please post corrections and any suggestions to make this better.

I will also add NTLM auto login in the future.

I did this only to prototype the use of Laconica on our Intranet and would like to see a “pluggable” authentication system to make this type of hack unnecessary.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: