Active Directory with LDAP some thoughts and code
Posted: Fri Sep 05, 2008 5:32 pm
I tried to authenticate against Microsoft Server 2003 AD domain and as I am not a guru either in LDAP or in AD I ended up modifying code to get it work.
I added one new configuration option user_base which is used as starting point for searching user object and added choice of "AD" to the type select.
Then I added a branch that uses ldap_search instead of ldap_read to find the user object when type is AD. I also modified filter to be (&(objectclass=*)(sAMAccountName={$addData['username']})).
I am not the lord of our AD so I have no access to the schema and can not add serendipity_userlevel to it. I found that requesting an attribute that does not exist causes the whole search to fail. I lazily
remedied that by removing the whole attributes thing from the search. After these modifications I was able to log in using my AD account.
Without the serendipity_userlevel attribute the control of who can log in with AD account is controlled only by user_base.
If anyone is interested here are two patch files:
And
I added one new configuration option user_base which is used as starting point for searching user object and added choice of "AD" to the type select.
Then I added a branch that uses ldap_search instead of ldap_read to find the user object when type is AD. I also modified filter to be (&(objectclass=*)(sAMAccountName={$addData['username']})).
I am not the lord of our AD so I have no access to the schema and can not add serendipity_userlevel to it. I found that requesting an attribute that does not exist causes the whole search to fail. I lazily
Without the serendipity_userlevel attribute the control of who can log in with AD account is controlled only by user_base.
If anyone is interested here are two patch files:
Code: Select all
*** serendipity_event_externalauth.php 2008-09-05 16:32:06.000000000 +0300
--- safe/serendipity_event_externalauth.php 2008-09-05 16:13:29.000000000 +0300
***************
*** 37,49 ****
));
$propbag->add('configuration', array('enable_ldap', 'enable_logging',
'host', 'port', 'rdn', 'source', 'userlevel', 'ldap_userlevel_attr',
! 'ldap_tls', 'firstlogin', 'auth_query', 'bind_user', 'bind_password', 'user_wysiwyg'));
$propbag->add('groups', array('BACKEND_USERMANAGEMENT'));
}
function introspect_config_item($name, &$propbag)
{
switch($name) {
case 'enable_ldap':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_EVENT_EXTERNALAUTH_ENABLE_LDAP);
--- 37,56 ----
));
$propbag->add('configuration', array('enable_ldap', 'enable_logging',
'host', 'port', 'rdn', 'source', 'userlevel', 'ldap_userlevel_attr',
! 'ldap_tls', 'firstlogin', 'auth_query', 'bind_user', 'bind_password', 'user_wysiwyg', 'user_base'));
$propbag->add('groups', array('BACKEND_USERMANAGEMENT'));
}
function introspect_config_item($name, &$propbag)
{
switch($name) {
+ case 'user_base':
+ $propbag->add('type','string');
+ $propbag->add('name', PLUGIN_EVENT_EXTERNALAUTH_USERBASE);
+ $propbag->add('description', PLUGIN_EVENT_EXTERNALAUTH_USERBASE_DESC);
+ $propbag->add('default', 'OU=internal,OU=Users,OU=ourcorp,DC=root,DC=local');
+ break;
+
case 'enable_ldap':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_EVENT_EXTERNALAUTH_ENABLE_LDAP);
***************
*** 98,104 ****
$propbag->add('name', PLUGIN_EVENT_EXTERNALAUTH_SOURCE);
$propbag->add('description', PLUGIN_EVENT_EXTERNALAUTH_SOURCE_DESC);
$propbag->add('default', 'LDAP');
! $propbag->add('select_values', array('LDAP' => 'LDAP'));
break;
case 'userlevel':
--- 105,111 ----
$propbag->add('name', PLUGIN_EVENT_EXTERNALAUTH_SOURCE);
$propbag->add('description', PLUGIN_EVENT_EXTERNALAUTH_SOURCE_DESC);
$propbag->add('default', 'LDAP');
! $propbag->add('select_values', array('LDAP' => 'LDAP', 'AD' => 'AD'));
break;
case 'userlevel':
***************
*** 298,315 ****
);
$this->debugmsg('LDAP bind call: ' . $rdn);
if ($valid = @ldap_bind($ds, $rdn, $addData['password'])) {
$srch="(objectclass=*)";
$attributes=array("objectclass","mail",$this->get_config('ldap_userlevel_attr'));
! if ($res = @ldap_read($ds,$rdn,$srch,$attributes)) {
$e = ldap_first_entry($ds,$res);
$attr = ldap_get_attributes($ds,$e);
$userlevel_attr = $this->get_config('ldap_userlevel_attr');
if ($attr[$userlevel_attr] > -1) {
$valid_userlevel = $attr[$userlevel_attr][0];
} else {
$valid_userlevel = $this->get_config('userlevel');
}
! }
}
} else { // LDAP with protected access and messy schema
$password = $addData['password'];
--- 305,338 ----
);
$this->debugmsg('LDAP bind call: ' . $rdn);
if ($valid = @ldap_bind($ds, $rdn, $addData['password'])) {
+ $this->debugmsg('Valid bind');
$srch="(objectclass=*)";
$attributes=array("objectclass","mail",$this->get_config('ldap_userlevel_attr'));
! if($this->get_config('source')=="AD") {
! $user_tree=$this->get_config('user_base');
! $srch="(&(objectclass=*)(sAMAccountName={$addData['username']}))";
! $this->debugmsg("Search $srch");
! $res = @ldap_search($ds,$user_tree,$srch);
! } else {
! $user_tree=$rdn;
! $res = @ldap_read($ds,$user_tree,$srch,$attributes);
! }
! if ($res) {
! $this->debugmsg('Read succeeded');
$e = ldap_first_entry($ds,$res);
$attr = ldap_get_attributes($ds,$e);
+ $this->debugmsg(print_r($attr,true));
$userlevel_attr = $this->get_config('ldap_userlevel_attr');
if ($attr[$userlevel_attr] > -1) {
$valid_userlevel = $attr[$userlevel_attr][0];
} else {
$valid_userlevel = $this->get_config('userlevel');
}
! } else {
! $this->debugmsg('Read failed');
! }
! } else {
! $this->debugmsg('Bind failed');
}
} else { // LDAP with protected access and messy schema
$password = $addData['password'];
Code: Select all
*** lang_en.inc.php 2008-09-05 16:30:40.000000000 +0300
--- safe/lang_en.inc.php 2008-09-05 15:08:50.000000000 +0300
***************
*** 39,41 ****
--- 39,43 ----
@define('PLUGIN_EVENT_EXTERNALAUTH_USER_WYSIWYG', 'Wysiwyg enabled by default?');
@define('PLUGIN_EVENT_EXTERNALAUTH_USER_WYSIWYG_DESC', 'Does new accounts are created with the "Use WYSIWYG editor on" by default?');
+ @define('PLUGIN_EVENT_EXTERNALAUTH_USERBASE','User tree base for AD-authentication.');
+ @define('PLUGIN_EVENT_EXTERNALAUTH_USERBASE_DESC','Where the users are located on your Active Directory.');