/** * Add a user to LDAP. * Return true if successful. * * @param User $user * @param string $password * @param string $email * @param string $realname * @return bool */ public function addUser($user, $password, $email = '', $realname = '') { $this->printDebug("Entering addUser", NONSENSITIVE); if (!$this->getConf('AddLDAPUsers') || 'local' == $this->getSessionDomain()) { $this->printDebug("Either the user is using a local domain, or the wiki isn't allowing users to be added to LDAP", NONSENSITIVE); // Tell the wiki not to return an error. return true; } if ($this->getConf('RequiredGroups')) { $this->printDebug("The wiki is requiring users to be in specific groups, and cannot add users as this would be a security hole.", NONSENSITIVE); // It is possible that later we can add users into // groups, but since we don't support it, we don't want // to open holes! return false; } $writer = $this->getConf('WriterDN'); if (!$writer) { $this->printDebug("The wiki doesn't have wgLDAPWriterDN set", NONSENSITIVE); // We can't add users without an LDAP account capable of doing so. return false; } $this->email = $user->getEmail(); $this->realname = $user->getRealName(); $username = $user->getName(); if ($this->getConf('LowercaseUsernameScheme')) { $username = strtolower($username); } $pass = $this->getPasswordHash($password); if ($this->connect()) { $writeloc = $this->getConf('WriteLocation'); $this->userdn = $this->getSearchString($username); if ('' == $this->userdn) { $this->printDebug("userdn is blank, attempting to use wgLDAPWriteLocation", NONSENSITIVE); if ($writeloc) { $this->printDebug("wgLDAPWriteLocation is set, using that", NONSENSITIVE); $this->userdn = $this->getConf('SearchAttribute') . "=" . $username . "," . $writeloc; } else { $this->printDebug("wgLDAPWriteLocation is not set, failing", NONSENSITIVE); // getSearchString will bind, but will not unbind LdapAuthenticationPlugin::ldap_unbind($this->ldapconn); return false; } } $this->printDebug("Binding as the writerDN", NONSENSITIVE); $bind = $this->bindAs($writer, $this->getConf('WriterPassword')); if (!$bind) { $this->printDebug("Failed to bind as the writerDN; add failed", NONSENSITIVE); return false; } // Set up LDAP objectclasses and attributes // TODO: make objectclasses and attributes configurable $values["uid"] = $username; // sn is required for objectclass inetorgperson $values["sn"] = $username; if (is_string($this->email)) { $values["mail"] = $this->email; } if (is_string($this->realname)) { $values["cn"] = $this->realname; } else { $values["cn"] = $username; } $values["userpassword"] = $pass; $values["objectclass"] = array("inetorgperson"); $result = true; # Let other extensions modify the user object before creation wfRunHooks('LDAPSetCreationValues', array($this, $username, &$values, $writeloc, &$this->userdn, &$result)); if (!$result) { $this->printDebug("Failed to add user because LDAPSetCreationValues returned false", NONSENSITIVE); LdapAuthenticationPlugin::ldap_unbind($this->ldapconn); return false; } $this->printDebug("Adding user", NONSENSITIVE); if (LdapAuthenticationPlugin::ldap_add($this->ldapconn, $this->userdn, $values)) { $this->printDebug("Successfully added user", NONSENSITIVE); LdapAuthenticationPlugin::ldap_unbind($this->ldapconn); return true; } $this->printDebug("Failed to add user", NONSENSITIVE); LdapAuthenticationPlugin::ldap_unbind($this->ldapconn); } return false; }