Last modified: 2007-03-13 13:10:33 UTC
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'> </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'> </td></tr><tr> + <td colspan='3' align='left'> + <p>$efl<br />"); + + if ( !wgUseLDAP) { $wgOut->addHTML(" - <tr><td colspan='3'> </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 @@ } } ?> +
I am going to review and test a bit this patch in the next day. LDAP authentication is something I am really interested in :o) Thanks Ryan !
Something to note when you test is that passwords are not encrypted when they are sent to the LDAP server. My write up on how to use it would try to enforce the idea of keeping SSL on (which it is by default).
Hmm, it seems I forgot to mention how to use my patch. My apologies. Here is a quick rundown: I've added 6 options to DefaultSettings.php and LocalSettings.php which are the following when used by an admin: $wgUseLDAP = true; $wgLDAPDomainNames = array("testADdomain","testLDAPdomain"); $wgLDAPServerNames = array("testADdomain"=>"testADserver.example.com","testLDAPdomain"=>"testLDAPserver.example.com testLDAPserver2.example.com"); $wgLDAPSearchStrings = array("testADdomain"=>"TDOMAIN\\USER-NAME", "testLDAPdomain"=>"cn=USER-NAME,ou=people,dc=example,dc=com"); $wgLDAPUseSSL = true; $wgLDAPUseLocal = true; In this example, there are three different domains, one is local, one is an Active Directory domain, and the other is a normal LDAP domain (Sun directory server, openLDAP, etc). The user must provide the search string for a user's distinguished name (USER-NAME is substituted in SpecialUserLogin.php with the actual user's loginname). Using SSL is optional (although it is the default) and so is using the local domain (which is the wiki itself, and is not on by default). Of course, using LDAP is off by default. When using LDAP, passwords are not stored in the database (unless users create accounts on the local domain). Blank passwords are no longer allowed since we wouldn't want people using the local domain logging in as domain users. The interface for logging in is slightly different when using LDAP as well. Since the LDAP directory will be managing user accounts and passwords, I have removed the "mail me a new password" button, and the validate password field (unless $wgLDAPUseLocal is true). I have added a selection box that will allow users to choose which domain they wish to authenticate against (in the above example, the options would be "testADdomain", "testLDAPdomain", and "local"). A few problems i have are not how I have it currently implemented, but with features that could be added later. For instance, large sites (wikipedia, and the like) i'm sure do not want to handle user accounts manually; small sites, and organizations that use it internally probably do. A feature that could be added to the basic LDAP authentication is the ability for the wiki to add user accounts and manage passwords like it does currently (locally). The problem with this is that most LDAP directories cannot work in this fashion. For instance, if the wiki was to mail a new password to a user, it would need to change the password on the LDAP directory which would cause the user's old password to no longer work. Obviously this is a huge DoS situation. Adding user accounts is less of a problem, but because of time considerations, I cannot implement it.
A couple bug fixes to the patch... in includes/SpecialUserlogin.php there is one typo (a missing dollar sign) and a minor bug... In function mainLoginForm $dom is uninitialized (spits out a Undef. Var. NOTICE to the log) it should be similar to: if ($wgUseLDAP) { $doms=""; // added this foreach ($wgLDAPDomainNames as $dom) { $doms = $doms . "<option>$dom</option>"; } if ($wgLDAPUseLocal) { $doms = $doms . "<option>local</option>"; } ... Also in function mainLoginForm the last few lines should read: if ( !$wgUseLDAP) { // fixed missing dollar sign $wgOut->addHTML("<input tabindex='10' type='submit' name=\"wpMailmypassword\" value=\"{$mmp}\"> /></p>"); } SB
Since the ability to use some external authentication system is a fairly general need, I'm adding a plugin hook for external authentication systems; it should be pretty straightforward to rearrange the LDAP code as an extension this way.
Bugfix: Can add local users with $wgLDAPUseLocal, but cannot login afterwards because the password isnt being stored in the wiki. Here is the fix. In SpecialUserLogin.php, in addNewAccountInternal(): - if ( !$wgUseLDAP ) { $u->setPassword( $this->mPassword ); } + if ( !$wgUseLDAP || 0 == strcmp('local', $this->mDomain) ) { $u->setPassword( $this->mPassword ); }
Bugfix: Adding accounts is not working when LDAP is enabled (unless you add local accounts). Here is the fix: In SpecialUserLogin.php, in addNewAccountInternal(): + $_SESSION["ldapdomain"] = $this; 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; } }
I added the link to the metawiki page about LDAP authentication. Changed to 1.5 (as I think, that I won't come with 1.4, am I correct ?) Tom
I have recoded this as an extension. However, it does require a minimal amount of core code changes. Specifically, I had to remove the ability for people to use create accounts with blank passwords or to logon with blank passwords. I also added a small interface change (which is done in a template), which needed a small modification of includes/SpecialUserLogin.php. Further core code modification will be required. Specifically, the way changing passwords works, and mailing temporary passwords. For the current extension, these features should be disabled when $wgAuth->strict() is true, since they would be useless. I have talked to Thomas Gries about merging the code with enotif. So a code diff may come from him. Ryan
(In reply to comment #9) > I have recoded this as an extension. However, it does require a minimal amount [...] > I have talked to Thomas Gries about merging the code with enotif. So a code diff > may come from him. > Ryan Ryan, just to confirm: I have read. Something coming in a while. (Please, can you have also an eye on the accompanying meta wikipages http://meta.wikipedia.org/LDAP_Authentication , which could be useful for our team work, too ? It's just a reminder and can perhaps help to collaborate.) Tom
Created attachment 254 [details] Diff of changes to 1.5 Diff of my changes to 1.5, and LdapAuthentication.php
Created attachment 282 [details] Patch for mediawiki 1.5 This is the current patch for mediawiki 1.5 to add LDAP Authentication. With this patch the wiki is able to pull a user email address, real name, nickname, and language preference from the LDAP directory. If the attributes in the LDAP server are blank, the wiki will use the preferences from the local database. This patch will NOT work with 1.4.
Created attachment 283 [details] Patch for mediawiki 1.4 This is the current patch for mediawiki 1.4 to add LDAP Authentication. With this patch the wiki is able to pull a user email address, real name, nickname, and language preference from the LDAP directory. If the attributes in the LDAP server are blank, the wiki will use the preferences from the local database. This patch will NOT work with 1.5.
Bugfix on last two patches (don't know HOW this got in here). In LdapAuthentication.php This: function initUser( &$user ) { # Override this to do something. //We are creating an LDAP user, it is very important that we do //NOT set a local password because it could compromise the //security of our domain. $user->setPassword( '' ); if ('' != $this->lang) { $u->setOption('language',$this->lang); } if ('' != $this->nickname) { $u->setOption('nickname',$this->nickname); } if ('' != $this->realname) { $u->setRealName($this->realname); } if ('' != $this->email) { $u->setEmail($this->email); } } Should be: function initUser( &$user ) { # Override this to do something. //We are creating an LDAP user, it is very important that we do //NOT set a local password because it could compromise the //security of our domain. $user->setPassword( '' ); if ('' != $this->lang) { $user->setOption('language',$this->lang); } if ('' != $this->nickname) { $user->setOption('nickname',$this->nickname); } if ('' != $this->realname) { $user->setRealName($this->realname); } if ('' != $this->email) { $user->setEmail($this->email); } }
Created attachment 287 [details] Updated patch to add LDAP authentication to mediawiki I'm on a roll this weekend! This patch adds the ability for the wiki to use an LDAP server to create users, update user information, change passwords, and pull information from an LDAP server. Unfortunately, updating users, and adding users does not currently work with Active Directory, and its likely the users are not able to mail themselves a password yet (with $wgAuth->strict() returning true). This patch is only for 1.5. A backport for 1.4 should be uploaded soon hopefully.
So ... if you can't add users with AD, how would you add users? What is different about AD's ldap interface that is causing problems? I'm tasked with getting auth against AD working and would be glad to help/hack however you need.
Let me state my confusion more precisely. By "adding users", I mean new wiki logins, not adding new users to AD through mediawiki. That being said, I haven't seen in my limited LDAP/AD/PHP experiments why adding users via AD is different than LDAP. Bugzilla does it just fine.
... what type of files are those last two patches? firefox seems to think they are binary.
Sorry to monopolize this bug all of a sudden. I've got an upgraded demo of my wiki site ready to test. It looks like the non-obsoleted patches in this bug are busted. Can you re-post the diffs as text/plain?
D'oh I see it's a .tar.gz now. If that is the case it shouldn't be labelled "patch" IMHO. I think just a single diff file would be preferrable for all involved anyway. My $0.02.
See also http://bugzilla.wikimedia.org/show_bug.cgi?id=1360 for Auto-Login / Auto-account-creation ( incl. working patch for 1.4 )
In my case auto-login isn't necessarily desirable. Full-bore LDAP support is needed. IMHO, you really shouldn't need a separate case for AD, since AD has a pretty standard LDAP interface. One catch in my instance is that I need to authenticate an "app user" first to then try and authenticate logins. Like I would have a "Wiki User" or "Bugzilla User".
OK. Your patch uses the actual bind as the authentication mechanism. What bugzilla does (and works in my AD case), is have a separate bind, and then do an LDAP search to verify the login. My in case, we only have a special set of users that can bind. I'll probably hack things around to get around this for now. Please let me know what you think of this idea.
GOD. Don't pay any attention to me. Please just ignore what I spout off without testing.
Created attachment 413 [details] Version .8 of the LDAP patch (For Mediawiki 1.4) Lol. I used to get emails when comments were being added to this page, but it seems i'm not getting them any more. I'll check here more often. All of my patches allow you to add new wiki users to the wiki db. What my new patches are starting to allow is for the wiki to use LDAP as a full blown backend. Instead of adding a user through your LDAP server to allow them access to the wiki, a user could create an account on the wiki, and a user would be added to the LDAP server. I am also allowing updates to user attributes through the wiki, because the next major versions of my plugin will allow full blown LDAP backend support, so that all user preferences and such are stored in LDAP. I've added options to allow/disallow this new behavior, since most people will not want this. There isn't a huge difference in adding users in AD. There is a slight problem with adding passwords to AD though. I will work around this soon hopefully. Also, there is a requirement in AD that you use SSL to add users/change passwords, etc. Also, in general, when adding new users through LDAP in AD, the user is created as disabled, without a password. I also don't have easy access to an AD when doing testing, or writing the patches, so AD support will be somewhat shaky (although, the original functionality should work with AD, even in the newest versions). When merging this plugin into your code, please do it by hand, people seem to be having problems merging with diff.
(In reply to comment #23) > OK. Your patch uses the actual bind as the authentication mechanism. What > bugzilla does (and works in my AD case), is have a separate bind, and then do an > LDAP search to verify the login. My in case, we only have a special set of > users that can bind. > > I'll probably hack things around to get around this for now. > > Please let me know what you think of this idea. In this case, you would have to have a proxyagent type user in your LDAP server, correct? I may add this as a user defined option, because not every unix/linux domain uses a proxyagent, and most AD domains do not. I do understand the need for it in some cases though, if your users are in multiple ou's, then a direct bind will not work.
(In reply to comment #26) > In this case, you would have to have a proxyagent type user in your LDAP server, > correct? I may add this as a user defined option, because not every unix/linux > domain uses a proxyagent, and most AD domains do not. I do understand the need > for it in some cases though, if your users are in multiple ou's, then a direct > bind will not work. Yes our users are in multiple ou's. For now I just added the single bind user and have it do a search to determine the individual user auth. Anyway, cheers on the work so far!
I'm trying to autheticate against AD. Finally it worked with these changes: LocalSettings.php: $wgLDAPSearchStrings = array( "testADdomain"=>"USER-NAME" ### instead of TDOMAIN\\USER-NAME ); When I login I get these warnings: Warning: ldap_read(): Search: Invalid DN syntax in /..../LdapAuthentication.php on line 150 Warning: ldap_get_entries(): supplied argument is not a valid ldap result resource in /..../LdapAuthentication.php on line 150 But it works.
I'd like to get any necessary changes to the core code or AuthPlugin interface ready in the 1.5 release so end users can easily drop in the LDAP extension. Ryan, is there a current patch for this ready to go?
(In reply to comment #29) > I'd like to get any necessary changes to the core code or AuthPlugin interface ready in the 1.5 > release so end users can easily drop in the LDAP extension. > > Ryan, is there a current patch for this ready to go? Brion, Give me a couple of days to get my new release out. It fixes the "Mail me a new password" problem that I was having. Otherwise, the 1.5 patch is mature enough for addition.
(In reply to comment #28) > I'm trying to autheticate against AD. Finally it worked with these changes: > > LocalSettings.php: > > $wgLDAPSearchStrings = array( > "testADdomain"=>"USER-NAME" ### instead of TDOMAIN\\USER-NAME > ); > > When I login I get these warnings: > Warning: ldap_read(): Search: Invalid DN syntax in /..../LdapAuthentication.php on line 150 > Warning: ldap_get_entries(): supplied argument is not a valid ldap result resource > in /..../LdapAuthentication.php on line 150 > > But it works. Well, TDOMAIN should be renamed to your actual domain. But if using just the username works, thats great too. Those two warnings you are getting is because of the DN syntax in your $wgLDAPSearchStrings. I really should update my documentation some. I'll clarify some though. My newest version of the patch allows the wiki to pull nickname, language, email address, real name, etc. from LDAP. To do so, the LDAP plugin reads an LDAP entry from the LDAP server. The problem with this is that it needs a complete DN. Your search string is not giving a full DN for your user, so the read is failing. This won't cause problems for you, because those preferences won't be overwritten unless they contain information (and if the read is failing, they do not). If you want this functionality, you'll have to give a full DN in the search strings. If all of your users are in the same OU (i believe this is generally the case in AD because it copies all users into ou=Users or something similar), then you can set your search string to be "sAMAccountName=USER-NAME,ou=Users,dc=domain,dc=com". If you have access to your domain controller, you can check this. You can probably also check it with an LDAP browser (there are a bunch freely available) even if you don't have access to the domain controller. I'm going to add an option for disabling reads in the next version so that you'll stop getting warnings.
Created attachment 551 [details] Version 1.0 of the LDAP patch (For Mediawiki 1.5) Sorry for the delay on the latest patch. This is version 1.0 of the LDAP authentication patch. This release should fix the "mail me a password" problem. This release also adds the ability to search for users through proxy credentials (this is useful if all of your users are not in the same ou). Also added is a option to disable fetching of user preferences. If you are currently using the LDAP patch to add users and set preferences, the option "$wgLDAPWikiDN" and "$wgLDAPWikiPassword" have been changed to "$wgLDAPWriterDN" and "$wgLDAPWriterPassword". This patch has been pretty well tested using openLDAP, and should work equally as well with Sun Directory Server. I have not had a chance to test this version of the patch with Active Directory. If you notice any problems with the new features on Active Directory, let me know (the normal authentication should work perfectly fine). Currently not working in this version, that will be fixed in the next is: If using proxy credentials, you can only use one domain, and the local domain. If using proxy credentials, you cannot add users to your LDAP server through the wiki (you can still add local users). I will hopefully post a 1.4 version of this patch in the next week. I will also update my documentation at: http://meta.wikimedia.org/wiki/LDAP_Authentication
I have one quick question about this patch.. Which is, with this patch will I be able to require authentication off of the LDAP (via a possible filter so only certain accounts can access it). And if you are not authenticated you can not see any content in the Wiki??? Or is the only way of accomplishing that via HTTP Auth?
(In reply to comment #33) > I have one quick question about this patch.. Which is, with this patch will I be > able to require authentication off of the LDAP (via a possible filter so only > certain accounts can access it). And if you are not authenticated you can not > see any content in the Wiki??? Or is the only way of accomplishing that via HTTP > Auth? Using just LDAP authentication (minimal options), the wiki will only authenticate users in LDAP, not users in the mysql database. You should be able to use the normal options for stopping users from viewing and editing pages unless they are logged in. Filtering users is left upon you. One way to filter would be to have a seperate OU for wiki users. Another way would be to use a proxyagent (available this version, see the caveats), and make an aci that only allows the proxyagent to access specific users, or users in a specific group. A proxyagent searches the directory for a user matching the username, and then binds as the user. This is probably a good way to go. You shouldn't need HTTP auth at all using this patch.
(In reply to comment #34) > > One way to filter would be to have a seperate OU for wiki users. Another way > would be to use a proxyagent (available this version, see the caveats), and make > an aci that only allows the proxyagent to access specific users, or users in a > specific group. A proxyagent searches the directory for a user matching the > username, and then binds as the user. This is probably a good way to go. > So there is no way to currently specify an LDAP filter? ie. (wikiAcces=TRUE) for the proxy "Search" credentials?
(In reply to comment #35) > (In reply to comment #34) > > > > One way to filter would be to have a seperate OU for wiki users. Another way > > would be to use a proxyagent (available this version, see the caveats), and make > > an aci that only allows the proxyagent to access specific users, or users in a > > specific group. A proxyagent searches the directory for a user matching the > > username, and then binds as the user. This is probably a good way to go. > > > > So there is no way to currently specify an LDAP filter? ie. (wikiAcces=TRUE) for > the proxy "Search" credentials? > No, not in this version. I will add this next version. If you want to add this yourself, the following code change should work: In LdapAuthentication.php (in function getUserDN() ), change: $filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=$username)"; to: $filter = str_replace("USER-NAME",$username,$wgLDAPSearchAttributes[$_SESSION['wsDomain']]); In LocalSettings.php, put (these are proxyagent settings, you'll still need $wgLDAPServerNames and $wgLDAPDomainNames): $wgLDAPProxyAgent = "cn=proxyagent,ou=profile,dc=base,dc=dn"; $wgLDAPProxyAgentPassword = "password"; //this should work with hashes btw $wgLDAPBaseDNs = array("yourdomainname"=>"dc=base,dc=dn"); $wgLDAPSearchAttributes = array("yourdomainname"=>"(uid=USER-NAME)(wikiAccess=TRUE)"); If you want to be able to update LDAP from the wiki, you'll need: $wgLDAPWriterDN = "cn=writer,dc=base,dc=dn"; $wgLDAPWriterPassword = "password"; //this should work with hashes $wgLDAPUpdateLDAP = true; //to set password, change preferences, etc
I've checked the changes to the core code into CVS HEAD, will be included in 1.5 so the plugin file can be dropped in easy.
wondering if the 1.0 patch has been back ported to 1.4 yet... I am having a bit of trouble getting any of the latest patches working with 1.4.5 and wanted to check before I started digging in. thanks!
(In reply to comment #38) > wondering if the 1.0 patch has been back ported to 1.4 yet... I am having a bit > of trouble getting any of the latest patches working with 1.4.5 and wanted to > check before I started digging in. thanks! No, sorry. I am probably dropping support for 1.4 in patches 1.0+. I've been extremely busy lately and its been hard to get time to work on this. The latest 1.4 patch should work for you though. It probably has the functionality you need (basic ssl encrypted LDAP authentication). If you need to use proxy credentials, that is only available in 1.0+, so you may be out of luck until mediawiki 1.5 comes out. I still haven't updated my documentation for patch 1.0, i'll try to get to that tonight (a couple variable names changed).
Ryan lane is working on this, not me :o)
Created attachment 787 [details] Patch DefaultSettings and Setup ($wgAuth) I want to suggest appling this patch to mediawiki above 1.5beta4. It will do the modifications described in the ticket for DefaultSettings.php and will setup the $wgAuth object in the Setup.php to the correct LdapAuthenticationPlugin() Regards, Dirk
It would be better if this: $wgLDAPUseSSL = false; was instead this: $wgLDAPUseSSL = true; In DefaultSettings.php, because it is very dangerous to not use SSL. Passwords are *NOT* sent across the line encrypted. To protect people, it would be better for the plugin to not work for them (because their server isn't set up correctly), than it would be for them to unknowingly send passwords across the line in the clear. Also, I don't know if the Setup.php additions are OK. I believe the reason AuthenticationPlugin.php was added was so that there could be multiple authentication plugins used just like extensions are now used. So it is probably better if the plugin is treated the same way as an extension (the way it is being used now).
I have added "$wgLDAPScope;" to the configuration file to search for the USER-NAME in the sub-scope OR in one-scope mode. example: # Scope is sub or one $wgLDAPScope = "sub"; following the patch for the patch version 1.4: --- LdapAuthentication.php Tue Aug 16 17:03:05 2005 +++ LdapAuthentication.php.old Tue Aug 16 15:13:54 2005 @@ -50,13 +50,16 @@ function userExists( $username ) { global $wgLDAPSearchStrings, $wgLDAPAddLDAPUsers; global $wgLDAPWikiDN, $wgLDAPWikiPassword; - global $wgLDAPScope; + //If we can't add LDAP users, we don't really need to check //if the user exists, the authenticate method will do this for //us. This will decrease hits to the LDAP server. if (!$wgLDAPAddLDAPUsers) { return true; } + + $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + $userdn = str_replace("USER-NAME",$username,$tmpuserdn); $ldapconn = $this->connect(); if ($ldapconn) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); @@ -67,25 +70,7 @@ //user, and we don't want that. return true; } - if($wgLDAPScope=="sub") - { - $userdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - preg_match("/(.*?)=USER-NAME/",$userdn,$attrmatch); - $searchattr=$attrmatch[1]; - $basedn=preg_replace("/.*?USER-NAME,/","",$userdn); - $search=ldap_search($ldapconn, $basedn, "($searchattr=$username)",$searchattr); - $info =ldap_get_entries($ldapconn, $search); - if($info["count"]==1) - { - $entry=ldap_first_entry($ldapconn,$search); - } - } - else - { - $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - $userdn = str_replace("USER-NAME",$username,$tmpuserdn); - $entry = @ldap_read($ldapconn, $userdn, "objectclass=*"); - } + $entry = @ldap_read($ldapconn, $userdn, "objectclass=*"); if (isset($wgLDAPProxyDN)) { //lets clean up @ldap_unbind(); @@ -145,46 +130,28 @@ */ function authenticate( $username, $password ) { global $wgLDAPSearchStrings; - global $wgLDAPScope; if ( '' == $password ) { return false; } - $ldapconn = $this->connect( ); - if ( $ldapconn ) { - if($wgLDAPScope=="sub") - { - $userdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); - preg_match("/(.*?)=USER-NAME/",$userdn,$attrmatch); - $searchattr=$attrmatch[1]; - $basedn=preg_replace("/.*?USER-NAME,/","",$userdn); - $search=ldap_search($ldapconn, $basedn, "($searchattr=$username)"); - $entry=ldap_first_entry($ldapconn,$search); - $binddn=ldap_get_dn($ldapconn,$entry); - $bind = @ldap_bind( $ldapconn, $binddn, $password ); - if (!$bind) { - return false; - } - } - else - { - $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - $userdn = str_replace("USER-NAME",$username,$tmpuserdn); - $bind = @ldap_bind( $ldapconn, $userdn, $password ); - if (!$bind) { - return false; - } - } - $entry = ldap_read($ldapconn, $binddn, "objectclass=*"); - $info = ldap_get_entries($ldapconn, $entry); - $this->email = $info[0]["mail"][0]; - $this->lang = $info[0]["preferredlanguage"][0]; - $this->nickname = $info[0]["displayname"][0]; - $this->realname = $info[0]["cn"][0]; - // Lets clean up. - @ldap_unbind(); + $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + $userdn = str_replace("USER-NAME",$username,$tmpuserdn); + $ldapconn = $this->connect( ); + if ( $ldapconn ) { + ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); + $bind = @ldap_bind( $ldapconn, $userdn, $password ); + if (!$bind) { + return false; + } + $entry = ldap_read($ldapconn, $userdn, "objectclass=*"); + $info = ldap_get_entries($ldapconn, $entry); + $this->email = $info[0]["mail"][0]; + $this->lang = $info[0]["preferredlanguage"][0]; + $this->nickname = $info[0]["displayname"][0]; + $this->realname = $info[0]["cn"][0]; + // Lets clean up. + @ldap_unbind(); } else { return false; }
i confused the new and the old file with the diff command, now the right patch: --- LdapAuthentication.php.old Tue Aug 16 15:13:54 2005 +++ LdapAuthentication.php Tue Aug 16 17:03:05 2005 @@ -50,16 +50,13 @@ function userExists( $username ) { global $wgLDAPSearchStrings, $wgLDAPAddLDAPUsers; global $wgLDAPWikiDN, $wgLDAPWikiPassword; - + global $wgLDAPScope; //If we can't add LDAP users, we don't really need to check //if the user exists, the authenticate method will do this for //us. This will decrease hits to the LDAP server. if (!$wgLDAPAddLDAPUsers) { return true; } - - $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - $userdn = str_replace("USER-NAME",$username,$tmpuserdn); $ldapconn = $this->connect(); if ($ldapconn) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); @@ -70,7 +67,25 @@ //user, and we don't want that. return true; } - $entry = @ldap_read($ldapconn, $userdn, "objectclass=*"); + if($wgLDAPScope=="sub") + { + $userdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + preg_match("/(.*?)=USER-NAME/",$userdn,$attrmatch); + $searchattr=$attrmatch[1]; + $basedn=preg_replace("/.*?USER-NAME,/","",$userdn); + $search=ldap_search($ldapconn, $basedn, "($searchattr=$username)",$searchattr); + $info =ldap_get_entries($ldapconn, $search); + if($info["count"]==1) + { + $entry=ldap_first_entry($ldapconn,$search); + } + } + else + { + $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + $userdn = str_replace("USER-NAME",$username,$tmpuserdn); + $entry = @ldap_read($ldapconn, $userdn, "objectclass=*"); + } if (isset($wgLDAPProxyDN)) { //lets clean up @ldap_unbind(); @@ -130,28 +145,46 @@ */ function authenticate( $username, $password ) { global $wgLDAPSearchStrings; + global $wgLDAPScope; if ( '' == $password ) { return false; } + $ldapconn = $this->connect( ); + if ( $ldapconn ) { + if($wgLDAPScope=="sub") + { + $userdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); + preg_match("/(.*?)=USER-NAME/",$userdn,$attrmatch); + $searchattr=$attrmatch[1]; + $basedn=preg_replace("/.*?USER-NAME,/","",$userdn); + $search=ldap_search($ldapconn, $basedn, "($searchattr=$username)"); + $entry=ldap_first_entry($ldapconn,$search); + $binddn=ldap_get_dn($ldapconn,$entry); + $bind = @ldap_bind( $ldapconn, $binddn, $password ); + if (!$bind) { + return false; + } + } + else + { + $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; + $userdn = str_replace("USER-NAME",$username,$tmpuserdn); + $bind = @ldap_bind( $ldapconn, $userdn, $password ); + if (!$bind) { + return false; + } + } - $tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']]; - $userdn = str_replace("USER-NAME",$username,$tmpuserdn); - $ldapconn = $this->connect( ); - if ( $ldapconn ) { - ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); - $bind = @ldap_bind( $ldapconn, $userdn, $password ); - if (!$bind) { - return false; - } - $entry = ldap_read($ldapconn, $userdn, "objectclass=*"); - $info = ldap_get_entries($ldapconn, $entry); - $this->email = $info[0]["mail"][0]; - $this->lang = $info[0]["preferredlanguage"][0]; - $this->nickname = $info[0]["displayname"][0]; - $this->realname = $info[0]["cn"][0]; - // Lets clean up. - @ldap_unbind(); + $entry = ldap_read($ldapconn, $binddn, "objectclass=*"); + $info = ldap_get_entries($ldapconn, $entry); + $this->email = $info[0]["mail"][0]; + $this->lang = $info[0]["preferredlanguage"][0]; + $this->nickname = $info[0]["displayname"][0]; + $this->realname = $info[0]["cn"][0]; + // Lets clean up. + @ldap_unbind(); } else { return false; }
Hi, I am trying for a whole day to get the ldap authentication running under 1.4.7 and 1.5beta4 but nothing works could anyone provide his/her running version, not in diff files, but in the already changed php files? Everytime I try to patch some files something goes wrong, not all patches succeed and so on. Thanks a lot. Johannes
Please try patching the code by hand, and not using the patch command. A few people have reported trouble when using the patch command. Also, make sure you are using the right version of the patch for the right version of the wiki. version 1.0 of the patch will not work with the 1.4 series of mediawiki. With 1.5, I believe that the code had already been added to the main source, all you should have to do is drop in the LDAP Authentication Plugin and include it into the LocalSettings.php. I just updated my documentation at: http://meta.wikimedia.org/wiki/LDAP_Authentication to reflect the newest version of my patch (1.0). Use this for mediawiki 1.5. Use patch version .8 for mediawiki 1.4.
I’m new to PHP and therefore still have a long way to go. However, I’ve been asked to build a localized version for my company, using LDAP authentication. I’ve been trying to get this thing to work but no luck so far. I was wondering if you have a running version that you could send me please, or a link to a website that would help me step- by-step with the necessary patching. Your kind help is much appreciated. Warm Regards, Sarith
I’ve been trying to do the LDAP integration for Wiki but so far I am unable to get it working. My Version of Wiki is mediawiki-1.4.5 and the patch I am using is changes.8.14. Am I using the correct versions? My problem is this: I have manually patched the files and now am able to get my domain listed in the special user login page. I have made the necessary changes in the LocalSettings.php, DefaultSettings.php, AuthPlugin.php, User.php, Language.php, SpecialUserLogin.php, UserLogin.php files. However, when I go to the Special User Login page, type in my credentials as listed in the Active Directory of my company, and click on ‘Login’, all I see is a blank page on my browser. This is what I see in the URL: http://localhost/Wikipedia/index.php? title=Special:Userlogin&action=submitlogin&returnto=Main_Page Can you please help me with getting this up and running? Your expert inputs would be much appreciated. Thank you
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.
I found what seems to be a bug in the LdapAuthentication.php code that was affecting the "proxy:" mode; I fixed it on my running system and now have LDAP working in my MediaWiki! (Thanks, guys!) Here is what I had to change: --- LdapAuthentication.php.old 2005-09-18 05:46:50.000000000 -0400 +++ LdapAuthentication.php 2005-09-18 06:12:49.000000000 -0400 @@ -52,6 +52,7 @@ global $wgLDAPWriterDN, $wgLDAPWriterPassword; global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword; global $wgLDAPBaseDN; + global $wgLDAPSearchAttributes; //If we can't add LDAP users, we don't really need to check //if the user exists, the authenticate method will do this for @@ -64,8 +65,9 @@ $ldapconn = $this->connect(); if ($ldapconn) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); - if ($searchtype == "proxy" && isset($wgLDAPProxyAgent)) { + if ($this->SearchType == "proxy" && isset($wgLDAPProxyAgent)) { $userdn = $this->getUserDN($ldapconn, $username); + if ($userdn == '') { return false; } @@ -79,7 +81,8 @@ } if ($this->SearchType == 'proxy') { //we need to do a subbase search for the entry - $filter = "($wgLDAPSearchAttribute=$username)"; + $searchattr = $wgLDAPSearchAttributes[$_SESSION['wsDomain']]; + $filter = "($searchattr=$username)"; $entry = @ldap_search($ldapconn, $searchstring, $filter); } else { //search for the entry itself
I had to change every instance of ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); to ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0); in order to authenticate against our W2k3 servers.
Patch proposition for group membership : I slightly modified LdapAuthentication.php to provide support for group membership : a user is authenticated if he can bin to the ldap AND he is member of an ldap group (groupofnames or groupofuniques names). New setting : --- in LocalSettings.php or in DefaultSettings.php $wgLDAPGroupDN = "cn=test,ou=groups,dc=mycompany,dc=com" --- The patch is at the end of the comment. Default : only LDAP groups are supported (i.e. not posixgroups) If a person provides correct authentication (login/password) but isn't member of the group, the error message is still "Wrong password" or similar. The patch : --- LdapAuthentication.php.orig 2005-09-30 10:59:23.000000000 +0200 +++ LdapAuthentication.php 2005-09-30 11:30:05.000000000 +0200 @@ -146,7 +146,7 @@ global $wgLDAPWriterDN, $wgLDAPWriterPassword; global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword; global $wgLDAPSearchAttribute; - + global $wgLDAPGroupDN; if ( '' == $password ) { return false; } @@ -173,6 +173,9 @@ $this->nickname = $info[0]["displayname"][0]; $this->realname = $info[0]["cn"][0]; } + if ($wgLDAPGroupDN) { + return $this->isMemberOfLdapGroup($ldapconn, $userdn, $wgLDAPGroupDN); + } // Lets clean up. @ldap_unbind(); } else { @@ -510,6 +513,23 @@ $userdn = $info[0]["dn"]; return $userdn; } + + function isMemberOfLdapGroup($ldapconn, $userDN, $groupDN) { + global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword; + global $wgLDAPSearchAttributes; + $bind = @ldap_bind( $ldapconn, $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword ); + if (!$bind) { + return ''; + } + //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); + + } + + + } ?>
Using LDAP group is definitely a good idea. A++.
Am planning on patching User.php to set user rights according to group. Thoughts?
(In reply to comment #54) > Am planning on patching User.php to set user rights according to group. Thoughts? Sounds good. Patch against 1.5 CVS, as all the changes in my patch except for LdapAuthentication.php should be in the 1.5 branch already. On another topic: Could someone apply the last few patches that were submitted, against LdapAuthentication.php, and add it as the current patch please? I am unable to work on this right now as I don't have access to a non-work computer (I'm still evacuated from Katrina).
Created attachment 945 [details] Version 1.0a of the LdapAuthentication.php (For Mediawiki 1.5) (=v1.0 plus changes in #50 #51 and #52) Because of the wish from Ryan lane I applied the last few patches that were submitted against LdapAuthentication.php. For me it works fine.
So did LDAP auth not make into already-released 1.5.0?
I use Mediawiki 1.5.0 and the LdapAuthentication.php from your LDAP patch v1.0 to authenticate against our company AD. So far it is working fine. (In reply to comment #3) > The interface for logging in is slightly different when using LDAP as well.Since the LDAP directory will be managing user accounts and passwords, I haveremoved the "mail me a new password" button, and the validate password field(unless $wgLDAPUseLocal is true). I have added a selection box that will allowusers to choose which domain they wish to authenticate against (in the aboveexample, the options would be "testADdomain", "testLDAPdomain", and "local"). At first: I'm not very familiar with PHP, but: After reading your post i would expect that the "mail me a new password" button should disapear !? But even if i set $wgLDAPUseLocal=false the "mail me a new Password" button, and some other fields (Retype password, Create new account buttom, etc.) are always apearing on the user login page. Is this what you intented, and i only don't understand the coherences, or ist this a bug ? Second: Unfortunately the usernames (loginname) in out AD are very cryptic, like xy15. Is the any posibillity/option that not the "cn", like xy15, but the "displayname", like Smith John, of the AD/LDAP users is used as wiki username? For example: i would like to log into the wiki with name "xy15", but on the wiki history pages should apear "Smith John". It would be very handy for us, and maby for other people to... Thanks you, for any hints.
(In reply to comment #57) > So did LDAP auth not make into already-released 1.5.0? Yes, but only the changes to the core files (AuthPlugin.diff,Language.diff,SpecialPreferences.diff,SpecialUserlogin.diff,User.diff,Userlogin.diff) are included in the 1.5.0. For a new installation you still need the LdapAuthentication.php, witch is not included in the relase 1.5.0
Is there an FM for me to RT? Just curious how I set this up. Just drop it into a dir somewhere and it should show up as an option somewhere?
(In reply to comment #60) > Is there an FM for me to RT? Just curious how I set this up. Just drop it into > a dir somewhere and it should show up as an option somewhere? Did you happen to check out the URL at the top of this page? ;) http://meta.wikimedia.org/wiki/LDAP_Authentication
/me hangs his head in shame and plunges the knife deep into his belly.
(In reply to comment #58) > I use Mediawiki 1.5.0 and the LdapAuthentication.php from your LDAP patch v1.0 to authenticate against our company AD. So far it is working fine. > > At first: I'm not very familiar with PHP, but: After reading your post i would expect that the "mail me a new password" button should disapear !? > But even if i set $wgLDAPUseLocal=false the "mail me a new Password" button, and some other fields (Retype password, Create new account buttom, > etc.) are always apearing on the user login page. Is this what you intented, and i only don't understand the coherences, or ist this a bug ? > Well, actually, the patch allows for mailing of a new password now. It also allows for creation of new accounts and such. Originally the patch would remove those fields, but now the patch for 1.5 is pretty much just "LdapAuthentication.php", so if you would like to disable these, you can edit function "modifyUITemplate" in "LdapAuthentication.php" and add the following: $template->set( 'create', false ); $template->set( 'useemail', false ); > Second: Unfortunately the usernames (loginname) in out AD are very cryptic, like xy15. Is the any posibillity/option that not the "cn", like xy15, > but the "displayname", like Smith John, of the AD/LDAP users is used as wiki username? For example: i would like to log into the wiki with > name "xy15", but on the wiki history pages should apear "Smith John". It would be very handy for us, and maby for other people to... > > Thanks you, for any hints. Function "authenticate" in "LdapAuthentication.php" is where these attributes are retreived. I have nickname set to "displayname" and real name set to "cn". You may want to set real name to be "displayname" as well as the nickname. People should be able to log into the wiki using their usernames, and have their nickname or real name shown as their displayname if you do this.
(In reply to comment #63) > you can editfunction "modifyUITemplate" in "LdapAuthentication.php" and add the following: > > $template->set( 'create', false ); > $template->set( 'useemail', false ); Slowly but surely the single functions become more clearly to me. Thank you for your explanations, that works really nice for me! Perhaps you might want to add another variable, with controls this settings through the LocalSettings.php ? > Function "authenticate" in "LdapAuthentication.php" is where these attributesare > retreived. I have nickname set to "displayname" and real name set to "cn".You may > want to set real name to be "displayname" as well as the nickname.People should > be able to log into the wiki using their usernames, and have theirnickname or > real name shown as their displayname if you do this. Futher I changed in LdapAuthentication.php: $this->nickname = $info[0]["displayname"][0]; $this->realname = $info[0]["cn"][0]; into $this->nickname = $info[0]["displayname"][0]; $this->realname = $info[0]["displayname"][0]; but this does not work so far. After the login of a "new" user (=a user who have never been loged in bevor), the user settings (email, language, nickname (e.g.John Smith)) are correctly received from the AD, and are displayed in the user preferences. But the displayed Name in the upper right corner, and the link to the users page, are still named with the cryptic cn (e.g. xy15) an not with the displayname (e.g. Smith John). Have you any futher suggestions? Thank you.
(In reply to comment #64) > Slowly but surely the single functions become more clearly to me. Thank you for your explanations, that works really nice for me! Perhaps you might > want to add another variable, with controls this settings through the LocalSettings.php ? I was thinking about it, but it could possibly add quite a few new options, and since the template could be changed (and likely will be changed) by a lot of people when they localize their wiki, the options may not be worthwhile. > Futher I changed in LdapAuthentication.php: > > $this->nickname = $info[0]["displayname"][0]; > $this->realname = $info[0]["cn"][0]; > > into > > $this->nickname = $info[0]["displayname"][0]; > $this->realname = $info[0]["displayname"][0]; > > but this does not work so far. After the login of a "new" user (=a user who have never been loged in bevor), the user settings (email, language, > nickname (e.g.John Smith)) are correctly received from the AD, and are displayed in the user preferences. But the displayed Name in the upper right > corner, and the link to the users page, are still named with the cryptic cn (e.g. xy15) an not with the displayname (e.g. Smith John). > > Have you any futher suggestions? Thank you. Actually, now that I look into it, it seems that the name that shows in the upper right hand corner is the login name of the user. The real name and nickname do not seem to change how that is displayed. What should be displayed for your users is whatever they log in as; so, if your AD usernames are some weird cryptic name, then thats what will be shown.
Here's a patch that will add the ability to require the authenticated user to have a required attribute in order to get access to the wiki. I was inspired to do this by the require ldap-attribute of apache's mod_auth_ldap. I started v 1.0 before the changes were included to makeup 1.0a. Hopefully I have merged them properly, it does still work for me, though I didn't try the group member feature. If the patch doesn't work for you, I can provide the full file for better merging or comparison if that helps. I moved the proxy user check to getUserDN. I noticed wherever the getUserDN was called, a proxy check was done right before it, so I just incorporated it into the getUserDN function. Jeff 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. --- LdapAuthentication-1.0a.php 2005-10-28 14:47:28.000000000 -0700 +++ LdapAuthentication-require-attr.php 2005-10-28 14:45:35.000000000 -0700 @@ -168,12 +168,17 @@ if ( $ldapconn ) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0); - if ($searchtype == "proxy" && isset($wgLDAPProxyAgent)) { + // Add additional search even if non-proxy to see if the user + // has the optionally required attribute. This should really + // be done in the userExists section, but userExists also checks + // the wiki, and the user might be there if their role was once + // valid. + // Proxy check is moved to getUserDN, so we can apply the proxy + // and the authattribute filter in one location only. - jeff $userdn = $this->getUserDN($ldapconn, $username); if ($userdn == '') { return false; } - } $bind = @ldap_bind($ldapconn, $userdn, $password); if (!$bind) { return false; @@ -253,12 +258,11 @@ if ($ldapconn) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0); - if ($searchtype == "proxy" && isset($wgLDAPProxyAgent)) { + // Proxy checking moved to the getUserDN function - jeff $userdn = $this->getUserDN($ldapconn, $user->getName()); if ($userdn == '') { return false; } - } if (!isset($wgLDAPWriterDN)) { return false; } @@ -305,12 +309,11 @@ if ($ldapconn) { ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0); - if ($searchtype == "proxy" && isset($wgLDAPProxyAgent)) { + // Proxy checking moved to the getUserDN function - jeff $userdn = $this->getUserDN($ldapconn, $user->getName()); if ($userdn == '') { return false; } - } $bind = @ldap_bind( $ldapconn, $wgLDAPWriterDN, $wgLDAPWriterPassword ); if (!$bind) { return false; @@ -514,13 +517,29 @@ function getUserDN($ldapconn, $username) { global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword; - global $wgLDAPSearchAttributes; - $bind = @ldap_bind( $ldapconn, $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword ); - if (!$bind) { - return ''; + global $wgLDAPSearchAttributes, $wgLDAPRequireAuthAttribute; + global $wgLDAPAuthAttribute; + if ($searchtype == "proxy" && isset($wgLDAPProxyAgent)) { + $bind = @ldap_bind( $ldapconn, $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword ); + if (!$bind) { + return ''; + } + } else { + // Do the search anonymously + $bind = @ldap_bind( $ldapconn ); + if (!$bind) { + return ''; + } } + //we need to do a subbase search for the entry - $filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=$username)"; + // Check that the user also has the required attribute - jeff + if ($wgLDAPRequireAuthAttribute) { + $filter = "(" . $wgLDAPAuthAttribute[$_SESSION['wsDomain']] . ")"; + } else { + $filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=$username)"; + } + $entry = @ldap_search($ldapconn, $this->getSearchString($username), $filter); if (!$entry) { return ''; @@ -529,10 +548,10 @@ $userdn = $info[0]["dn"]; return $userdn; } - function isMemberOfLdapGroup($ldapconn, $userDN, $groupDN) { global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword; global $wgLDAPSearchAttributes; + $bind = @ldap_bind( $ldapconn, $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword ); if (!$bind) { return '';
Comment on attachment 787 [details] Patch DefaultSettings and Setup ($wgAuth) This patch may cause problems, and as such, I'm not recommending it.
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
(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 [details]? 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).
Created attachment 1036 [details] 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
Created attachment 1038 [details] 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.
Created attachment 1042 [details] 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.
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.
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?
(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.
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
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.
(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.
(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.
(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?
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.
oops, i meant comment #63 - sorry
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?
(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.
(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.
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 );
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
(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
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; }
(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); > # 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).
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; }
Created attachment 1412 [details] 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.
(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.
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.
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
Created attachment 1426 [details] 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.
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?
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!
(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.
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.
(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.
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.
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.
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 />
(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
(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.
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.
(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.
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,242c242,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.
(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,242c242,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?
(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,242c242,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.
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?
(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.
Created attachment 2050 [details] 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.
Created attachment 2218 [details] 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.
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); }
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.
(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.
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.
(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".
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?
(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.
(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']];
in setPassword function, to not eraze password, we can change : $pass = $this->getPasswordHash($pass); by $pass = $this->getPasswordHash($password);
(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.
(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...
(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
(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.
Created attachment 2697 [details] 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: # Comment #118 (lowercasing the username in the groups checking) # Comment #125 (redundant auth attr check) # 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).
I have problems with the group authentication, can anybody please help? My LDAP section looks like this: <code> # 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; # 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.
(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.
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); }
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.
(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
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); }
Created attachment 2798 [details] Ldap Group Support against 1.0e as described yesterday.
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.
(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.
Created attachment 2823 [details] 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). # Fixed bug with pulled preferences not being saved in the local database. # 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.
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?
(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.
Created attachment 2830 [details] 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.
Created attachment 2857 [details] Patch to 1.1b including hacks to support NTLM
Comment on attachment 2857 [details] Patch to 1.1b including hacks to support NTLM For Ryan's perusal, with a view to possibly include NTLM support
Created attachment 2924 [details] 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.
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 ?
(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?
(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.
(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.
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?
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.
(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.
Created attachment 3173 [details] 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.
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.
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.
(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.)
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.
(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.
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
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.
(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.