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