EternalWindows
アカウント管理 / パスワードの変更

既存ユーザーのパスワードを変更するには、NetUserChangePasswordを呼び出します。

NET_API_STATUS NetUserChangePassword(
  LPCWSTR domainname,
  LPCWSTR username,
  LPCWSTR oldpassword,
  LPCWSTR newpassword
);

domainnameは、ドメインの名前を指定します。 NULLを指定した場合は、ローカルドメインが対象になります。 usernameは、パスワードを変更するユーザーの名前を指定します。 oldpasswordは、ユーザーの前のパスワードを指定します。 newpasswordは、ユーザーの新しいパスワードを指定します。

NetUserChangePasswordを呼び出す例を次に示します。

#include <windows.h>
#include <lm.h>

#pragma comment (lib, "netapi32.lib")

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	NET_API_STATUS status;

	status = NetUserChangePassword(NULL, L"myuser", L"pass", L"newpass");
	if (status != NERR_Success) {
		if (status == ERROR_INVALID_PASSWORD)
			MessageBox(NULL, TEXT("パスワードが正しくありません。"), NULL, MB_ICONWARNING);
		else
			MessageBox(NULL, TEXT("パスワードの変更に失敗しました。"), NULL, MB_ICONWARNING);
		return 0;
	}

	MessageBox(NULL, TEXT("パスワード変更しました。"), TEXT("OK"), MB_OK);

	return 0;
}

myuserの現在のパスワードがpassである場合は、 パスワードがnewpassに変更されることになります。

NetUserChangePasswordを呼び出すには、前のパスワードが必要になりますから、 前のパスワードを忘れてしまった場合などは、この関数を呼び出すことはできません。 代わりに、パスワードを設定し直す必要があります。 こうした情報の設定を行うには、NetUserSetInfoを呼び出します。

NET_API_STATUS NetUserSetInfo(
  LPCWSTR servername,
  LPCWSTR username,
  DWORD level,
  LPBYTE buf,
  LPDWORD parm_err
);

servernameは、servernameは、この関数を実行するサーバー名を指定します。 NULLを指定した場合は、ローカルコンピュータで実行されます。 usernameは、情報を設定するユーザーの名前を指定します。 levelは、情報レベルを指定します。 bufは、設定する情報を格納したバッファを指定します。 parm_errは、エラーの原因となったメンバのインデックスを受け取る変数のアドレスを指定します。 どのメンバに問題があるのかを特定したくない場合は、NULLを指定しても問題ありません。

次に、NetUserSetInfoを呼び出してパスワードを設定する例を示します。

#include <windows.h>
#include <lm.h>

#pragma comment (lib, "netapi32.lib")

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	USER_INFO_1003 userInfo;
	
	userInfo.usri1003_password = L"newpass";

	if (NetUserSetInfo(NULL, L"myuser", 1003, (LPBYTE)&userInfo, NULL) != NERR_Success) {
		MessageBox(NULL, TEXT("パスワードの設定に失敗しました。"), NULL, MB_ICONWARNING);
		return 0;
	}

	MessageBox(NULL, TEXT("パスワードを設定しました。"), TEXT("OK"), MB_OK);

	return 0;
}

1003という情報レベルは、パスワードのみを設定したい場合に使用します。 上記コードを管理者として実行すれば、myuserのパスワードはnewpassになります。

パスワードを変更したいけれども、変更後のパスワードをユーザーに決定させたい場合は、 パスワードを期限切れにする方法があります。 次に、コード例を示します。

#include <windows.h>
#include <lm.h>

#pragma comment (lib, "netapi32.lib")

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	WCHAR        szUserName[] = L"myuser";
	PUSER_INFO_4 pUserInfo;

	if (NetUserGetInfo(NULL, szUserName, 4, (LPBYTE *)&pUserInfo) != NERR_Success)
		return 0;
	
	pUserInfo->usri4_flags &= ~UF_DONT_EXPIRE_PASSWD;
	pUserInfo->usri4_password_expired = 1;

	if (NetUserSetInfo(NULL, szUserName, 4, (LPBYTE)pUserInfo, NULL) != NERR_Success) {
		MessageBox(NULL, TEXT("パスワードの期限変更に失敗しました。"), NULL, MB_ICONWARNING);
		NetApiBufferFree(pUserInfo);
		return 0;
	}

	MessageBox(NULL, TEXT("パスワードを期限切れに設定しました。"), TEXT("OK"), MB_OK);
	NetApiBufferFree(pUserInfo);

	return 0;
}

パスワードの期限に関するメンバは、usri4_flagsとusri4_password_expiredです。 usri4_flagsにUF_DONT_EXPIRE_PASSWDが含まれている場合は、 パスワードが無期限ということになるため、これを外しておきます。 この状態でさらにusri4_password_expiredを1に設定すれば、 パスワードは期限切れの状態になります。 コンソールへのログオンの際にパスワードが期限切れになっている場合は、 パスワードの入力を促すダイアログが表示されるはずです。


戻る