packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/lostpw.php
changeset 3 a044870a9d3d
equal deleted inserted replaced
2:700d61d93b1b 3:a044870a9d3d
       
     1 <?php
       
     2 
       
     3 require('includes/starthere.php');
       
     4 
       
     5 if ( !empty($_SERVER['PATH_INFO']) )
       
     6 {
       
     7 	if ( count($params = explode('/', $_SERVER['PATH_INFO'])) !== 4 )
       
     8 	{
       
     9 		redirect('/lostpw');
       
    10 	}
       
    11 	
       
    12 	list(,$uid,$timestamp,$token) = $params;
       
    13 	
       
    14 	try
       
    15 	{
       
    16 		$do_redirect = true;
       
    17 		if ( !preg_match('/^[a-z0-9]{3,32}$/', $uid) ||
       
    18 			 !preg_match('/^[a-f0-9]{8}$/', $timestamp) ||
       
    19 		  	 !preg_match('/^[a-f0-9]{40}$/', $token) )
       
    20 			throw new Exception("Request format is invalid");
       
    21 		
       
    22 		$ts_dec = hexdec($timestamp);
       
    23 		
       
    24 		if ( hash_hmac('sha1', "$uid%$ts_dec", $hmac_secret) !== $token )
       
    25 			throw new Exception("Request token is invalid");
       
    26 		
       
    27 		if ( abs(time() - $ts_dec) > (12 * 3600) )
       
    28 			throw new Exception("This link has expired. Please request another password reset.");
       
    29 		
       
    30 		$userinfo = ldap_get_user($uid);
       
    31 		
       
    32 		// handle a submit?
       
    33 		$do_redirect = false;
       
    34 		if ( !empty($_POST['password']) )
       
    35 		{
       
    36 			if ( ($result = test_password($_POST['password'])) !== true )
       
    37 				throw new Exception("Your new password $result.");
       
    38 			
       
    39 			if ( $_POST['password'] !== $_POST['password_confirm'] )
       
    40 				throw new Exception("The passwords you entered did not match.");
       
    41 			
       
    42 			if ( reset_password($uid, $_POST['password']) )
       
    43 			{
       
    44 				queue_message(E_NOTICE, "Your password has been reset. You can now log into the control panel.");
       
    45 				redirect('/lostpw');
       
    46 			}
       
    47 			else
       
    48 			{
       
    49 				throw new Exception("Internal error when performing password reset.");
       
    50 			}
       
    51 		}
       
    52 	}
       
    53 	catch ( Exception $e )
       
    54 	{
       
    55 		queue_message(E_ERROR, $e->getMessage());
       
    56 		if ( $do_redirect )
       
    57 			redirect('/lostpw');
       
    58 	}
       
    59 	
       
    60 	display_template('resetpw', array(
       
    61 			'userinfo' => $userinfo
       
    62 		));
       
    63 	
       
    64 	exit;
       
    65 }
       
    66 
       
    67 if ( !empty($_POST['email_or_username']) )
       
    68 {
       
    69 	try
       
    70 	{
       
    71 		global $_ldapconn, $ldap_user_basedn;
       
    72 		
       
    73 		$field = strstr($_POST['email_or_username'], '@') ? 'mail' : 'uid';
       
    74 		if ( $field == 'uid' && !preg_match('/^[a-z0-9]{3,32}$/', $_POST['email_or_username']) )
       
    75 		{
       
    76 			throw new Exception("Invalid username. Usernames can only contain 3-32 a-z and 0-9 (all lowercase) characters.");
       
    77 		}
       
    78 		
       
    79 		$search_filter = sprintf('(&(%s=%s)(objectClass=posixAccount))', $field, ldap_escape($_POST['email_or_username']));
       
    80 		$search_result = ldap_search($_ldapconn, $ldap_user_basedn, $search_filter);
       
    81 		
       
    82 		if ( !$search_result )
       
    83 		{
       
    84 			throw new Exception(ldap_error($_ldapconn));
       
    85 		}
       
    86 		
       
    87 		if ( ldap_count_entries($_ldapconn, $search_result) == 0 )
       
    88 		{
       
    89 			throw new Exception("Could not find any accounts that matched that $field.");
       
    90 		}
       
    91 		else if ( ldap_count_entries($_ldapconn, $search_result) > 1 )
       
    92 		{
       
    93 			throw new Exception("LDAP search query erroneously returned multiple results.");
       
    94 		}
       
    95 		
       
    96 		$userinfo = ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result)));
       
    97 		
       
    98 		if ( !isset($userinfo['mail']) )
       
    99 		{
       
   100 			throw new Exception("No e-mail address is registered to your account. Please contact the administrator to request a password reset.");
       
   101 		}
       
   102 		
       
   103 		$mail_censored = $mail = is_array($userinfo['mail']) ? $userinfo['mail'][ count($userinfo['mail']) - 1 ] : $userinfo['mail'];
       
   104 		
       
   105 		// smtp_mail($from, $to, $subject, $body, $headers = '')
       
   106 		$reset_link = sprintf('http://%s/lostpw/%s/%08x/%s', gethostname(), $userinfo['uid'], time(), hash_hmac('sha1', "{$userinfo['uid']}%" . time(), $hmac_secret));
       
   107 		$email_body = parse_template('emails/lostpw', array(
       
   108 				'userinfo' => $userinfo
       
   109 				, 'reset_link' => $reset_link
       
   110 				, 'ip' => $_SERVER['REMOTE_ADDR']
       
   111 			));
       
   112 			
       
   113 		$domainname = strtolower(get_default_kerberos_realm());
       
   114 		$mail_result = smtp_mail("accounts@$domainname", $mail, "$domainname password reset", $email_body, "From: $domainname accounts <accounts@$domainname>\r\nTo: {$userinfo['cn']} <$mail>");
       
   115 		
       
   116 		// censor e-mail address to keep deviants from scraping for it
       
   117 		if ( $field == 'uid' && preg_match('/^(.)(.*?)(.)@([a-z\.]+)$/', $mail, $match) )
       
   118 			$mail_censored = sprintf('%s%s%s@%s', $match[1], str_repeat('.', strlen($match[2])), $match[3], $match[4]);
       
   119 		
       
   120 		if ( $mail_result )
       
   121 		{
       
   122 			queue_message(E_NOTICE, "Password reset instructions have been mailed to $mail_censored.");
       
   123 		}
       
   124 		else
       
   125 		{
       
   126 			throw new Exception("Failed to send e-mail.");
       
   127 		}
       
   128 	}
       
   129 	catch ( Exception $e )
       
   130 	{
       
   131 		queue_message(E_ERROR, $e->getMessage());
       
   132 	}
       
   133 }
       
   134 
       
   135 display_template('lostpw');