<?php
$session_name_new = "sidsuite_idp";
$session_name_org = session_name($session_name_new);

session_start();
$_SESSION['lang'] = 'en';
require_once("../lib/util.php");


$logid = 'IdsyncIdP';
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
	$log = &Log::singleton('syslog', LOG_LOCAL5, $logid);
} else {
	$opts = array('locking' => true, 'timeFormat' => '%Y/%m/%d %H:%M:%S');
	$log = &Log::singleton('file', '/opt/secioss/var/log/auth.log', $logid, $opts);
}

$conf = parse_ini_file("../conf/idsync.ini", true);
if (empty($conf)) {
	 $log->crit(logformat("Can't read idsync.ini"));
	 exit(1);
}
if (!isset($conf['password'])) {
	 $log->crit(logformat("Set password configuration"));
	 exit(1);
}
$pwconf = $conf['password'];

$code = 1;
$message = '';
$response_xml = 
'<?xml version="1.0" encoding="UTF-8"?>
<response>
  <code>%d</code>
  <message>%s</message>
</response>
';

if (isset($pwconf['multitenant']) && $pwconf['multitenant']) {
        if (isset($_SESSION['tenant'])) {
		$tenant = $_SESSION['tenant'];
	} else {
		$message = 'Not authenticated';
		printf($response_xml, $code, $message);
		exit(1);
	}

	$conn = ldap_connect($pwconf['uri']);
	ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
	$res = ldap_search($conn, $pwconf['basedn'], "(&(o=$tenant)(&(host=tenantlogin)(seciossAccountStatus=active)))");
        if ($res === false) {
                ldap_unbind($conn);
		$message = 'Can\'t get ldap configuration';
		printf($response_xml, $code, $message);
		exit(1);
        }

        $entries = ldap_get_entries($conn, $res);
        ldap_unbind($conn);
        $data = $entries[0]['description'][0];
        if (preg_match('/uri=(ldaps?:\/\/[a-zA-Z0-9\-. :\/]+)\/([^#]+)/', $data, $matches)) {
		$conf['password']['uri'] = $matches[1];
		$conf['password']['basedn'] = $matches[2];
	} else {
		$message = 'Invalid ldap configuration';
		printf($response_xml, $code, $message);
		exit(1);
	}
        if (preg_match('/userfilter=([^#]+)/', $data, $matches)) {
		$conf['password']['userfilter'] = $matches[1];
        }
        if (preg_match('/userattr=([^#]+)/', $data, $matches)) {
		$conf['password']['userattr'] = $matches[1];
	}
	$conf['password']['binddn'] = urldecode($entries[0]['uid'][0]);
	$conf['password']['bindpw'] = desDecrypt($entries[0]['seciossencryptedpassword'][0]);
} else {
	if (isset($_SESSION['authuser']) && isset($_SESSION['authpwd'])) {
		$conf['password']['binddn'] = $_SESSION['authuser'];
		$conf['password']['bindpw'] = $_SESSION['authpwd'];
	}
	else {
		$message = 'Not authenticated';
		printf($response_xml, $code, $message);
		exit(1);
	}
}
if (isset($_GET['username']) && isset($_POST['password'])) {
	$username = $_GET['username'];
	if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
		$username = mb_convert_encoding($username, "SJIS", "UTF-8");	// usernameをUTF-8からSJISへ変更
	}
	$_SERVER['REMOTE_USER'] = $username;
}
else {
	$message = 'Username or password is not set';
	printf($response_xml, $code, $message);
	exit(0);
}


if (!isset($pwconf['pwhash'])) {
	$conn = ldap_connect($conf['password']['uri']);
	ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
	$res = ldap_read($conn, '', '(objectClass=*)');
	if ($res) {
		$entries = ldap_get_entries($conn, $res);
		if (isset($entries[0]['rootdomainnamingcontext'])) {
			$conf['password']['pwhash'] = 'AD';
			$conf['password']['pwdattr'] = 'unicodePwd';
		}
		ldap_unbind($conn);
	}
}
$login = new AutoLogin('LDAP', $conf['password'], null);
$rc = $login->setUser($username, true);
if (PEAR::isError($rc)) {
	$log->err(logformat("Changing password failed: ". $rc->getMessage()));
	//$message = USS_ERR_003;
	$message = "Changing password failed: ".$rc->getMessage();
}
else if (isset($_POST['password']) /*&& checkCsrf($csrf)*/) {
	$password = $_POST['password'];

	$rc = $login->changePasswd($password, false);
	if (PEAR::isError($rc)) {
		switch($rc->getCode()) {
			case AUTO_LOGIN_INVALID_VALUE:
				$log->err(logformat("Password is invalid: ".$rc->getMessage()));
				$message = USS_ERR_001;
				break;
			case AUTO_LOGIN_MIN_AGE:
				$log->err(logformat("Minimum time doesn't elapse between modification to the password"));
				$message = USS_ERR_005;
				break;
			case AUTO_LOGIN_IN_HISTORY:
				$log->err(logformat("Password is in the history"));
				$message = USS_ERR_006;
				break;
			case AUTO_LOGIN_WEAK_PASSWD:
			case AUTO_LOGIN_WEAK_PASSWD_WARN:
				$errmsg = $rc->getMessage();
				if (preg_match('/too short/', $errmsg)) {
					$message = USS_ERR_011;
				} else if (preg_match('/DIFFERENT characters/', $errmsg)) {
					$message = USS_ERR_401;
				} else if (preg_match('/all whitespace/', $errmsg)) {
					$message = USS_ERR_402;
				} else if (preg_match('/too simplistic\/systematic/', $errmsg)) {
					$message = USS_ERR_403;
				} else if (preg_match('/National Insurance number/', $errmsg)) {
					$message = USS_ERR_403;
				} else if (preg_match('/dictionary word/', $errmsg)) {
					$message = USS_ERR_404;
				}
				if ($rc->getCode() == AUTO_LOGIN_WEAK_PASSWD) {
					$log->err(logformat("Password is weark: $errmsg"));
				} else {
					$log->err(logformat("Changing password succeeded but password is weak: $errmsg"));
					$message = USS_NML_001."<br>($message)";
				}
				break;
			case AUTO_LOGIN_MIN_PASSWD:
				$log->err(logformat("Password length is too short"));
				$message = USS_ERR_011;
				break;
			case AUTO_LOGIN_MAX_PASSWD:
				$log->err(logformat("Password length is too long"));
				$message = USS_ERR_012;
				break;
			default:
				$log->err(logformat("Changing password failed: ". $rc->getMessage()));
				//$message = USS_ERR_002;
				$message = "Changing password failed: ".$rc->getMessage();
		}
	}
	else if ($rc) {
		$code = 0;
		$log->notice(logformat("Changing password succeeded"));
		$message = USS_NML_001;
		if (!isset($_COOKIE['auth_tkt'])) {
			$_SESSION['password'] = $password;
		}
	}
}

printf($response_xml, $code, $message);

?>
