I'm running MediaWiki 1.30.0 with the latest version of LDAP Authentication extension (master branch, commit aa165265357f0420ae8f17e5b8bd7e80f8febe79)
I need to support LDAP accounts and local accounts (MySQL), so I configured
$wgLDAPUseLocal = true;
which basically works, but I'm unable to create new local accounts at Special:CreateAccount...
As soon as I enter a user name (and leave the input field) a red box appears saying
Username entered already in use. Please choose a different name.
In the web developer toolbar, I can see a get request to WIKIBASE/api.php?action=query&format=json&list=users&ususers=blah23&usprop=cancreate&formatversion=2&errorformat=html&errorsuselocal=true&uselang=en -> I cannot see the selected domain here!?
(Not sure if that is already a bug? How is the API endpoint supposed to know under which domain I want to create the account? But maybe only local is supported and the domain-drop-down on that page is irrelevant?)
I ignore the message and nevertheless submit the form, the browser sends a POST request containing all the data (incl. domain):
wpName blah23 wpPassword test wpDomain local retype test email realname reason wpCreateaccount Create+account wpEditToken xxxx title Special:CreateAccount authAction create force wpCreateaccountToken xxxx
But it still says Username entered already in use. Please choose a different name. ...
So it seems as I cannot create a new local account...!?
If I disable the LDAP Authentication extension, the same POST request (just pressing F5 then) is working fine and a new account is being created..
Debugging
I already went a bit through the code, and if I understand correctly the check for existing users basically starts at AuthManager.php -> beginAccountCreation( User $creator, array $reqs, $returnToUrl ), where I can see it gets the domain in $reqs.
On line 1068 it then calls AuthManager.php -> canCreateAccount( $username, $options), which only retrieves the username:
$status = $this->canCreateAccount( $username, [ 'flags' => User::READ_LOCKING, 'creating' => true ] );
From canCreateAccount (line 943) the function AuthManager.php -> userExists ($username, $flags) is called, which then iterates getPrimaryAuthenticationProviders () to testUserExists..
Arriving at AuthPluginPrimaryAuthenticationProvider.php -> testUserExists( $username, $flags = User::READ_NORMAL ), it simply iterates every domain (as the domain information has been lost above) and checks the AuthPlugin::userExists():
foreach ( $domains as $domain ) { $this->auth->setDomain( $domain ); if ( $this->auth->userExists( $username ) ) { $this->auth->setDomain( $curDomain ); return true; } }
The LDAP Authentication extension in my case then always returns true (=user exists), as it cannot add LDAP users ([[ https://github.com/wikimedia/mediawiki-extensions-LdapAuthentication/blob/master/LdapAuthenticationPlugin.php#L497 | AddLDAPUsers is false]]). So even if I would introduce an (in my opinion) missing check for 'local' == $this->getDomain() at the LdapAuthentication extension, it will still fail, as AuthPluginPrimaryAuthenticationProvider.php -> testUserExists still checks for all domains (including LDAP domains..).
Workaround
As explained above, one option would be to temporarily disable LDAP Authentication.
Another option is to create a new local account with a command line call for eg.
php maintenance/createAndPromote.php USER PASS
which apparently doesn't check all these things..
However, I don't want to grant command line access to the users/maintainers of the wiki.
Solution
Does anyone have an idea how to fix that issue?
I'm not sure, but I guess the AuthManager.php -> canCreateAccount( $username, $options) should also know about the domain, in which the user should be created? And then also provide this information to AuthPluginPrimaryAuthenticationProvider.php -> testUserExists( $username, $flags = User::READ_NORMAL ), which doesn't check the LDAP extension for local accounts (or provides the domain to the LDAP extension, which then knows where/what/if to check..)?