Page MenuHomePhabricator

LDAP Authentication
Closed, ResolvedPublic

Assigned To
None
Authored By
bzimport
Nov 1 2004, 4:39 PM
Referenced Files
F1379: LdapAuthentication.php
Nov 21 2014, 7:04 PM
F1378: LdapAuthentication-1.1b.php.diff
Nov 21 2014, 7:04 PM
F1377: ldap_group_support_agains_1.0e.patch
Nov 21 2014, 7:04 PM
F1376: LdapAuthentication.php
Nov 21 2014, 7:04 PM
F1375: changes.8.14.tar.gz
Nov 21 2014, 7:04 PM

Description

Author: ryan.lane

Description:
DefaultSettings.php (add):

$wgUseLDAP = false;
$wgLDAPDomainNames = array("");
$wgLDAPServerNames = array("");
$wgLDAPSearchStrings = array("");
$wgLDAPUseSSL = true;
$wgLDAPUseLocal = false;

Language.php (add):

'yourdomainname' => 'Your LDAP Domain'
'blankpasswordnotallowed' => 'Blank passwords are not allowed.'

includes/User.php (diff -u old new):

  • User.php.new.old 2004-11-01 09:43:28.000000000 -0600

+++ User.php.new 2004-11-01 09:30:39.000000000 -0600
@@ -1010,6 +1010,12 @@

	 */
	function checkPassword( $password ) {
		$this->loadFromDatabase();

+ if ( 0 == strcmp( "", $password ) ) {
+ return false;
+ }
+ if ( $this->checkLDAPPassword( $password ) && 0 !=
strcmp('local', $_SESSION["ldapdomain"]->mDomain ) ) {
+ return true;
+ }

		$ep = $this->encryptPassword( $password );
		if ( 0 == strcmp( $ep, $this->mPassword ) ) {
			return true;

@@ -1025,6 +1031,42 @@

		}
		return false;
	}

-}

+
+ function checkLDAPPassword( $password ) {
+ global $wgLDAPDomainNames, $wgLDAPServerNames,
$wgLDAPSearchStrings;
+ global $wgLDAPUseLocal, $wgLDAPUseSSL;
+
+ if ( $wgLDAPUseSSL ) {
+ $serverpre = "ldaps://";
+ } else {
+ $serverpre = "ldap://";
+ }
+
+ $domain = $_SESSION["ldapdomain"]->mDomain;
+ $tmpservers = $wgLDAPServerNames["$domain"];
+ $tok = strtok($tmpservers, " ");
+ while ($tok) {
+ $servers = $servers . " " . $serverpre . $tok;
+ $tok = strtok(" ");
+ }
+ $servers = rtrim($servers);
+
+ $tmpuserdn = $wgLDAPSearchStrings["$domain"];
+ $userdn = str_replace("USER-NAME",$this->mName,$tmpuserdn);
+ $userpass = $password;
+ $ldapconn = @ldap_connect( $servers );
+ if ( $ldapconn ) {
+ ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
+ $bind = @ldap_bind( $ldapconn, $userdn, $userpass );
+ if (!$bind) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+}
?>

includes/SpecialUserlogin.php (diff -u old new):

  • SpecialUserlogin.php.new.old 2004-11-01 09:57:41.000000000 -0600

+++ SpecialUserlogin.php 2004-11-01 10:02:01.000000000 -0600
@@ -32,11 +32,12 @@
class LoginForm {

	var $mName, $mPassword, $mRetype, $mReturnto, $mCookieCheck, $mPosted;
	var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword;
  • var $mLoginattempt, $mRemember, $mEmail;

+ var $mLoginattempt, $mRemember, $mEmail, $mDomain;

	function LoginForm( &$request ) {
		global $wgLang, $wgAllowRealName;

+ $this->mDomain = $request->getVal( 'wpDomain' );

		$this->mName = $request->getText( 'wpName' );
		$this->mPassword = $request->getText( 'wpPassword' );
		$this->mRetype = $request->getText( 'wpRetype' );

@@ -149,15 +150,18 @@

		global $wgUser, $wgOut;
		global $wgMaxNameChars;
		global $wgMemc, $wgAccountCreationThrottle, $wgDBname, $wgIP;

+ global $wgUseLDAP, $wgLDAPUseLocal;

		if (!$wgUser->isAllowedToCreateAccount()) {
			$this->userNotPrivilegedMessage();
			return;
		}
  • if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
  • $this->mainLoginForm( wfMsg( 'badretype' ) );
  • return;

+ if ( !$wgUseLDAP || 0 == strcmp('local', $this->mDomain ) ) {
+ if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
+ $this->mainLoginForm( wfMsg( 'badretype' ) );
+ return;
+ }

		}
		
		$name = trim( $this->mName );

@@ -194,8 +198,21 @@

			}
		}

+ if ( $wgUseLDAP && 0 != strcmp('local', $this->mDomain ) ) {
+ if (!$u->checkPassword( $this->mPassword )) {
+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ return;
+ }
+ } else {
+ # We shouldn't allow blank passwords, even on
+ # local accounts
+ if ( 0 == strcmp( "", $this-mPassword ) ) {
+ return;
+ }
+ }
+

		$u->addToDatabase();
  • $u->setPassword( $this->mPassword );

+ if ( !$wgUseLDAP ) { $u->setPassword( $this->mPassword ); }

		$u->setEmail( $this->mEmail );
		$u->setRealName( $this->mRealName );

@@ -224,14 +241,16 @@

		}
		$id = $u->idForName();
		if ( 0 == $id ) {
  • $this->mainLoginForm( wfMsg( 'nosuchuser', $u->getName() ) );

+ $this->mainLoginForm( wfMsg( 'nosuchuser', $u->getName()) );

			return;
		}
		$u->setId( $id );
		$u->loadFromDatabase();

+
+ $_SESSION["ldapdomain"] = $this;

		if (!$u->checkPassword( $this->mPassword )) {
  • $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
  • return;

+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ return;

		}

		# We've verified now, update the real record

@@ -351,11 +370,13 @@

	function mainLoginForm( $err ) {
		global $wgUser, $wgOut, $wgLang;
		global $wgDBname, $wgAllowRealName;

+ global $wgUseLDAP, $wgLDAPDomainNames, $wgLDAPUseLocal;

		$le = wfMsg( 'loginerror' );
		$yn = wfMsg( 'yourname' );
		$yp = wfMsg( 'yourpassword' );
		$ypa = wfMsg( 'yourpasswordagain' );

+ $ydn = wfMsg( 'yourdomainname' );

		$rmp = wfMsg( 'remembermypassword' );
		$nuo = wfMsg( 'newusersonly' );
		$li = wfMsg( 'login' );

@@ -392,7 +413,7 @@

			$wgOut->addHTML( "<h2>$li:</h2>\n<p>$lp</p>" );
		} else {
			$wgOut->addHTML( "<h2>$le:</h2>\n<font size='+1'
  • color='red'>$err</font>\n" );

+ color='red'>$err</font>\n" );

		}
		if ( 1 == $wgUser->getOption( 'rememberpassword' ) ) {
			$checked = ' checked';

@@ -413,6 +434,7 @@

		$encRetype = htmlspecialchars( $this->mRetype );
		$encEmail = htmlspecialchars( $this->mEmail );
		$encRealName = htmlspecialchars( $this->mRealName );

+ $encDomain = htmlspecialchars( $this->mDomain );

		if ($wgUser->getID() != 0) {
			$cambutton = "<input tabindex='6' type='submit' name=\"wpCreateaccountMail\"

value=\"{$cam}\" />";
@@ -436,21 +458,44 @@

	<td align='left'>
	<input tabindex='2' type='password' name=\"wpPassword\"

value=\"{$encPassword}\" size='20' />

	</td>
  • <td align='left'>
  • <input tabindex='4' type='checkbox' name=\"wpRemember\" value=\"1\"

id=\"wpRemember\"$checked /><label for=\"wpRemember\">$rmp</label>

  • </td>
  • </tr>");

+ ");
+
+ if ($wgUseLDAP) {
+ foreach ($wgLDAPDomainNames as $dom) {
+ $doms = $doms . "<option>$dom</option>";
+ }
+ if ($wgLDAPUseLocal) {
+ $doms = $doms . "<option>local</option>";
+ }
+ $wgOut->addHTML("<tr><td align='right'>$ydn:</td>
+ <td align='left'>
+ <select tabindex='9' name=\"wpDomain\" value=\"{$encDomain}\">
+ $doms
+ </select>
+ </td></tr>");
+ } else {
+ $wgOut->addHTML("
+ <td align='left'>
+ <input tabindex='4' type='checkbox' name=\"wpRemember\" value=\"1\"
id=\"wpRemember\"$checked /><label for=\"wpRemember\">$rmp</label>
+ </td></tr>");
+ }
+

		if ($wgUser->isAllowedToCreateAccount()) {
			$encRetype = htmlspecialchars( $this->mRetype );
			$encEmail = htmlspecialchars( $this->mEmail );
	$wgOut->addHTML("<tr><td colspan='3'>&nbsp;</td></tr><tr>
  • <td align='right'>$ypa:</td>
  • <td align='left'>
  • <input tabindex='5' type='password' name=\"wpRetype\" value=\"{$encRetype}\"
  • size='20' />
  • </td><td>$nuo</td></tr>
  • <tr>

+ <td align='right'>$nuo</td></tr>");
+
+ if (!$wgUseLDAP || $wgLDAPUseLocal) {
+ $wgOut->addHTML("<td align='right'>$ypa:</td>
+ <td align='left'>
+ <input tabindex='5' type='password' name=\"wpRetype\" value=\"{$encRetype}\"
+ size='20' />
+ </td></tr>");
+ }
+
+ $wgOut->addHTML("<tr>

	<td align='right'>$ye:</td>
	<td align='left'>
	<input tabindex='7' type='text' name=\"wpEmail\" value=\"{$encEmail}\"

size='20' />
@@ -470,16 +515,22 @@

	$cambutton
	</td></tr>");
		}

+
+ $wgOut->addHTML("
+ <tr><td colspan='3'>&nbsp;</td></tr><tr>
+ <td colspan='3' align='left'>
+ <p>$efl<br />");
+
+ if ( !wgUseLDAP) {

		$wgOut->addHTML("
  • <tr><td colspan='3'>&nbsp;</td></tr><tr>
  • <td colspan='3' align='left'>
  • <p>$efl<br />
  • <input tabindex='10' type='submit' name=\"wpMailmypassword\" value=\"{$mmp}\"

/></p>

  • </td></tr></table>
  • </form>\n" );
  • $wgOut->addHTML( $endText );

+ <input tabindex='10' type='submit' name=\"wpMailmypassword\" value=\"{$mmp}\"
/></p>");

	}

+
+ $wgOut->addHTML("
+ </td></tr>
+ </table></form>\n $endText" );
+ }
+

	/**
	 * @access private

@@ -531,3 +582,4 @@

	}

}
?>
+


Version: 1.10.x
Severity: enhancement
URL: http://meta.wikimedia.org/wiki/LDAP_Authentication

Details

Reference
bz814

Related Objects

StatusSubtypeAssignedTask
ResolvedNone
ResolvedNone

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

ryan.lane wrote:

Comment on attachment 787
Patch DefaultSettings and Setup ($wgAuth)

This patch may cause problems, and as such, I'm not recommending it.

slakkie wrote:

Hi,

I am not seeing through anymore, is there now a working solution for LDAP. If so could someone please direct us
to the final files and documentation. As it is a bit mixed up where what is at the moment.

That would be very kind. Thank you!!

Regards
Slakkie

ryan.lane wrote:

(In reply to comment #68)

Hi,

I am not seeing through anymore, is there now a working solution for LDAP. If

so could someone please direct us

to the final files and documentation. As it is a bit mixed up where what is at

the moment.

That would be very kind. Thank you!!

Regards
Slakkie

The "URL" will lead you to the documentation. The current version of this patch
is 1.0a (I haven't obsoleted 1.0 yet because I haven't had the ability to test
1.0a fully, but others have tested it).

Is this in confusion to me obsoleting attachment 787? That was a patch to
"DefaultSettings.php" and "Setup.php", which could have caused problems to some
people.

The current patch is a working solution for authentication, and as a partial
backend to mediawiki. It should fit your needs, if not let me know what is
missing (or submit a patch for what is missing).

jeff wrote:

Patch to 1.0.a for require attribute

This is a restructured version of the first patch submitted to add support for
requiring a user to have a certain attribute to finish authenticating to the
wiki. It now properly handles the case where no proxy user is allowed, nor is
an anonymous search allowed.

Thanks to Marcus Schwartz who suggested this change.

This is a patch against v 1.0a, and only makes changes necessary to implement
the feature. I did move the GroupDN check above retrieve prefs, since I thought
there's no need to get any prefs if the user is not allowed access. This patch
has been tested with openldap and mw 1.5.

Additional parameters for LocalSettings:
Check for this or not:
$wgLDAPRequireAuthAttribute = true;

Look for the attribute/value, for example:
$wgLDAPAuthAttribute = array(
"ldap"=>"businesscategory=wikiuser"
);

Businesscategory is a multivalued attribute in the inetorgperson schema so it's

probably there for you to use already.

Please let me know if you have any issues with the patch, I can send a fully
patched file if necessary.

Jeff

attachment LdapAuth-req-attr.patch ignored as obsolete

ryan.lane wrote:

Version 1.0b of the LdapAuthentication.php Plugin (for Mediawiki 1.5)

Version 1.0b is now the current version of this plugin for Mediawiki 1.5.

This version of the plugin adds in the patch to 1.0a for role based
restriction, fixes a bug in the group based restrictions, and removes some
global variables in functions where they were not being used.

The bug in the group based restrictions could have occured when the wiki was
set up to do straight binds (when not using proxy authentication), and group
based restriction was enabled. The function "isMemberOfLdapGroup" was rebinding
as the proxy agent. To fix this problem, I just removed the rebinding, as
binding was being done before the method was called in the "authenticate"
function. This could be an issue if the user logging into the system is not
allowed to read group information in LDAP, as the last bind done in the
"authenticate" function is as the user logging in. As this is generally not the
case, this should not cause problems.

attachment LdapAuthentication.php ignored as obsolete

ryan.lane wrote:

Version 1.0c of the LdapAuthentication.php Plugin (for Mediawiki 1.5)

Version 1.0c is now the current version of this plugin for Mediawiki 1.5.

This version of the plugin fixes a bug I introduced while testing in 1.0b,
where I accidentally commented something out (would only affect you if you were
using a local domain). It also fixes another bug I introduced in the
"isMemberOfLdapGroup" function. The bug would cause the function not to rebind
as the proxyagent. This was done to fix a bug where the proxyagent would rebind
whether the plugin was set to use straight binds or proxy binds (breaking
straight binds). However, the fix introduced a problem where if the user
binding did not have permissions to read groups, authentication would fail.

This fix still has a problem, but there will be problems no matter how this is
solved. With this fix, if the proxyagent does not have read permissions on
groups, then authentication will also fail. However, it is much better
situation to have the proxyagent try to read, than to have the user binding try
to read, as the proxyagent is more likely to have read access on all of the
directory (as this is generally what proxyagents are for).

So, the fix will cause the proxyagent to rebind in the "isMemberOfLdapGroup"
function if proxy authentication is being used.

attachment LdapAuthentication.php ignored as obsolete

don wrote:

Is the plan for this to eventually be packaged with mediawiki proper?

PS LdapAuthentication 1.0a (and now 1.0c) work just great for me. I use
proxyAgent for binding/searching. Haven't done group member checking yet, but
now we may. Great work!

No, it's a third-party plugin. MediaWiki is designed for public reference sites,
not for corporate intranets, so it's not something we'd be likely to maintain.

kgrinberg wrote:

RE: Ryan's instructions for getting group authentication to work on AD

I spent a lot longer than I should have trying to get it to work as written, but
finally debugged it down to a case-sensitivity issue:

$info[0]["distinguishedName"][0];
should be
$info[0]["distinguishedname"][0];

I'm not sure if it's just my setup (PHP 5.0.5 on Windows, authenticating against
a 2003 AD), or something more general, but making the array key names lowercase
seems like a safer bet.

Also, is there any reason not to move the "if ($wgLDAPRetrievePrefs) {" section
above the "if ($wgLDAPGroupDN) {" check?

I already pull the preferences, so I didn't see the point in duplicating the
code... just switching the order of the sections (pull LDAP properties first,
including distinguishedname, then check for group membership) seemed to work out
well for me. Is there any reason not to make the switch in the patch?

ryan.lane wrote:

(In reply to comment #75)

RE: Ryan's instructions for getting group authentication to work on AD

Also, is there any reason not to move the "if ($wgLDAPRetrievePrefs) {" section
above the "if ($wgLDAPGroupDN) {" check?

I already pull the preferences, so I didn't see the point in duplicating the
code... just switching the order of the sections (pull LDAP properties first,
including distinguishedname, then check for group membership) seemed to work out
well for me. Is there any reason not to make the switch in the patch?

Well, in your case, it would work more efficiently to pull preferences first, and then check the group. If you are not using AD, then it is probably more efficient to pull
after you check for group membership. I'll look into a better way of doing this. Thanks for the update, I'll change my documentation to reflect the lowercase requirement
on the attribute name.

schibeci wrote:

Thanks to Ryan for the LdapAuthentication.php Plugin and Pierre for adding group
membership.

I've modified LdapAuthentication.php to use a variable for the member attribute
as we use groupOfUniqueMembers rather than groupOfMembers.

Here is my modification if anyone else might find it useful:

  • /root/mediawiki/LdapAuthentication-1.0c.php 2005-11-30 10:41:29.000000000 +0800

+++ includes/LdapAuthentication.php 2005-11-30 10:41:49.000000000 +0800
@@ -154,6 +154,7 @@

global $wgLDAPRetrievePrefs;
global $wgLDAPProxyAgent;
global $wgLDAPGroupDN;

+ global $wgLDAPMemberAttributes;

global $wgLDAPRequireAuthAttribute, $wgLDAPAuthAttribute;
 
if ( '' == $password ) {

@@ -183,7 +184,7 @@

        if ($info["count"] < 1) { return false; }
 }
if ($wgLDAPGroupDN) {
  • return $this->isMemberOfLdapGroup($ldapconn,

$userdn, $wgLDAPGroupDN);
+ return $this->isMemberOfLdapGroup($ldapconn,
$userdn, $wgLDAPGroupDN[$_SESSION['wsDomain']],
$wgLDAPMemberAttributes[$_SESSION['wsDomain']]);

}
if ($wgLDAPRetrievePrefs) {
        $entry = @ldap_read($ldapconn, $userdn,

"objectclass=*");
@@ -541,7 +542,7 @@

        return $userdn;
}
  • function isMemberOfLdapGroup($ldapconn, $userDN, $groupDN) {

+ function isMemberOfLdapGroup($ldapconn, $userDN, $groupDN, $memberattr) {

global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword;
global $wgLDAPSearchAttributes;
//If we are using a proxyagent, we should search the groups

using a proxyagent.
@@ -553,7 +554,7 @@

        }
}
//we need to do a subbase search for the entry
  • $filter = "(member=".$userDN.")";

+ $filter = "($memberattr=".$userDN.")";

$info=ldap_get_entries($ldapconn,@ldap_search($ldapconn,

$groupDN, $filter));

        return ($info["count"]>=1);
}

I also made $wgLDAPGroupDN an array which is why
$wgLDAPGroupDN[$_SESSION['wsDomain']] is sent to isMemberOfLdapGroup

mailsarith wrote:

I've installed Wiki 1.5.3 on IIS 5.0, Win 2K Pro, PHP 5.1, MySQL 3.23. After doing an
LDAP integration, the authentication works fine. But when I get the "login succesful"
page, this appears -

Notice: Undefined variable: servers in
C:\Wiki\mediawiki\includes\LdapAuthentication.php on line 87

Your help appreciated.

erudd wrote:

(Copied from Comment #49)
This is not a support channel. Go to IRC or the mailing lists to get support.
DO not change the bug status information like the way you did.. If you've found
a bug, file a new report, don't change the status of an enhancement bug and
"morph" into your issue.

I'm reverting the status on this bug.

mailsarith wrote:

(In reply to comment #79)

(Copied from Comment #49)This is not a support channel. Go to IRC or the mailing lists to get

support.DO not change the bug status information like the way you did.. If you've founda bug, file
a new report, don't change the status of an enhancement bug and"morph" into your issue.I'm
reverting the status on this bug.

Well, I'd think that if a patch doesnt work 100% in the said configurations and throws exceptions,
it should be considered a bug. If you cant replicate the error or dont have a clue, might as well
mention that.

robchur wrote:

(In reply to comment #80)

(In reply to comment #79)

(Copied from Comment #49)This is not a support channel. Go to IRC or the

mailing lists to get

support.DO not change the bug status information like the way you did.. If

you've founda bug, file

a new report, don't change the status of an enhancement bug and"morph" into

your issue.I'm

reverting the status on this bug.

Well, I'd think that if a patch doesnt work 100% in the said configurations

and throws exceptions,

it should be considered a bug. If you cant replicate the error or dont have a

clue, might as well

mention that.

Was the "patch" part of the code provided in the official MediaWiki distribution
tarball?

mde wrote:

Hi,

what do you think about making the attributes more flexible (see comment #67) e.
g. by shifting the values of

$this->email = $info[0]["mail"][0];
 $this->lang = $info[0]["preferredlanguage"][0];
 $this->nickname = $info[0]["displayname"][0];
 $this->realname = $info[0]["cn"][0];

as variables to the Localsettings, then it would be easier to customize for not
so standard set up LDAP Servers.

mde wrote:

oops, i meant comment #63 - sorry

mde wrote:

One more question on groups. As already discussed it is possible to give access
based on different groups defined on the LDAP Server. What I would like to do
ist to assign group right within the wikidb according to this information which
can easily be retrived together with the uerprefs, so I can use

$wgGroupPermissions

rules based on the data from the LDAP. Creating the groups can be done manually
before, but assignment of users in an automatic way on (1st?) login would be
great instead of using Special:Userrights or editing the database directly.

Anybody any ideas how to achive this?

ryan.lane wrote:

(In reply to comment #82)

Hi,

what do you think about making the attributes more flexible (see comment #67) e.
g. by shifting the values of

$this->email = $info[0]["mail"][0];
 $this->lang = $info[0]["preferredlanguage"][0];
 $this->nickname = $info[0]["displayname"][0];
 $this->realname = $info[0]["cn"][0];

as variables to the Localsettings, then it would be easier to customize for not
so standard set up LDAP Servers.

Next time I have a chance to update the plugin, I'll add options for these. The
biggest problem with doing this is that it adds four new options to the
configuration. I guess I'll have to look into adding a "LDAPDefaultSettings.php"
file.

ryan.lane wrote:

(In reply to comment #84)

One more question on groups. As already discussed it is possible to give access
based on different groups defined on the LDAP Server. What I would like to do
ist to assign group right within the wikidb according to this information which
can easily be retrived together with the uerprefs, so I can use

$wgGroupPermissions

rules based on the data from the LDAP. Creating the groups can be done manually
before, but assignment of users in an automatic way on (1st?) login would be
great instead of using Special:Userrights or editing the database directly.

Anybody any ideas how to achive this?

This is definitely possible... It would be taxing on your LDAP servers if you
have very heavy traffic though. Since LDAP would be your authoritative source,
and since this is authorization information, you shouldn't cache the information
from LDAP. So, every time someone requests a page, it would probably cause a
lookup in LDAP. I guess you could cache the information per session if you
rarely change the info in LDAP...

I'll look into a good way to implement this, as this is also something I'd like.
No promises on time frame though, as I don't have reliable internet access. If
someone else wants to look into how to tackle this, please have at it.

nick.hildebrant wrote:

I had some issues getting LDAP Auth working in MediaWiki 1.5.5. After logging in
with a valid uname and passwd I got the error:

Call to a member function on a non-object in SpecialUserlogin.php on 314.

This seems like a mediawiki bug, and the following change to
SpecialUserlogin.php was required to make LDAP Auth work...

< $u = $this->initUser( $u );

$u =& $this->initUser( $u );

libregeek wrote:

I have posted this mail to the wikitech-l@wikipedia.org. But got Ryan's
instruction to post it here.

I have just started hacking mediawiki. I am trying to apply the LDAP
authentication plugin to mediawiki-1.5.2 in a FC-4. I'm using openldap-2.2.23-5.
I have read the documentation at :
http://meta.wikimedia.org/wiki/LDAP_Authentication and downloaded the plugin
from :http://bugzilla.wikipedia.org/attachment.cgi?id=1042&action=view

I have dropped the above file in /includes and changed Localsettings.php
accordingly. Luckily everything seems to be working fine. But everything crashed
when I tried to Group based authentication in mediawiki. I have added group
entry to the ldap server, restarted it and then inlcuded the configuration
parameters for group based
authentication. Now my Localsettings.php looks like this:
<code>
require_once( 'LdapAuthentication.php' );
$wgAuth = new LdapAuthenticationPlugin();
$wgLDAPDomainNames = array( "libregeek" );
$wgLDAPServerNames = array( "libregeek"=>"localhost" );
$wgLDAPSearchStrings = array(
"libregeek"=>"uid=USER-NAME,ou=People,dc=libregeek,dc=net" );
$wgLDAPUseSSL = false;
$wgLDAPUseLocal = false;
$wgLDAPAddLDAPUsers = false;
$wgLDAPUpdateLDAP = false;
$wgLDAPMailPassword = false;
$wgLDAPRetrievePrefs = false;
$wgMinimalPasswordLength = 1;

$wgLDAPGroupDN = "cn=itpeople,ou=Groups,dc=libregeek,dc=net";
$wgLDAPProxyAgent = "cn=root,dc=libregeek,dc=net";
$wgLDAPProxyAgentPassword = "secret"; //this should work with hashes btw
$wgLDAPBaseDNs = array("libregeek"=>"dc=libregeek,dc=net");
$wgLDAPSearchAttributes =
array("libregeek"=>"(uid=USER-NAME)(wikiAccess=TRUE)");
</code>

With this configuration I can't login . It simply says "The password you entered
is incorrect (or missing). Please try again.". is there any missing
configuration items ?? I just tried to print the global variables corresponding
to Proxies in LdapAuthentication.php and it gives nothing. One more thing I
didn't got the correct idea of Proxy. is it like the "Manager" account who has
read permission to all the directory entries.

what may have gone wrong?
please help
regards

Manilal

ryan.lane wrote:

(In reply to comment #88)

I have posted this mail to the wikitech-l@wikipedia.org. But got Ryan's
instruction to post it here.

Actually, I wanted you to post it to the discussion page on meta ;). This spot
is really more for people who are developing addons for the plugin.

V/r,

Ryan Lane

nabber00 wrote:

I modified the LDAP code to do a search before doing the bind, this is typical
of LDAP authentication mechanisms. This is required if your LDAP does not use
uid in the DN string. It also allows you to use other unique attributes for
login, such as "mail" or "cn". I highly recommend that this standard
functionality be added to the next release.

function getSearchString($username) {
    global $wgLDAPSearchStrings, $wgLDAPBaseDNs;
    $userdn = $wgLDAPBaseDNs[$_SESSION['wsDomain']];
        $this->SearchType = "proxy";
        if (!isset($userdn)) {
                $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']];

                // NCM added for dn search before bind
                $parseddn = split("USER-NAME", $tmpuserdn);
                $searchdn = substr($parseddn[1], 1);
                $filter = $parseddn[0] . $username;

                $ldapconn = $this->connect();
                if ($ldapconn) {
                        ldap_set_option( $ldapconn,

LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0);
# request these attributes
$justthese = array("dn");

$sr = ldap_search($ldapconn, $searchdn, $filter,

$justthese);

        if ($sr !== FALSE) {
                $info = ldap_get_entries($ldapconn, $sr);
                $userdn = $info[0]["dn"];
        } else {
                ldap_error($ldapconn);
        }

        ldap_unbind($ldapconn);
        $this->SearchType = "nonproxy";
}
else {
        $userdn =

str_replace("USER-NAME",$username,$tmpuserdn);

                }
        }

        return $userdn;
}

ryan.lane wrote:

(In reply to comment #90)

I modified the LDAP code to do a search before doing the bind, this is typical
of LDAP authentication mechanisms. This is required if your LDAP does not use
uid in the DN string. It also allows you to use other unique attributes for
login, such as "mail" or "cn". I highly recommend that this standard
functionality be added to the next release.

function getSearchString($username) {
    global $wgLDAPSearchStrings, $wgLDAPBaseDNs;
    $userdn = $wgLDAPBaseDNs[$_SESSION['wsDomain']];
        $this->SearchType = "proxy";
        if (!isset($userdn)) {
                $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']];

                // NCM added for dn search before bind
                $parseddn = split("USER-NAME", $tmpuserdn);
                $searchdn = substr($parseddn[1], 1);
                $filter = $parseddn[0] . $username;

                $ldapconn = $this->connect();
                if ($ldapconn) {
                        ldap_set_option( $ldapconn,

LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_set_option( $ldapconn,

LDAP_OPT_REFERRALS, 0);

  1. request these attributes $justthese = array("dn");

    $sr = ldap_search($ldapconn, $searchdn, $filter,

$justthese);

        if ($sr !== FALSE) {
                $info = ldap_get_entries($ldapconn, $sr);
                $userdn = $info[0]["dn"];
        } else {
                ldap_error($ldapconn);
        }

        ldap_unbind($ldapconn);
        $this->SearchType = "nonproxy";
}
else {
        $userdn =

str_replace("USER-NAME",$username,$tmpuserdn);

                }
        }

        return $userdn;
}

It looks like this change affects straight binds...

What if the directory server required authentication to search? In that case,
this change breaks straight binds. If you want to search, you should be doing a
proxy search. If you don't have a proxyagent, try setting the proxyagent
information blank to do your search.

Many people do not allow anonymous searching (I for one do not), but still want
to do straight binds (me again).

If the plugin for some reason will not allow anonymous searching, please send a
patch for that.

If I am misunderstanding what your code changes do, let me know (and please
submit changes in unified diff format in the future, as it is easier to see what
you changed).

nabber00 wrote:

Sorry, I think these changes should address your concerns. If the search fails
(or bad anonymous/proxy bind occurs), then the function will kick out the
original DN with the replaced USER-NAME string just like the original function did.

  • ../extensions/LdapAuthentication.php 2006-02-21 14:00:31.000000000 -0800

+++ LdapAuthentication.php 2006-02-21 14:00:30.000000000 -0800
@@ -505,13 +505,39 @@

function getSearchString($username) {
           global $wgLDAPSearchStrings, $wgLDAPBaseDNs;

+ global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword;

        $userdn = $wgLDAPBaseDNs[$_SESSION['wsDomain']];
$this->SearchType = "proxy";
if (!isset($userdn)) {
                  $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']];
                  $userdn = str_replace("USER-NAME",$username,$tmpuserdn);

+
+ // NCM added for dn search before bind
+ $parseddn = split("USER-NAME", $tmpuserdn);
+ $searchdn = substr($parseddn[1], 1);
+ $filter = $parseddn[0] . $username;
+
+ $ldapconn = $this->connect();
+ if ($ldapconn) {
+ $bind = @ldap_bind( $ldapconn, $wgLDAPProxyAgent,
$wgLDAPProxyAgentPassword );
+ if ($bind) {
+ ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ldap_set_option( $ldapconn,
LDAP_OPT_REFERRALS, 0);
+ # request these attributes
+ $justthese = array("dn");
+
+ $sr = @ldap_search($ldapconn, $searchdn, $filter, $justthese);
+ if ($sr !== FALSE) {
+ $info = ldap_get_entries($ldapconn, $sr);
+ $userdn = $info[0]["dn"];
+ } else {
+ ldap_error($ldapconn);
+ }
+ }
+ ldap_unbind($ldapconn);

 $this->SearchType = "nonproxy";
}

+ }

   return $userdn;
}

ryan.lane wrote:

Version 1.0d of the LdapAuthentication.php Plugin (for Mediawiki 1.5)

This is a bugfix version of the plugin.

This should address comments #90-92. It also fixes an issue where even if local
authentication was chosen, the plugin would try to authenticate to the LDAP
server. Notice that if you are trying to create local accounts, it will still
try to contact the LDAP server (this is so that people cannot create local
accounts with the same name as LDAP users). It also fixes a bug with proxy
authentication, where if the plugin was misconfigured just the right way, it
would let users in without authenticating (you'd notice this if it was
happening...).

The code was partially refactored. It was cleaned up quite a bit, and the way
proxy authentication was being done is now different (it was being done in a
very asinine way before). It should be a transparent change though. It does
allow you to use $wgLDAPSearchStrings and $wgLDAPBaseDN together (although
there still isn't much reason to do it).

I have not yet added variables for preference attributes, but I plan on getting
to that next release.

attachment LdapAuthentication.php ignored as obsolete

ryan.lane wrote:

(In reply to comment #92)

Sorry, I think these changes should address your concerns. If the search fails
(or bad anonymous/proxy bind occurs), then the function will kick out the
original DN with the replaced USER-NAME string just like the original function

did.

Well, it really doesn't. These changes don't really add anything the plugin
doesn't already do. What you were adding, is done when you do a proxy search.
I've refactored my code, and it should be a little more apparent what I'm doing
in the newest version. You can get the functionality you want, by doing a proxy
search instead of a straight bind.

Look at the configuration options at:
http://meta.wikimedia.org/wiki/LDAP_Authentication_Configuration_Examples#Single_Domain_Requiring_Proxyagent_Binding

It'll do what you need. Just leave out "$wgLDAPProxyAgent" and
"$wgLDAPProxyAgentPassword" for anonymous searches. If for some reason, I'm just
not understanding how my plugin isn't doing exactly what your code is doing
above, let me know.

nabber00 wrote:

Ok, that looks good except getUserDN() needs a line that reads "global
$wgLDAPBaseDNs;" Also it wasn't clear in the documentation what the difference
between using $wgLDAPBaseDNs and $wgLDAPSearchStrings is. I'm not using a
Proxyagent so I never looked in that section where $wgLDAPBaseDNs is referenced
until now.

hackeron wrote:

Cant get this to work with enotifWiki 3.60 + MediaWiki 1.5.6 - I get:

Warning: Missing argument 1 for inituser() in
/var/www/mediawiki1.5.6+enotifwiki3.60/includes/LdapAuthentication.php on line 484

Fatal error: Call to a member function on a non-object in
/var/www/mediawiki1.5.6+enotifwiki3.60/includes/LdapAuthentication.php on line 491

Any ideas?

(In reply to comment #96)

Cant get this to work with enotifWiki 3.60 + MediaWiki 1.5.6 - I get:

Warning: Missing argument 1 for inituser() in
/var/www/mediawiki1.5.6+enotifwiki3.60/includes/LdapAuthentication.php on line 484
Fatal error: Call to a member function on a non-object in
/var/www/mediawiki1.5.6+enotifwiki3.60/includes/LdapAuthentication.php on line 491

Please keep in mind, that questions regarding EnotifWiki should perhaps better
be placed on the page on http://www.enotifwiki.org in order not to disturb the
main development line of MediaWiki.

In your case I am still not sure why this problem came up, but EnotifWiki has
not been tested together with LdapAuthentication and has another method built in
see [1] which perhaps can be adapted to work with LdapAuthentication. Sorry for
this limited help.

[1] http://bugzilla.wikipedia.org/show_bug.cgi?id=1360 Auto-login /
Auto-account-creation by hostname for intranet MediaWikis

ryan.lane wrote:

Version 1.0e of the LdapAuthentication.php Plugin (for Mediawiki 1.5)

This is the latest version of the LdapAuthentication plugin.

This fixes comment #95, which was introduced with plugin version 1.0d, and may
affect proxy-style logins.

attachment LdapAuthentication.php ignored as obsolete

monsoon1 wrote:

I have a problem: When I change the password of a user in AD I can logon in
MediaWiki with the new and the old password. Can anyone help me?

jking wrote:

Has anybody noticed that the version number of the attached files are wrong?
Presently, the version 1.0e link is to a file that has a version 1.0a notice
inside. Ryan, I assume that you are the one to update this in the future? When
1.0f comes around, can you update the internal documentation please? Thanks for
a great addition!

ryan.lane wrote:

(In reply to comment #99)

I have a problem: When I change the password of a user in AD I can logon in
MediaWiki with the new and the old password. Can anyone help me?

This may be a bug. The wiki may be saving the user's password in the database
(it shouldn't be). Please post this on the talk page at meta (follow the URL at
the top of this page), so that we can debug it and see if this is a bug or not.

mike.vonderbecke wrote:

I'm having some problems getting Group authentication working with Active
Directory on a Windows 2000 domain. I've hacked the code per the documentation
and set up my wgLDAPGroupDN variable to be
"CN=wikitest,CN=Users,DC=ourdomain,DC=com" (where ourdomain obviously is the
actual value).

Every time I try to log in I get an error that the password is missing or
incorrect. This is on a user that was already able to login via LDAP
Authentication prior to turning on group auth. I double checked that the User
is a member of the wikitest group, I also double checked the distinguishedname
of both the group and the user using the ADSIEdit program that comes with W2k
server and they match up.

Any ideas as to why I'm having a problem? I have 1.0e.

ryan.lane wrote:

(In reply to comment #102)

I'm having some problems getting Group authentication working with Active
Directory on a Windows 2000 domain. I've hacked the code per the documentation
and set up my wgLDAPGroupDN variable to be
"CN=wikitest,CN=Users,DC=ourdomain,DC=com" (where ourdomain obviously is the
actual value).

Every time I try to log in I get an error that the password is missing or
incorrect. This is on a user that was already able to login via LDAP
Authentication prior to turning on group auth. I double checked that the User
is a member of the wikitest group, I also double checked the distinguishedname
of both the group and the user using the ADSIEdit program that comes with W2k
server and they match up.

Any ideas as to why I'm having a problem? I have 1.0e.

Please use the discussion page on the LDAP Authentication page at meta. This is
not a support forum.

ryan.lane wrote:

While we are on the topic of group authentication. Justin Grote mentioned he was
going to be working on a better solution for this. I haven't heard anything back
from him (this was January 29th). If anyone knows what the status of that is,
please post it.

It seems we have a need for updated code, and if he isn't working on it I'll
start working on it.

don wrote:

Has anyone got this working with mediawiki 1.6? We just upgraded and
authentication always fails now.

We're authenticating against AD, worked fine with 1.5.5.

don wrote:

Just noticed this error at the top of the page after auth failure as well:

<b>Warning</b>: Compilation failed: characters with values > 255 are not yet
supported in classes at offset 33 in
<b>/usr/local/mediawiki-1.6.1/includes/User.php</b> on line <b>224</b><br />

don wrote:

(In reply to comment #106)

Just noticed this error at the top of the page after auth failure as well:

<b>Warning</b>: Compilation failed: characters with values > 255 are not yet
supported in classes at offset 33 in
<b>/usr/local/mediawiki-1.6.1/includes/User.php</b> on line <b>224</b><br />

This was due to a PHP/unicode/preg_match() issue, unrelated to LDAP auth. I
commented out that block of code and LDAP auth still fails, but the error goes
away :p

don wrote:

(In reply to comment #105)

Has anyone got this working with mediawiki 1.6? We just upgraded and
authentication always fails now.

We're authenticating against AD, worked fine with 1.5.5.

GAH don't mind me. This is a case of too many things changing at once and too
many cooks. Other admin updated to new version of LdapAuthentication, and proxy
binding wasn't being done there. Reverted to older version of
LdapAuthentication.php and all works fine. I'll have to look at configs for new
version to see what is different.

greenwaldjared wrote:

I tired the .8 patch for my 1.4.15 config and I can't seem to get it working.
I'm not even sure its setup correctly. I followed the examples in found in the
wiki, but when I try using an ldap uid to login, it fails.

ryan.lane wrote:

(In reply to comment #109)

I tired the .8 patch for my 1.4.15 config and I can't seem to get it working.
I'm not even sure its setup correctly. I followed the examples in found in the
wiki, but when I try using an ldap uid to login, it fails.

I gotta be honest. I probably don't remember how to setup version .8 with
mediawiki 1.4. I'd have to look back at my old code. I've dropped support for
version .8 and mediawiki 1.4. If you can, upgrade your wiki to 1.5 or 1.6
series, the documentation for that is good.

me wrote:

It will be great if user can choose the way for hashing password in LDAP.

fyi, i'm trying to integrate mediawiki with my existing LDAP, SHA generated by
this plugin will break an existing application as it knows CRYPT only.

i added a new configuration, $wgLDAPPasswordHash to get this works, here is the
diff to 1.0e:

232c232,233

<

global $wgLDAPPasswordHash;

241,rEWBA242c242b1d0d,255
< $pwd_md5 = base64_encode(pack('H*',sha1($password)));

< $pass = "{SHA}".$pwd_md5;

switch ($wgLDAPPasswordHash) {
        case 'crypt':
                $pass = '{CRYPT}' . crypt($password);
                break;
        case 'clear':
                $pass = $password;
                break;
        default:
                $pwd_md5 =

base64_encode(pack('H*',sha1($password)));

                $pass = "{SHA}".$pwd_md5;
                break;
}

more hashing can be added but i will just leave it there.

ryan.lane wrote:

(In reply to comment #111)

It will be great if user can choose the way for hashing password in LDAP.

fyi, i'm trying to integrate mediawiki with my existing LDAP, SHA generated by
this plugin will break an existing application as it knows CRYPT only.

i added a new configuration, $wgLDAPPasswordHash to get this works, here is the
diff to 1.0e:

232c232,233

<

global $wgLDAPPasswordHash;

241,rEWBA242c242b1d0d,255
< $pwd_md5 = base64_encode(pack('H*',sha1($password)));

< $pass = "{SHA}".$pwd_md5;

switch ($wgLDAPPasswordHash) {
        case 'crypt':
                $pass = '{CRYPT}' . crypt($password);
                break;
        case 'clear':
                $pass = $password;
                break;
        default:
                $pwd_md5 =

base64_encode(pack('H*',sha1($password)));

                $pass = "{SHA}".$pwd_md5;
                break;
}

more hashing can be added but i will just leave it there.

I'm probably wrong, but... Don't all passwords have to be base64 encoded in LDAP?

ryan.lane wrote:

(In reply to comment #111)

It will be great if user can choose the way for hashing password in LDAP.

fyi, i'm trying to integrate mediawiki with my existing LDAP, SHA generated by
this plugin will break an existing application as it knows CRYPT only.

i added a new configuration, $wgLDAPPasswordHash to get this works, here is the
diff to 1.0e:

232c232,233

<

global $wgLDAPPasswordHash;

241,rEWBA242c242b1d0d,255
< $pwd_md5 = base64_encode(pack('H*',sha1($password)));

< $pass = "{SHA}".$pwd_md5;

switch ($wgLDAPPasswordHash) {
        case 'crypt':
                $pass = '{CRYPT}' . crypt($password);
                break;
        case 'clear':
                $pass = $password;
                break;
        default:
                $pwd_md5 =

base64_encode(pack('H*',sha1($password)));

                $pass = "{SHA}".$pwd_md5;
                break;
}

more hashing can be added but i will just leave it there.

I'm probably wrong, but... Don't all passwords have to be base64 encoded in
LDAP? I like the patch otherwise, and I'll include it in the next version of the
plugin.

kgrinberg wrote:

Something I noticed: in userExists, $wgLDAPBaseDN is defined (global) but never
used... which is good, because unless I'm mistaken, it should be $wgLDAPBaseDNs
(note the "s" at the end...)

Am I missing something, or is this a bug waiting to happen?

ryan.lane wrote:

(In reply to comment #114)

Something I noticed: in userExists, $wgLDAPBaseDN is defined (global) but never
used... which is good, because unless I'm mistaken, it should be $wgLDAPBaseDNs
(note the "s" at the end...)

Am I missing something, or is this a bug waiting to happen?

This must be a variable left in from the pre 1.0 days. I *thought* I cleaned out
all of the unused globals, but it looks like I missed one. I'll check my
functions again and clean out unused variables for next release.

ryan.lane wrote:

Version 1.0f of the LdapAuthentication.php Plugin (for Mediawiki 1.5-1.7)

This is a (mostly) bugfix version of the plugin.

Fixed the version number at the top of the file.
Fixed the preferences bug from: Talk:LDAP Authentication#Problem with
preferences from LDAP
Added function in for changing usernames to lowercase to fix:
Talk:LDAP_Authentication#Username_modified_.28capital_letter.29.2C_authentication_fails
(only works in versions 1.6+)
Added debugging code (let me know what extra debugging info you want, or if
some things should be showing at a different debug level)
Cleaned out unused global variables
Added the password switching statement from #111 in this bug (notice I added it
for changing passwords, and for creating users)
Fixed an undeclared global variable $wgLDAPWriteLocation in addUsers
Added the ability to use TLS as well as LDAPS (I'm not 100% sure this is
working, let me know!)

Updated documentation at the normal place will follow soon.

attachment LdapAuthentication.php ignored as obsolete

ryan.lane wrote:

Version 1.0g of the LdapAuthentication.php Plugin (for Mediawiki 1.5-1.7)

This update offers a new group based authentication check and deprecates the
old included one. The new check allows for nested groups, and can search groups
either as a proxyagent, or as the user who is authenticating. Documentation to
follow soon on meta at the normal place.

attachment LdapAuthentication.php ignored as obsolete

bgmilne wrote:

I had a problem with the current patch where the filter for checking group
memberships (in the attribute value is username case) was using the uppercased
username, which did not match.

I've hacked it at line 212 to have:

if ($wgLDAPRequiredGroups[$_SESSION['wsDomain']]) {
        $ldapusername = $username;
        $ldapusername[0] = strtolower($ldapusername[0]);
        $this->printDebug("Checking for (new style)

group membership",1);

if ($wgLDAPGroupUseFullDN[$_SESSION['wsDomain']]) {
        $inGroup =

$this->isMemberOfRequiredLdapGroup($ldapconn, $userdn);

} else {
        $inGroup =

$this->isMemberOfRequiredLdapGroup($ldapconn, $ldapusername);

}

gunter.schmidt wrote:

We have a similiar case problem with the groups checking.

Using:

$wgLDAPRequiredGroups = array( "REF-EDIR"=>array("cn=lht-wiki,ou=adg,ou=roles (pw),ou=LH,o=LH-DIR") );

will not find any groups, giving "Couldn't find the user in any groups (2)."

The LDAP Server returns the groups correctly, but in lower case ... ou=lh, o=lh-dir.

After changing the line to

$wgLDAPRequiredGroups = array( "REF-EDIR"=>array("cn=lht-wiki,ou=adg,ou=roles (pw),ou=lh,o=lh-dir") );

all works out fine.

Thanks for implementing the proxy user so fast.

ryan.lane wrote:

(In reply to comment #119)

We have a similiar case problem with the groups checking.Using:$wgLDAPRequiredGroups = array( "REF-EDIR"=>array

("cn=lht-wiki,ou=adg,ou=roles (pw),ou=LH,o=LH-DIR") );will not find any groups, giving "Couldn't find the user in any
groups (2)."The LDAP Server returns the groups correctly, but in lower case ... ou=lh, o=lh-dir.After changing the
line to$wgLDAPRequiredGroups = array( "REF-EDIR"=>array("cn=lht-wiki,ou=adg,ou=roles (pw),ou=lh,o=lh-dir") );all
works out fine.Thanks for implementing the proxy user so fast.

This is done on purpose. I do a tolower on the returned groups in the function getGroups. LDAP is case insensitive,
and PHP is not, it should be impossible to enter both cn=group and cn=Group, so to avoid weird matching problems, I
make sure everything is lowercase.

I guess I should update my documentation to inform people of this right? ;)

In response to #118. I don't see where I'm matching anywhere for usernames; LDAP is case insensitive on this matter,
so it shouldn't be an issue for the username to be cased. I'll look a little harder, but I won't make this change
just yet.

bgmilne wrote:

Right, I should have included a bit more information on my group setup, which is using the
nis.schema/posixAccount/posixGroup-type stuff, so I have:

$wgLDAPRequiredGroups = array( "mycontext"=>array("cn=build,ou=group,dc=mydomain,dc=com") );
$wgLDAPGroupUseFullDN = array( "mycontext"=>false );
$wgLDAPGroupObjectclass = array( "mycontext"=>"posixGroup" );
$wgLDAPGroupAttribute = array( "mycontext"=>"memberUid" );
$wgLDAPGroupSearchNestedGroups = array( "mycontext"=>false );

memberUid (according to nis.schema - and rfc2307bis seems to be the same) is:
attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid'

EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

So, for the memberUid attribute, case does matter:

[bgmilne@comanche ~]$ ldapsearch -LLL -x "(memberUid=bgmilne)" dn
dn: cn=sysadmins,ou=Group,dc=mydomain,dc=com

dn: cn=build,ou=Group,dc=mydomain,dc=com

[bgmilne@comanche ~]$ ldapsearch -LLL -x "(memberUid=Bgmilne)" cn
[bgmilne@comanche ~]$

"LDAP is case insensitive" is an invalid generalisation, some attributes, such as dn, are case insensitive, but this
doesn't mean that all attributes are. Eg, the uid attribute is case insentitive, and usually the same string appears
in the memebrUid attribute, but this attribute is case sensitive.

Since the group membership attribute is configurable, it could be case sensitive, so case should be preserved (at
least in the $wgLDAPGroupUseFullDN=false case) when doing group membership checks. The question is which case to
preserve (the one the user entered, or the result of a search), the result of the search would probably be best.

(I should probably consider migrating to rfc2307bis where member attribute is the dn, but ... a lot of people still
use nis.schema).

I'll look at doing a better fix for this and supplying a patch.

ryan.lane wrote:

(In reply to comment #121)

"LDAP is case insensitive" is an invalid generalisation, some attributes, such

as dn, are case insensitive, but this

doesn't mean that all attributes are. Eg, the uid attribute is case

insentitive, and usually the same string appears

in the memebrUid attribute, but this attribute is case sensitive.

[snip]

(I should probably consider migrating to rfc2307bis where member attribute is

the dn, but ... a lot of people still

use nis.schema).

I'll look at doing a better fix for this and supplying a patch.

Sorry about the generalization. I usually leave out the part about "for specific
attributes". I thought I had taken into account for nis.schema, but it looks
like Sun's nis schema is different from openldap's nis schema, and I'm using Sun
Directory Server with the nis schema. (Thanks Sun for screwing me again, I
looked at the RFC and it DOES indeed say caseExactIA5Match).

No need to send in a patch. This fix only really has to do with groups, so I'll
add it into "isMemberOfRequiredLdapGroup".

gunter.schmidt wrote:

moving to our production environment, I have a serious performance problem.

The group check takes about 4 Minutes. I included the debug listing, where I added a time stamp.

Search string: (&(member=cn=X1234,ou=HAM,ou=LHT,ou=LH,o=LH-DIR)(objectclass=groupofnames))Wed, 23 Aug 2006 18:12:48
Binding as the proxyagentDN Wed, 23 Aug 2006 18:12:48 +0200
Binding finished Wed, 23 Aug 2006 18:12:48 +0200
Returned groups:cn=role-hamtisfa,ou=governor,ou=roles (pw),ou=lh,o=lh-dir,cn=wlan,ou=applications,ou=roles
(pw),ou=lh,o=lh-dir, --- snip --- Wed, 23 Aug 2006 18:17:07 +0200
GroupCount = 14
Found user in a group. Wed, 23 Aug 2006 18:17:07 +0200

Has anybody noticed similar problems or is this a configuration problem of our LDAP-Server?

ryan.lane wrote:

(In reply to comment #123)

moving to our production environment, I have a serious performance problem.The group check takes about 4 Minutes. I

included the debug listing, where I added a time stamp.Search string: (&(member=cn=X1234,ou=HAM,ou=LHT,ou=LH,o=LH-DIR)
(objectclass=groupofnames))Wed, 23 Aug 2006 18:12:48Binding as the proxyagentDN Wed, 23 Aug 2006 18:12:48
+0200Binding finished Wed, 23 Aug 2006 18:12:48 +0200Returned groups:cn=role-hamtisfa,ou=governor,ou=roles
(pw),ou=lh,o=lh-dir,cn=wlan,ou=applications,ou=roles (pw),ou=lh,o=lh-dir, --- snip --- Wed, 23 Aug 2006 18:17:07
+0200GroupCount = 14Found user in a group. Wed, 23 Aug 2006 18:17:07 +0200Has anybody noticed similar problems or is
this a configuration problem of our LDAP-Server?

Support requests should be added to the talk page of the meta article. I'll copy and paste it into there with my
response. This is for bugs and patches only.

Douglas.Pace wrote:

(In reply to comment #70)

Created an attachment (id=1036) [edit]
Patch to 1.0.a for require attribute

This is a restructured version of the first patch submitted to add support for
requiring a user to have a certain attribute to finish authenticating to the
wiki. It now properly handles the case where no proxy user is allowed, nor is
an anonymous search allowed.

First let me say I love this feature but I have a suggestion about it. I
currently have need to use the AuthAttribute to filter based on a protected
attribute in LDAP, specifically class enrollment.

I have two options. One is a proxy user, which is highly frowned upon because of
security and clear text passwords in world readable files, etc. The second is to
only check the attribute after binding as the user, which seems to be a better
solution anyway. But currently the AuthAttribute is checked twice. Once in
getUserDN as either anonymous or as the proxy user(which is where this breaks in
this situation) and again after the user binds. I understand this first check
does save work on users who don't have the attribute, but it doesn't seem as
robust since the user themselves will almost always have more access than
anonymous and possibly even more than the proxy user?

  • LdapAuthentication-1.0g.php 2006-09-05 11:01:41.665817575 -0700

+++ LdapAuthentication.php 2006-09-05 10:59:04.722809051 -0700
@@ -693,18 +693,8 @@ class LdapAuthenticationPlugin extends A

}

//we need to do a subbase search for the entry
  • //Why waste a bind later, if a user is missing an auth attribute
  • //let's catch it here.
  • if ($wgLDAPRequireAuthAttribute) {
  • $auth_filter = "(" .

$wgLDAPAuthAttribute[$_SESSION['wsDomain']] . ")";

  • $srch_filter = "(" .

$wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=$username)";

  • $filter = "(&" . $srch_filter . $auth_filter . ")";
  • $this->printDebug("Created an auth attribute filter:

$filter",2);

  • } else {
  • $filter = "(" .

$wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=$username)";

  • $this->printDebug("Created a regular filter: $filter",2);
  • }

+ $filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] .
"=$username)";
+ $this->printDebug("Created a regular filter: $filter",2);

$attributes = array("dn");
 $base = $wgLDAPBaseDNs[$_SESSION['wsDomain']];

tom wrote:

in setPassword function, to not eraze password, we can change :
$pass = $this->getPasswordHash($pass);
by
$pass = $this->getPasswordHash($password);

ryan.lane wrote:

(In reply to comment #126)

in setPassword function, to not eraze password, we can change :
$pass = $this->getPasswordHash($pass);
by
$pass = $this->getPasswordHash($password);

Wow, now *there* is a real for deal bug. I don't know how this ever worked (and
I know I tested it at one point). Good catch, this will be fixed next release.

hg wrote:

(In reply to comment #122)

(In reply to comment #121)

"LDAP is case insensitive" is an invalid generalisation, some attributes, such

as dn, are case insensitive, but this

doesn't mean that all attributes are. Eg, the uid attribute is case

insentitive, and usually the same string appears

in the memebrUid attribute, but this attribute is case sensitive.

[snip]

No need to send in a patch. This fix only really has to do with groups, so I'll
add it into "isMemberOfRequiredLdapGroup".

When will this adjustment be made? Meanwhile i did a dirty hack, which only
works for our environment...

ryan.lane wrote:

(In reply to comment #128)

When will this adjustment be made? Meanwhile i did a dirty hack, which only
works for our environment...

Sorry, I've been out of the country, and my laptop was broken, so I haven't had
much of a chance to work on this. Hopefully I'll have a new release soon. I'll
try to have one out in the next couple of weeks.

Little problem:

The first login throws an error "Fatal error: Call to a member function on a
non-object in /srv/www/htdocs/wiki/includes/SpecialUserlogin.php on line 320".

Later logins work without problems. Is there a possibility to get rid of this
error message?

Concerning versions:

  • MediaWiki 1.6.8
  • mod_php4

ryan.lane wrote:

(In reply to comment #130)

Little problem:The first login throws an error "Fatal error: Call to a member function on anon-object

in /srv/www/htdocs/wiki/includes/SpecialUserlogin.php on line 320".Later logins work without problems. Is there a
possibility to get rid of thiserror message?Concerning versions:- MediaWiki 1.6.8- mod_php4

I'm using the same setup and not having that problem. I also don't manage SpecialUserlogin.php, you'll need to put a
new bug report in if you believe there is a bug in that class.

You may just have a configuration error. If you need support, please post your question on the discussion page for
the plugin's documentation on meta.

ryan.lane wrote:

Version 1.0h of the LdapAuthentication.php Plugin (for Mediawiki 1.5+)

This is a bugfix version of the plugin. The following fixes have been made:

  1. Comment #118 (lowercasing the username in the groups checking)
  2. Comment #125 (redundant auth attr check)
  3. Comment #126 (setPassword function erasing the user's password in LDAP)

In regards to the fix for comment #125: This fix disabled the check, it did not
remove it. If you would like to re-enable it for performance reasons, just
uncomment the section that was commented.

In regards to the fix for comment #118: The fix proposed may have caused issues
with other users who need case sensitive searches. I've added the fix as a
boolean option ($wgLDAPGroupLowerCaseUsername).

Attached:

clemens.steinkogler wrote:

I have problems with the group authentication, can anybody please help? My LDAP section looks like this:

<code>

  1. LDAP require_once( 'LdapAuthentication.php' ); $wgAuth = new LdapAuthenticationPlugin(); $wgLDAPDomainNames = array("olymp"); $wgLDAPServerNames = array("olymp"=>"neptun.xxx.yyy.at"); $wgLDAPSearchStrings = array("olymp"=>"OLYMP\USER-NAME"); $wgLDAPSearchAttributes = array("olymp"=>"sAMAccountName"); $wgLDAPUseSSL = false; $wgLDAPUseLocal = false; $wgMinimalPasswordLength = 1; $wgLDAPRetrievePrefs = false;
  2. GROUP AUTHENICATION $wgLDAPRequiredGroups = array( "olymp"=>array("cn=standby,ou=test,dc=neptun,dc=xxx,dc=yyy,dc=at") ); $wgLDAPGroupUseFullDN = array( "olymp"=>true ); $wgLDAPGroupObjectclass = array( "olymp"=>"group" ); $wgLDAPGroupAttribute = array( "olymp"=>"member" ); $wgLDAPGroupSearchNestedGroups = array( "olymp"=>false ); $wgLDAPBaseDNs = array( "olymp"=>"dc=neptun,dc=xxx,dc=yyy,dc=at" );

    $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['edit'] = false; $wgWhitelistRead = array("Hauptseite","Spezial:Userlogin", "-","MediaWiki:Monobook.css"); $wgGroupPermissions['*']['read'] = false; $wgShowIPinHeader = true;

</code>

Our Windows 2000 Server "neptun" with active directory has an OU "test" with a group "standby". I'm now member of the
group "standby". If I now want to log in to the wiki there appears following error:

<b>Warning</b>: ldap_get_entries(): supplied argument is not a valid ldap result resource in
<b>/var/www/standby/includes/LdapAuthentication.php</b> on line <b>857</b><br />
<br />
<b>Warning</b>: array_shift() function.array-shift: The argument should be an array in
<b>/var/www/standby/includes/LdapAuthentication.php</b> on line <b>860</b><br />
<br />
<b>Warning</b>: Invalid argument supplied for foreach() in <b>/var/www/standby/includes/LdapAuthentication.php</b>
on line <b>863</b><br />
Password wrong: blabla

So what could be wrong here. I can imagine that it's something small but I'm trying now for days and can't find the
error. Without groupauthenication it works. Hope that it is allowed to post this here. Thanks for any help.

ryan.lane wrote:

(In reply to comment #133)

I have problems with the group authentication, can anybody please help? My

LDAP section looks like this:

[snip]

I don't know how many times I (and others) have to write this here, but this
bugzilla page is *NOT* a support forum, it is for bugs and release information
only!!

There are at least a couple places you can ask this question. One is on the
discussion page of the LDAP Authentication article on meta, the other is on the
Mediawiki Enterprise list:

http://mail.wikimedia.org/mailman/listinfo/mediawiki-enterprise

I've even been occasionally known to answer questions on the mediawiki-l list as
well (although I don't like to bug everyone else there with LDAP support issues).

I'll give support on one of those places, but not here. When you post your
question in the correct place, make sure you give debug information as well
using $wgLDAPDebug = 4, making sure to snip out any sensitive information. Also
include the version of mediawiki, and the version of the plugin you are using.

alfonsname wrote:

Hi,

this is patch agains 1.0e (LdapPlugin from April 2006).
It adds ldap group support to mediawiki, where a ldap group overrides any
membership setting of a local group.
this is useful for example for restricted namespaces.

sincerly,
mbraun

  • LdapAuthentication.php.bck Wed Nov 29 12:49:38 2006
  • LdapAuthentication.php Wed Nov 29 16:25:04 2006 ***
  • 44,50 **** require_once( 'AuthPlugin.php' );

    class LdapAuthenticationPlugin extends AuthPlugin {

! var $email, $lang, $realname, $nickname, $SearchType;

	/**
	 * Check whether there exists a user account with the given name.
	 * The name will be normalized to MediaWiki's requirements, so
  • 44,50 ---- require_once( 'AuthPlugin.php' );

    class LdapAuthenticationPlugin extends AuthPlugin {

! var $email, $lang, $realname, $nickname, $SearchType, $groups, $allLdapGroups;

	/**
	 * Check whether there exists a user account with the given name.
	 * The name will be normalized to MediaWiki's requirements, so

  • 155,161 ****
  • 155,165 ---- global $wgLDAPProxyAgent; global $wgLDAPGroupDN; global $wgLDAPRequireAuthAttribute, $wgLDAPAuthAttribute;

+ global $wgLDAPGrpBase;

+ $this->groups=Array();
+ $this->allLdapGroups=Array();
+

		if ( '' == $password ) {
			return false;
		}

  • 183,189 **** if ($info["count"] < 1) { return false; } } if ($wgLDAPGroupDN) {

! return $this->isMemberOfLdapGroup($ldapconn, $userdn, $wgLDAPGroupDN);

			}
			if ($wgLDAPRetrievePrefs) {
				$entry = @ldap_read($ldapconn, $userdn, "objectclass=*");
  • 187,194 ---- if ($info["count"] < 1) { return false; } } if ($wgLDAPGroupDN) {

! if (! $this->isMemberOfLdapGroup($ldapconn, $userdn, $wgLDAPGroupDN))
! return false;

			}
			if ($wgLDAPRetrievePrefs) {
				$entry = @ldap_read($ldapconn, $userdn, "objectclass=*");

  • 193,198 ****
  • 198,225 ---- $this->nickname = $info[0]["displayname"][0]; $this->realname = $info[0]["cn"][0]; }

+
+ // get groups
+ $grpRes = ldap_search($ldapconn,
$wgLDAPGrpBase[$_SESSION[wsDomain]],
"memberUid=".strtolower($username)."",Array("cn"));
+ for ($entryID=ldap_first_entry($ldapconn,$grpRes);
+ $entryID!=false;
+ $entryID=ldap_next_entry($ldapconn,$entryID))
+ {
+ $cGroup = ldap_get_values($ldapconn,$entryID,'cn');
+ $cGroup=$cGroup[0];
+ $this->groups[] = $cGroup;
+ }
+
+ $grpRes = ldap_search($ldapconn, $wgLDAPGrpBase[$_SESSION[wsDomain]],
"objectClass=posixGroup",Array("cn"));
+ for ($entryID=ldap_first_entry($ldapconn,$grpRes);
+ $entryID!=false;
+ $entryID=ldap_next_entry($ldapconn,$entryID))
+ {
+ $cGroup = ldap_get_values($ldapconn,$entryID,'cn');
+ $cGroup=$cGroup[0];
+ $this->allLdapGroups[] = $cGroup;
+ }
+

			// Lets clean up.
			@ldap_unbind();
                } else {

  • 450,457 ****
  • 477,512 ---- if ('' != $this->email) { $user->setEmail($this->email); }

+ # add groups permissions
+ $localAvailGrps = $user->getAllGroups();
+ $localUserGrps = $user->getEffectiveGroups();
+ # note: $localUserGrps does not need to be updated with $cGroup added,
+ # as $localAvailGrps contains $cGroup only once.
+ foreach ($localAvailGrps as $cGroup) {
+ # did we once add the user to the group?
+ if (in_array($cGroup,$localUserGrps)) {
+ if ((!$this->hasLDAPGroup($cGroup)) && ($this->isLDAPGroup($cGroup))) {
+ # die LDAP Gruppe überschreibt die lokale Gruppe
+ # d.h. wenn sie existiert, und der user nicht enthlaten ist, dann
muss er auch aus der wiki grp raus
+ $user->delGroup($cGroup);
+ }
+ } else { # no, but maybe the user has just been added to the group
+ if ($this->hasLDAPGroup($cGroup)) {
+ # so use the addGroup function
+ $user->addGroup($cGroup);
+ # completedfor $cGroup.
+ }
+ }
+ }

}

+ function hasLDAPGroup($group) {
+ return in_array($group, $this->groups);
+ }
+
+ function isLDAPGroup($group) {
+ return in_array($group, $this->allLdapGroups);
+ }

	/**
	 * Return true to prevent logins that don't authenticate here from being
	 * checked against the local database's password fields.

  • 553,559 **** } } //we need to do a subbase search for the entry

! $filter = "(member=".$userDN.")";

		$info=ldap_get_entries($ldapconn,@ldap_search($ldapconn, $groupDN, $filter));
		return ($info["count"]>=1);
	}
  • 608,614 ---- } } //we need to do a subbase search for the entry

! $filter = "(memberUid=".$userDN.")";

		$info=ldap_get_entries($ldapconn,@ldap_search($ldapconn, $groupDN, $filter));
		return ($info["count"]>=1);
	}

alfonsname wrote:

My last patch introduces a new configuration option: $wgLDAPGrpBase : Array
(Domain => Ldap search base for groups).
The names posixGroup, memberUid, cn are currently fixed in code.

ryan.lane wrote:

(In reply to comment #135)

Hi,

this is patch agains 1.0e (LdapPlugin from April 2006).
It adds ldap group support to mediawiki, where a ldap group overrides any
membership setting of a local group.
this is useful for example for restricted namespaces.

sincerly,
mbraun

Great work! I'm glad you've sent me a patch for this, because this was pretty
low on my hit-list. I'll take a look at the patch and rework it to be a little
more generic. I'll probably add some debugging info, and might change some of
the options to conform to the other options.

Is there any way you can translate the comments? I can't read german (that is
german right?).

I'm about to release a pretty big update to the plugin to add smartcard support,
so it may take me a while to integrate this (especially since this is a patch
against 1.0e...).

V/r,

Ryan Lane

alfonsname wrote:

Hi,

okay, here is the patch with the english-only comments.
There are two comments added and the delGroup-function is actually named
removeGroup (bug fix).

sincerly,
mbraun

  • LdapAuthentication.php.bck Wed Nov 29 12:49:38 2006
  • LdapAuthentication.php Thu Nov 30 08:47:58 2006 ***
  • 44,50 **** require_once( 'AuthPlugin.php' );

    class LdapAuthenticationPlugin extends AuthPlugin {

! var $email, $lang, $realname, $nickname, $SearchType;

	/**
	 * Check whether there exists a user account with the given name.
	 * The name will be normalized to MediaWiki's requirements, so
  • 44,50 ---- require_once( 'AuthPlugin.php' );

    class LdapAuthenticationPlugin extends AuthPlugin {

! var $email, $lang, $realname, $nickname, $SearchType, $groups, $allLdapGroups;

	/**
	 * Check whether there exists a user account with the given name.
	 * The name will be normalized to MediaWiki's requirements, so

  • 155,161 ****
  • 155,165 ---- global $wgLDAPProxyAgent; global $wgLDAPGroupDN; global $wgLDAPRequireAuthAttribute, $wgLDAPAuthAttribute;

+ global $wgLDAPGrpBase;

+ $this->groups=Array();
+ $this->allLdapGroups=Array();
+

		if ( '' == $password ) {
			return false;
		}

  • 183,189 **** if ($info["count"] < 1) { return false; } } if ($wgLDAPGroupDN) {

! return $this->isMemberOfLdapGroup($ldapconn, $userdn, $wgLDAPGroupDN);

			}
			if ($wgLDAPRetrievePrefs) {
				$entry = @ldap_read($ldapconn, $userdn, "objectclass=*");
  • 187,194 ---- if ($info["count"] < 1) { return false; } } if ($wgLDAPGroupDN) {

! if (! $this->isMemberOfLdapGroup($ldapconn, $userdn, $wgLDAPGroupDN))
! return false;

			}
			if ($wgLDAPRetrievePrefs) {
				$entry = @ldap_read($ldapconn, $userdn, "objectclass=*");

  • 193,198 ****
  • 198,225 ---- $this->nickname = $info[0]["displayname"][0]; $this->realname = $info[0]["cn"][0]; }

+
+ // get information on ldap groups and this user group memberships
+ $grpRes = ldap_search($ldapconn,
$wgLDAPGrpBase[$_SESSION[wsDomain]],
"memberUid=".strtolower($username)."",Array("cn"));
+ for ($entryID=ldap_first_entry($ldapconn,$grpRes);
+ $entryID!=false;
+ $entryID=ldap_next_entry($ldapconn,$entryID))
+ {
+ $cGroup = ldap_get_values($ldapconn,$entryID,'cn');
+ $cGroup=$cGroup[0];
+ $this->groups[] = $cGroup;
+ }
+
+ $grpRes = ldap_search($ldapconn, $wgLDAPGrpBase[$_SESSION[wsDomain]],
"objectClass=posixGroup",Array("cn"));
+ for ($entryID=ldap_first_entry($ldapconn,$grpRes);
+ $entryID!=false;
+ $entryID=ldap_next_entry($ldapconn,$entryID))
+ {
+ $cGroup = ldap_get_values($ldapconn,$entryID,'cn');
+ $cGroup=$cGroup[0];
+ $this->allLdapGroups[] = $cGroup;
+ }
+

			// Lets clean up.
			@ldap_unbind();
                } else {

  • 450,458 ****
  • 477,521 ---- if ('' != $this->email) { $user->setEmail($this->email); }

+ # add groups permissions
+ $localAvailGrps = $user->getAllGroups();
+ $localUserGrps = $user->getEffectiveGroups();
+ # note: $localUserGrps does not need to be updated with $cGroup added,
+ # as $localAvailGrps contains $cGroup only once.
+ foreach ($localAvailGrps as $cGroup) {
+ # did we once add the user to the group?
+ if (in_array($cGroup,$localUserGrps)) {
+ if ((!$this->hasLDAPGroup($cGroup)) && ($this->isLDAPGroup($cGroup))) {
+ # the ldap group overrides the local group
+ # so as the user is currently not a member of the ldap group, he
shall be removed from the local group
+ $user->removeGroup($cGroup);
+ }
+ } else { # no, but maybe the user has recently been added to the ldap group?
+ if ($this->hasLDAPGroup($cGroup)) {
+ # so use the addGroup function
+ $user->addGroup($cGroup);
+ # completedfor $cGroup.
+ }
+ }
+ }

        }

	/**

+ * returns true if the last authenticated user is member of this group, else
false
+ * will always return false if the last user did not authenticate
successfully with ldap
+ */
+ function hasLDAPGroup($group) {
+ return in_array($group, $this->groups);
+ }
+
+ /
+ * returns true if a ldap group with this name exists, else false
+ * will always return false if the last user did not authenticate
successfully with ldap
+ */
+ function isLDAPGroup($group) {
+ return in_array($group, $this->allLdapGroups);
+ }
+ /

    • Return true to prevent logins that don't authenticate here from being
    • checked against the local database's password fields. * ***
  • 553,559 **** } } //we need to do a subbase search for the entry

! $filter = "(member=".$userDN.")";

		$info=ldap_get_entries($ldapconn,@ldap_search($ldapconn, $groupDN, $filter));
		return ($info["count"]>=1);
	}
  • 616,622 ---- } } //we need to do a subbase search for the entry

! $filter = "(memberUid=".$userDN.")";

		$info=ldap_get_entries($ldapconn,@ldap_search($ldapconn, $groupDN, $filter));
		return ($info["count"]>=1);
	}

alfonsname wrote:

Ldap Group Support against 1.0e

as described yesterday.

Attached:

joecorporation wrote:

Someone have any experiences with Apache 2.2 and the LDAP Patch ?
We have a System where the Patch works fine, but on a new System with the Apache 2.2 nothing works.

ryan.lane wrote:

(In reply to comment #140)

Someone have any experiences with Apache 2.2 and the LDAP Patch ?
We have a System where the Patch works fine, but on a new System with the

Apache 2.2 nothing works.

I haven't tried the plugin with Apache 2.2; however, I have no clue why the
plugin wouldn't work with it. The plugin doesn't use anything Apache specific.
Make a section on the discussion page on meta and we'll investigate this further
(you didn't exactly give me much to work with). Since this is only for bugs and
release notices, I'll post the bug/bugfix here whenever we figure out what it is.

ryan.lane wrote:

Version 1.1a of the LdapAuthentication.php plugin (for Mediawiki 1.6+)

This is a major version update of the plugin. A number of options have changed
syntax, and a new form of authentication, using autoauthenticate, has been
added. Updated documentation should follow shortly; you may not want to use
this version until the documentation is available. The following has changed
with this version:

Fixed bug in getGroups, searchNestedGroups, and isMemberOfRequiredLdapGroup

where warnings are thrown if no groups are found. This was a symptom of a
problem in Comment #133 (this would not fix that issue however).

  1. Fixed bug with pulled preferences not being saved in the local database.
  2. Options have changed to work for multiple domains. All options that make

sense with multi-domain support can be configured to work for multiple domains.

Smartcard/CAC support has been added to the plugin using the AutoAuthenticate

hook.
#* Most options supported by password authentication are supported in smartcard
authentication
#* Only a single smartcard domain can be used due to the way AutoAuthenticate
works; however, smartcard authentication and password authentication can be
mixed allowing multiple domains through the use of clever hackery
#* Smartcard authentication does not have to be turned on for the entire
server, but can instead be turned on for certain locations, or even specific
wiki pages

Smartcard authentication requires the getCanonicalName() function which is only
available in MediaWiki 1.6+. Do not use this version of the plugin for
mediawiki 1.5 as it has not been tested and will not be supported; instead,
please use version 1.0h.

attachment LdapAuthentication.php ignored as obsolete

michael wrote:

I receive this error the first time someone logs into the wiki. After a
refresh it is fine.

Fatal error: Call to a member function on a non-object in
c:\inetpub\wwwroot\wiki\includes\SpecialUserlogin.php on line 321

Which points to SpecialUserlogin.php

line 321--> if (!$u->checkPassword( $this->mPassword )) {

			$this->mainLoginForm( wfMsg( $this->mPassword == '' ? 'wrongpasswordempty' :

'wrongpassword' ) );

			return;
		}

Does anyone know a solution?

ryan.lane wrote:

(In reply to comment #143)

I receive this error the first time someone logs into the wiki. After a
refresh it is fine.

1: Don't change ANY of the information associated with this plugin in the
bugzilla, ever; you don't manage this plugin
2: This bugzilla page is for the LDAP plugin, not SpecialUserlogin
3: You didn't provide any information about your environment (like versions of
stuff)
4: This isn't a support forum; if you can't be bothered to pay attention to the
other comments that chastise people for asking support questions here, why
should I be bothered to pay attention to your problem?

You should probably post this to the mediawiki-l email list, taking into account
#3 in the above list. Unless you have a specific bug with the LdapAuthentication
plugin, don't post here.

ryan.lane wrote:

Version 1.1b of the LdapAuthentication.php plugin (for Mediawiki 1.6+)

This is a bugfix update of the LdapAuthentication plugin.

There was an issue with user's preferences being overwritten when
$wgLDAPRetrievePrefs was not set, or was set to false. The issue should only
have affected 1.1a; 1.0h should not be affected.

attachment LdapAuthentication.php ignored as obsolete

afhole wrote:

Patch to 1.1b including hacks to support NTLM

Attached:

afhole wrote:

Comment on attachment 2857
Patch to 1.1b including hacks to support NTLM

For Ryan's perusal, with a view to possibly include NTLM support

ryan.lane wrote:

Version 1.1c of the LdapAuthentication.php plugin (for Mediawiki 1.6+)

This is a bugfix and update version of the plugin (and an early christmas
present to all the enterprises out there). The following has been
changed/added:

  • Added support for Mediawiki security groups based upon LDAP groups
  • Added an option to disable auto-creation of accounts

($wgLDAPDisableAutoCreate)

  • Fixed TLS/SSL issue discussed in the Suggestions section on the Meta page
    • Removed options $wgLDAPUseSSL and $wgLDAPUseTLS; added option

$wgLDAPEncryptionType (a string) with allowed values "ssl", "tls", and "clear"

  • Moved $wgLDAPLowerCaseUsername a little higher up in the authentication chain
  • Added $wgLDAPGroupUseRetrievedUsername so that you can use the exact username

pulled from LDAP to search for groups

  • Changed $wgLDAPUseSmartcardAuth to $wgLDAPAutoAuthMethod (a string); this

will allow users to define which type of auto authenticate methods they would
like to use. Smartcard auth will only be available at first, but other methods
will follow.

  • Changed $wgLDAPGroupLowerCaseUsername to allow for multiple domains
  • Moved authenticate part of smartcard login out of getCanonicalName to the

SSLAuth function (I have no clue what I was thinking before ;) )

Updated documentation to follow at the usual spot. It may be a good idea to
wait until the documentation is updated before using this version. Hopefully
I'll have the documentation updated today.

attachment LdapAuthentication.php ignored as obsolete

antoine.musso wrote:

Ryan, can't you get subversion access to commit that in the extension
directory at http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/

That might be easier to get than using a bug report ?

hg wrote:

(In reply to comment #129)

(In reply to comment #128)

When will this adjustment be made? Meanwhile i did a dirty hack, which only
works for our environment...

Sorry, I've been out of the country, and my laptop was broken, so I haven't had
much of a chance to work on this. Hopefully I'll have a new release soon. I'll
try to have one out in the next couple of weeks.

What's about this?

ryan.lane wrote:

(In reply to comment #150)

What's about this?

Huh? If you are asking whether or not this was added... yes it was. Otherwise I
don't know what you mean.

ryan.lane wrote:

(In reply to comment #149)

Ryan, can't you get subversion access to commit that in the extension
directory at http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/

That might be easier to get than using a bug report ?

*shrug*

This has been a pretty easy way to do it so far. I use a subversion server
locally and send ready updates here. This also notified interested parties when
a new version is ready. If the developers would rather me use svn, and close
this ticket, I'm fine with that too. For the time being I'll keep the process
the same as to not confuse people who are used to coming here.

russ_lavoie wrote:

I am having a problem getting mediawiki 1.9.0 working with this plugin. I
downloaded the above that Ryan posted and added the below to the
Localsettings.php file:

require_once( 'LdapAuthentication.php' );
$wgAuth = new LdapAuthenticationPlugin();

$wgLDAPDomainNames = array("domain");
$wgLDAPServerNames = array(

"domain"=>"server.domain.com","server.domain.com");

$wgLDAPUseLocal = false;

LDAP BIND info

$wgLDAPProxyAgent = array(

"domain"=>"cn=ldapquery,cn=Users,dc=domain,dc=com");

$wgLDAPProxyAgentPassword = array(

"domain"=>"passwordgoeshere");

LDAP Login Restrictions

$wgLDAPRequiredGroups = array(

"domain"=>array("cn=wikigroup,ou=Groups,dc=domain,dc=com"));

$wgLDAPGroupSearchNestedGroups = array(

"domain"=>true);

I see traffic but no errors on the Windows server...

Can I get some assistance?

chris.porter wrote:

add $wfLDAPDebug = 3 to your LocalSettings.php file. I suspect it is complaining
about not being able to update user preferences. The way it is designed it wants
to update user preferences and write into the LDAP database. If you create a
"local" user account with the same name and password (to be secure) it should work.

ryan.lane wrote:

(In reply to comment #154)

add $wfLDAPDebug = 3 to your LocalSettings.php file. I suspect it is complaining
about not being able to update user preferences. The way it is designed it wants
to update user preferences and write into the LDAP database. If you create a
"local" user account with the same name and password (to be secure) it should

work.

*Sigh*. Maybe I *should* shut this bug page down and switch to svn... This isn't
the support page...

There is an outstanding bug with MediaWiki 1.9. The SpecialUserlogin.php and
User.php changes with regards to passwords conflict with authentication plugins.

Authentication plugins should return false if users aren't allowed to change
passwords, but the change password function in the plugin shouldn't be called
when users aren't allowed to change passwords. This isn't the case currently. I
need to file a bug report, but without being able to test 1.9 right now I can't
test a fix.

For the time being, please use the following workaround:

http://meta.wikimedia.org/wiki/Talk:LDAP_Authentication#Authentication_against_AD_does_not_work_using_1.9

Notice there is another bug that needs a workaround applied as well:

http://meta.wikimedia.org/wiki/Talk:LDAP_Authentication#User_creation_errors.2C_user_still_created

I plan on fixing the latter soon.

ryan.lane wrote:

Version 1.1d of the LdapAuthentication.php plugin (for Mediawiki 1.6+)

This is a bugfix version of the plugin. The following has changed:

  • Get the user's DN if straight binds are used with AD style binds

(DOMAIN\\USER-NAME, USER-NAME@DOMAIN) to allow for group checking, group
pulling, retrieving preferences, etc.

  • Fix the problem with group based restrictions causing failures even when they

aren't being used.

  • Allow $wgLDAPRequiredGroups to have uppercase letters, and automatically

convert to lowercase for comparison to search results.

  • Fix part of the compability issues with MediaWiki 1.9
  • Fix Talk:LDAP_Authentication#Bug_in_hasLDAPGroup.28.29_and_isLDAPGroup.28.29

If you want the plugin to pull the userdn when using AD style straight binds,
you'll need to set $wgLDAPBaseDNs, and $wgLDAPSearchAttributes for the domain.

Attached:

wpadroncu wrote:

Ryan, on Windows Server 2003 SP1, IIS 6, mediawiki 1.10, PHP 5.2.0,
LDAPAuthentication 1.1d

Problem: The getAllGroups function is not returning empty AD groups resulting in
incorrect user access permissions.

IMHO, must work this way, if a user has a wikimedia effective group 'nsGroup'
and the AD group 'nsGroup' has no members, the nsGroup must be removed from
user's effective groups because the user don't belongs to the AD group.

  • As a workaround i make a sysop a member of all AD groups used for sync.

garen_parham wrote:

Using MediaWiki 1.9.x, LdapAuthentication.php version 1.1d, and the the patch
listed here:

http://bugzilla.wikipedia.org/show_bug.cgi?id=8815

I can now successfully login against LDAP/AD! I do however see these two
warnings after login:

Notice: Undefined variable: updateLDAP in
/var/www/swtools/mediawiki-1.9.0/extensions/LdapAuthentication.php on line 596
Notice: Undefined variable: mailPassword in
/var/www/swtools/mediawiki-1.9.0/extensions/LdapAuthentication.php on line 596

It looks like those two variables aren't defined. If I add a simple "global
$updateLDAP, $mailPassword;" at the top of the function, the warnings go away.

ryan.lane wrote:

(In reply to comment #158)

Using MediaWiki 1.9.x, LdapAuthentication.php version 1.1d, and the the patchlisted

here:http://bugzilla.wikipedia.org/show_bug.cgi?id=8815I can now successfully login against LDAP/AD! I do however see
these twowarnings after login:Notice: Undefined variable: updateLDAP in/var/www/swtools/mediawiki-
1.9.0/extensions/LdapAuthentication.php on line 596Notice: Undefined variable: mailPassword
in/var/www/swtools/mediawiki-1.9.0/extensions/LdapAuthentication.php on line 596It looks like those two variables
aren't defined. If I add a simple "global$updateLDAP, $mailPassword;" at the top of the function, the warnings go
away.

Ah. Yeah, I see that. Neither of the variables are ever getting initialized. The fix is to add:

$updateLDAP = false;
$mailPassword = false;

before the if statements, so that the defaults get set (and the variables get initialized). This will be fixed next
release.

Ryan,

I'm using your extension with our PKI infrastructure (via the smartcard code)
and everything works fine. But for MediaWiki 1.9.1, I had to modify the
function SSLAuth() to make a new user before User::LoadFromSession is called
since this function is not ... whats the term... a static function? It makes
references to $this now. So anyway, I changed SSLAuth() to make an anonymous
user $tmpuser = new User(); and then called $tmpuser->LoadFromSession() in the
if statement below where $tmpuser->isLoggedIn() was being called
(LoadFromSession returns true if the user is logged in.)

jase700 wrote:

Ryan,

I left you a PM on mwusers.com. Here is the problem we are experiencing with the current plugin.

http://www.mwusers.com/forums/showthread.php?t=2812

many thanks,

jA

Another bug with 1.9.1 and 1.1d using PKI authentication (smartcard auth). When
a user attempts to log in and exists in the LDAP but not in the local database,
I get an infinite unstub loop (see the header of includes/StubObject.php for
more info). It's caused by SSLAuth creating a new LoginForm (~line 1551). If
the function gets to that point, it realizes the user is in the LDAP but not in
the local database and it tries to setup a new LoginForm to init the user.
However, something in the LoginForm chain fires the AutoAuthenticate hook again
which calls SSLAuth again hence the loop. I worked around this by adding a flag
to wgAuth called isBusy which gets set at the start of SSLAuth() and cleared
before that function returns. Then at the start of the function I check to see
if its set and if so return. This ensures that SSLAuth is never called twice in
one request.

ryan.lane wrote:

(In reply to comment #162)

Another bug with 1.9.1 and 1.1d using PKI authentication (smartcard auth). Whena user attempts to log in and exists

in the LDAP but not in the local database,I get an infinite unstub loop (see the header of includes/StubObject.php
formore info). It's caused by SSLAuth creating a new LoginForm (~line 1551). Ifthe function gets to that point, it
realizes the user is in the LDAP but not inthe local database and it tries to setup a new LoginForm to init the user.
However, something in the LoginForm chain fires the AutoAuthenticate hook againwhich calls SSLAuth again hence the
loop. I worked around this by adding a flagto wgAuth called isBusy which gets set at the start of SSLAuth() and
clearedbefore that function returns. Then at the start of the function I check to seeif its set and if so return.
This ensures that SSLAuth is never called twice inone request.

Thanks for the info on SSLAuth and 1.9.1. I'm not able to move to php5 yet, so I can't test anything above MediaWiki
1.6.x right now. Hopefully in a couple months I'll be able to start testing higher versions of MediaWiki, and these
problems will go away. Unfortunately, I won't be able to add your changes in until I've been able to test them.

I'll add these to the list of things I need to fix.

ryan.lane wrote:

The plugin will no longer be released on this bugzilla page. Instead, the
software will be hosted in MediaWiki's svn, new version releases will be
announced on mediawiki-l, support will be given at:
http://meta.wikimedia.org/wiki/Talk:LDAP_Authentication and plugin information
(including links to downloads) will be maintained at:
http://meta.wikimedia.org/wiki/LDAP_Authentication

bugzilla wrote:

Since I can't update the article at MW, I'll add this here. Trying to apply
group requirements to users, I was unable to find certain users in any groups
(in getGroups() function.) It turns out that if a DN has any special characters
in it, they need to be escaped. I made this change from 1.1d, and have had
success authenticating some users who had parentheses in their names:

@@ -1214,7 +1214,8 @@

$nameattribute = $wgLDAPGroupNameAttribute[$_SESSION['wsDomain']];

//Search for the groups this user is in
  • $filter = "(&($attribute=$dn)(objectclass=$objectclass))";

+ $filterdn = ($dn == '*') ? '*' : $filterdn =
preg_replace('/([\\*\\(\\)\\\])/', '\\\\$1', $dn);
+ $filter = "(&($attribute=$filterdn)(objectclass=$objectclass))";

$this->printDebug("Search string: $filter",2);

The ldap_search() function on line 1229 is what was failing; it would be nice if
that were checked for a non-boolean false value before proceeding with the search.

ryan.lane wrote:

(In reply to comment #165)

Since I can't update the article at MW, I'll add this here. Trying to apply
group requirements to users, I was unable to find certain users in any groups
(in getGroups() function.) It turns out that if a DN has any special characters
in it, they need to be escaped. I made this change from 1.1d, and have had
success authenticating some users who had parentheses in their names:

@@ -1214,7 +1214,8 @@

$nameattribute = $wgLDAPGroupNameAttribute[$_SESSION['wsDomain']];

//Search for the groups this user is in
  • $filter = "(&($attribute=$dn)(objectclass=$objectclass))";

+ $filterdn = ($dn == '*') ? '*' : $filterdn =
preg_replace('/([\\*\\(\\)\\\])/', '\\\\$1', $dn);
+ $filter = "(&($attribute=$filterdn)(objectclass=$objectclass))";

$this->printDebug("Search string: $filter",2);

The ldap_search() function on line 1229 is what was failing; it would be nice if
that were checked for a non-boolean false value before proceeding with the search.

You can't update a page that is writable by anyone in the world? Did you even
bother to read any of the documentation? This is something that is going to be
fixed next release; if you read the roadmap you'd have noticed this, or if you
took at look at the talk page, you'd also have noticed that many people have
sent in fixes for this (and I mentioned specifically that I'd be using one of
the fixes).

Do *not* comment on this closed bug, it is closed for a reason.