PHPでLdapを使用してユーザのパスワードを変更する方法

  • 2020.02.16
  • PHP
PHPでLdapを使用してユーザのパスワードを変更する方法

PHPからLdapを使用してユーザのパスワードを変更する方法を紹介します。
Active Directoryは、Windows Server 2016を想定しています。

パスワード変更手順

1.Ldapユーザでのコネクション接続
2.Ldapユーザでのバインド接続
3.ユーザの存在確認
4.ユーザでのバインド接続
5.無効アカウントの確認
6.アカウントのパスワード変更

サンプルソース

ldap関数については、公式のPHPマニュアルを参照してください。

パスワードは、UTF-16LEコードに変更する必要があります。
無効アカウントの確認は、ビット演算で確認する必要があります。
●パスワードで使える文字
ABCDEFGHIJKLMNPQRSTUVWXYZ
abcdefghijklmnpqrstuvwxyz
0123456789
!$%&()*+-/<=>?@[]{}
// Ldapサーバー
$ldap_server = "ldap://localhost:389";

// Ldapユーザー
$ldap_user = "ldapuser";

// ベースのDN
$base_dn = "OU=tset,DC=example,DC=com"; // DN

// アカウント
$user_id 	= "user01";   // パスワード変更するユーザ名
$user_password 	= "password"; // 新しいパスワード

// コネクション接続
$ldapconn = ldap_connect($ldap_server);
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

if(!$ldapconn){
	echo "コネクション接続できません";
	exit;
}
else{
	// バインド接続
	$ldapbind = ldap_bind($ldapconn, "CN=" . $ldap_user . "," . $base_dn, "password");
	
	if(!$ldapbind){
		//コネクション切断
		ldap_unbind($ldapconn);

		echo "バインド接続できません";
		exit;
	}
}

if($ldapconn!==false){

	// ユーザの存在確認
	$user_filter = "(sAMAccountName=" . $user_id . ")";
	$ldapres = ldap_search($ldapconn, $base_dn, $user_filter, array("distinguishedName"));

	if(ldap_count_entries($ldapconn, $ldapres)==0){
		echo "ユーザが存在しない";
	}
	else{
		// 無効の確認
		$user_filter = "(sAMAccountName=" . $user_id . ")";
		$attributes = array("useraccountcontrol");
		$ldapres = ldap_search($ldapconn, $base_dn, $user_filter, $attributes);
		$ldap_data = ldap_get_entries($ldapconn, $ldapres);

		$useraccountcontrol = $ldap_data["useraccountcontrol"][0];
		if(bindec((int)decbin((int)$useraccountcontrol & 2)) == 2){ //「2」は無効のこと
			echo "アカウントが無効となってます";
			exit;
		}
		else{
			// DN名の取得
			$ldapentry = ldap_first_entry($ldapconn, $ldapres);
			$distinguishedNameArr = ldap_get_values($ldapconn, $ldapentry, "distinguishedName");
			$distinguishedName = $distinguishedNameArr[0];

			//パスワード変更
			$replace_user = array();
			$replace_user["unicodePwd"] = mb_convert_encoding("\"" . $user_password . "\"", "UTF-16LE"); // 新しいバスワード
			$replace_user["pwdLastSet"] = 0; // パスワード変更を促す
			$replace_user["lockoutTime"] = 0; // ロック解除する

			$result = ldap_mod_replace($ldapconn, $distinguishedName, $replace_user);
			if($result){
				echo "パスワード変更が成功しました";
			}
			else{
				echo "パスワード変更が失敗しました";
			}
		}
	}

	//コネクション切断
	ldap_unbind($ldapconn);
}