/** * Authenticate using currently logged in user */ private function authenticate($secondAttempt = false) { global $auth, $INPUT; // Ok, this is evil. We read the login information of the current user and forward it to the HTTPClient list($this->user, $sticky, $this->pass) = auth_getCookie(); // Logged in in second attempt is now in Session. if ($secondAttempt && !isset($this->user) && $INPUT->str('u') && $INPUT->str('p')) { // We hacked directly into the login mechanism which provides the login information without encryption via $INPUT $this->user = $INPUT->str('u'); $this->pass = $INPUT->str('p'); $sticky = $INPUT->str('r'); } else { $secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session $this->pass = $this->auth_decrypt($this->pass, $secret); } return isset($this->user); }
/** * Update user profile * * @author Christopher Smith <*****@*****.**> */ function updateprofile() { global $conf; global $lang; /* @var auth_basic $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; if (!$INPUT->post->bool('save')) { return false; } if (!checkSecurityToken()) { return false; } if (!actionOK('profile')) { msg($lang['profna'], -1); return false; } $changes = array(); $changes['pass'] = $INPUT->post->str('newpass'); $changes['name'] = $INPUT->post->str('fullname'); $changes['mail'] = $INPUT->post->str('email'); // check misspelled passwords if ($changes['pass'] != $INPUT->post->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // clean fullname and email $changes['name'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['name'])); $changes['mail'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['mail'])); // no empty name and email (except the backend doesn't support them) if (empty($changes['name']) && $auth->canDo('modName') || empty($changes['mail']) && $auth->canDo('modMail')) { msg($lang['profnoempty'], -1); return false; } if (!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } $changes = array_filter($changes); // check for unavailable capabilities if (!$auth->canDo('modName')) { unset($changes['name']); } if (!$auth->canDo('modMail')) { unset($changes['mail']); } if (!$auth->canDo('modPass')) { unset($changes['pass']); } // anything to do? if (!count($changes)) { msg($lang['profnochange'], -1); return false; } if ($conf['profileconfirm']) { if (!$auth->checkPass($_SERVER['REMOTE_USER'], $INPUT->post->str('oldpass'))) { msg($lang['badlogin'], -1); return false; } } if ($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) { // update cookie and session with the changed data if ($changes['pass']) { list(, $sticky, ) = auth_getCookie(); $pass = PMA_blowfish_encrypt($changes['pass'], auth_cookiesalt(!$sticky)); auth_setCookie($_SERVER['REMOTE_USER'], $pass, (bool) $sticky); } return true; } return false; }
/** * Return user info * * Returns info about the given user needs to contain * at least these fields: * * name string full name of the user * mail string email addres of the user * grps array list of groups the user is in * * This LDAP specific function returns the following * addional fields: * * dn string distinguished name (DN) * uid string Posix User ID * inbind bool for internal use - avoid loop in binding * * @author Andreas Gohr <*****@*****.**> * @author Trouble * @author Dan Allen <*****@*****.**> * @author <*****@*****.**> * @author Stephane Chazelas <*****@*****.**> * * @param string $user * @param bool $inbind authldap specific, true if in bind phase * @return array containing user data or false */ public function getUserData($user, $inbind = false) { global $conf; if (!$this->_openLDAP()) { return false; } // force superuser bind if wanted and not bound as superuser yet if ($this->getConf('binddn') && $this->getConf('bindpw') && $this->bound < 2) { // use superuser credentials if (!@ldap_bind($this->con, $this->getConf('binddn'), $this->getConf('bindpw'))) { $this->_debug('LDAP bind as superuser: '******'user'] = $user; $info['server'] = $this->getConf('server'); //get info for given user $base = $this->_makeFilter($this->getConf('usertree'), $info); if ($this->getConf('userfilter')) { $filter = $this->_makeFilter($this->getConf('userfilter'), $info); } else { $filter = "(ObjectClass=*)"; } $sr = $this->_ldapsearch($this->con, $base, $filter, $this->getConf('userscope')); $result = @ldap_get_entries($this->con, $sr); $this->_debug('LDAP user search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); $this->_debug('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); // Don't accept more or less than one response if (!is_array($result) || $result['count'] != 1) { return false; //user not found } $user_result = $result[0]; ldap_free_result($sr); // general user info $info['dn'] = $user_result['dn']; $info['gid'] = $user_result['gidnumber'][0]; $info['mail'] = $user_result['mail'][0]; $info['name'] = $user_result['cn'][0]; $info['grps'] = array(); // overwrite if other attribs are specified. if (is_array($this->getConf('mapping'))) { foreach ($this->getConf('mapping') as $localkey => $key) { if (is_array($key)) { // use regexp to clean up user_result list($key, $regexp) = each($key); if ($user_result[$key]) { foreach ($user_result[$key] as $grp) { if (preg_match($regexp, $grp, $match)) { if ($localkey == 'grps') { $info[$localkey][] = $match[1]; } else { $info[$localkey] = $match[1]; } } } } } else { $info[$localkey] = $user_result[$key][0]; } } } $user_result = array_merge($info, $user_result); //get groups for given user if grouptree is given if ($this->getConf('grouptree') || $this->getConf('groupfilter')) { $base = $this->_makeFilter($this->getConf('grouptree'), $user_result); $filter = $this->_makeFilter($this->getConf('groupfilter'), $user_result); $sr = $this->_ldapsearch($this->con, $base, $filter, $this->getConf('groupscope'), array($this->getConf('groupkey'))); $this->_debug('LDAP group search: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); $this->_debug('LDAP search at: ' . htmlspecialchars($base . ' ' . $filter), 0, __LINE__, __FILE__); if (!$sr) { msg("LDAP: Reading group memberships failed", -1); return false; } $result = ldap_get_entries($this->con, $sr); ldap_free_result($sr); if (is_array($result)) { foreach ($result as $grp) { if (!empty($grp[$this->getConf('groupkey')][0])) { $this->_debug('LDAP usergroup: ' . htmlspecialchars($grp[$this->getConf('groupkey')][0]), 0, __LINE__, __FILE__); $info['grps'][] = $grp[$this->getConf('groupkey')][0]; } } } } // always add the default group to the list of groups if (!$info['grps'] or !in_array($conf['defaultgroup'], $info['grps'])) { $info['grps'][] = $conf['defaultgroup']; } return $info; }
/** * Definition of the function modifyUser in order to modify the password * * @param string $user nick of the user to be changed * @param array $changes array of field/value pairs to be changed (password will be clear text) * @return bool true on success, false on error */ function modifyUser($user, $changes) { // open the connection to the ldap if (!$this->_openLDAP()) { $this->_debug('LDAP cannot connect: ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } // find the information about the user, in particular the "dn" $info = $this->getUserData($user, true); if (empty($info['dn'])) { $this->_debug('LDAP cannot find your user dn', 0, __LINE__, __FILE__); return false; } $dn = $info['dn']; // find the old password of the user list($loginuser, $loginsticky, $loginpass) = auth_getCookie(); if ($loginuser !== null) { // the user is currently logged in $secret = auth_cookiesalt(!$loginsticky, true); $pass = auth_decrypt($loginpass, $secret); // bind with the ldap if (!@ldap_bind($this->con, $dn, $pass)) { $this->_debug('LDAP user bind failed: ' . htmlspecialchars($dn) . ': ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } } elseif ($this->getConf('binddn') && $this->getConf('bindpw')) { // we are changing the password on behalf of the user (eg: forgotten password) // bind with the superuser ldap if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) { $this->_debug('LDAP bind as superuser: '******'pass']); // change the password if (!@ldap_mod_replace($this->con, $dn, array('userpassword' => $hash))) { $this->_debug('LDAP mod replace failed: ' . htmlspecialchars($dn) . ': ' . htmlspecialchars(ldap_error($this->con)), 0, __LINE__, __FILE__); return false; } return true; }
/** * This tries to login the user based on the sent auth credentials * * The authentication works like this: if a username was given * a new login is assumed and user/password are checked. If they * are correct the password is encrypted with blowfish and stored * together with the username in a cookie - the same info is stored * in the session, too. Additonally a browserID is stored in the * session. * * If no username was given the cookie is checked: if the username, * crypted password and browserID match between session and cookie * no further testing is done and the user is accepted * * If a cookie was found but no session info was availabe the * blowfish encrypted password from the cookie is decrypted and * together with username rechecked by calling this function again. * * On a successful login $_SERVER[REMOTE_USER] and $USERINFO * are set. * * @author Andreas Gohr <*****@*****.**> * * @param string $user Username * @param string $pass Cleartext Password * @param bool $sticky Cookie should not expire * @param bool $silent Don't show error on bad auth * @return bool true on successful auth */ function auth_login($user, $pass, $sticky = false, $silent = false) { global $USERINFO; global $conf; global $lang; global $auth; $sticky ? $sticky = true : ($sticky = false); //sanity check if (!$auth) { return false; } if (!empty($user)) { //usual login if ($auth->checkPass($user, $pass)) { // make logininfo globally available $_SERVER['REMOTE_USER'] = $user; auth_setCookie($user, PMA_blowfish_encrypt($pass, auth_cookiesalt()), $sticky); return true; } else { //invalid credentials - log off if (!$silent) { msg($lang['badlogin'], -1); } auth_logoff(); return false; } } else { // read cookie information list($user, $sticky, $pass) = auth_getCookie(); // get session info $session = $_SESSION[DOKU_COOKIE]['auth']; if ($user && $pass) { // we got a cookie - see if we can trust it if (isset($session) && $auth->useSessionCache($user) && $session['time'] >= time() - $conf['auth_security_timeout'] && $session['user'] == $user && $session['pass'] == $pass && $session['buid'] == auth_browseruid()) { // he has session, cookie and browser right - let him in $_SERVER['REMOTE_USER'] = $user; $USERINFO = $session['info']; //FIXME move all references to session return true; } // no we don't trust it yet - recheck pass but silent $pass = PMA_blowfish_decrypt($pass, auth_cookiesalt()); return auth_login($user, $pass, $sticky, true); } } //just to be sure auth_logoff(true); return false; }
/** * Update user profile * * @author Christopher Smith <*****@*****.**> */ function updateprofile() { global $conf; global $INFO; global $lang; global $auth; if (empty($_POST['save'])) { return false; } if (!checkSecurityToken()) { return false; } if (!actionOK('profile')) { msg($lang['profna'], -1); return false; } if ($_POST['newpass'] != $_POST['passchk']) { msg($lang['regbadpass'], -1); // complain about misspelled passwords return false; } //clean fullname and email $_POST['fullname'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $_POST['fullname'])); $_POST['email'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $_POST['email'])); if (empty($_POST['fullname']) && $auth->canDo('modName') || empty($_POST['email']) && $auth->canDo('modMail')) { msg($lang['profnoempty'], -1); return false; } if (!mail_isvalid($_POST['email']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } if ($_POST['fullname'] != $INFO['userinfo']['name'] && $auth->canDo('modName')) { $changes['name'] = $_POST['fullname']; } if ($_POST['email'] != $INFO['userinfo']['mail'] && $auth->canDo('modMail')) { $changes['mail'] = $_POST['email']; } if (!empty($_POST['newpass']) && $auth->canDo('modPass')) { $changes['pass'] = $_POST['newpass']; } if (!count($changes)) { msg($lang['profnochange'], -1); return false; } if ($conf['profileconfirm']) { if (!$auth->checkPass($_SERVER['REMOTE_USER'], $_POST['oldpass'])) { msg($lang['badlogin'], -1); return false; } } if ($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) { // update cookie and session with the changed data if ($changes['pass']) { list($user, $sticky, $pass) = auth_getCookie(); $pass = PMA_blowfish_encrypt($changes['pass'], auth_cookiesalt(!$sticky)); auth_setCookie($_SERVER['REMOTE_USER'], $pass, (bool) $sticky); } return true; } }
/** * Update user profile * * @author Christopher Smith <*****@*****.**> */ function updateprofile() { global $conf; global $lang; /* @var DokuWiki_Auth_Plugin $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; if (!$INPUT->post->bool('save')) { return false; } if (!checkSecurityToken()) { return false; } if (!actionOK('profile')) { msg($lang['profna'], -1); return false; } $changes = array(); $changes['pass'] = $INPUT->post->str('newpass'); $changes['name'] = $INPUT->post->str('fullname'); $changes['mail'] = $INPUT->post->str('email'); // check misspelled passwords if ($changes['pass'] != $INPUT->post->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // clean fullname and email $changes['name'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['name'])); $changes['mail'] = trim(preg_replace('/[\\x00-\\x1f:<>&%,;]+/', '', $changes['mail'])); // no empty name and email (except the backend doesn't support them) if (empty($changes['name']) && $auth->canDo('modName') || empty($changes['mail']) && $auth->canDo('modMail')) { msg($lang['profnoempty'], -1); return false; } if (!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } $changes = array_filter($changes); // check for unavailable capabilities if (!$auth->canDo('modName')) { unset($changes['name']); } if (!$auth->canDo('modMail')) { unset($changes['mail']); } if (!$auth->canDo('modPass')) { unset($changes['pass']); } // anything to do? if (!count($changes)) { msg($lang['profnochange'], -1); return false; } if ($conf['profileconfirm']) { if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { msg($lang['badpassconfirm'], -1); return false; } } if (!$auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), &$changes))) { msg($lang['proffail'], -1); return false; } if ($changes['pass']) { // update cookie and session with the changed data list(, $sticky, ) = auth_getCookie(); $pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true)); auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky); } else { // make sure the session is writable @session_start(); // invalidate session cache $_SESSION[DOKU_COOKIE]['auth']['time'] = 0; session_write_close(); } return true; }