我想知道,如果WindowsAccount受密码保护。
出于安全原因,你无法获得密码,这是明确的,但必须有办法,找出是否设置了密码。
public bool IsAccountPasswordProteced(String userName)
{
String entryString = "WinNT://" + Environment.MachineName + ",Computer";
DirectoryEntry dirEntry = new DirectoryEntry(entryString);
DirectoryEntry user = dirEntry.Children.Find(userName, "User");
// First try was to check the ADS_UF_PASSWD_NOTREQD flag.
// If this flag is set, the account has no password,
// but if not, both is possible.
int userFlags = (int)user.Properties["UserFlags"].Value;
return (userFlags & (int)ActiveDs.ADS_USER_FLAG.ADS_UF_PASSWD_NOTREQD) == 0;
// Second try was to check the PasswordAge.
int pwAge = (int)user.Properties["PasswordAge"].Value;
return pwAge > 0;
}
答案 0 :(得分:3)
如果没有更好的方法,我将使用LogonUser功能,但这不是我想要的方式。但它总比没有好。 如果我从本地帐户(不是通过网络,因为LogonType)和启用的帐户使用它,它应该可以工作。
我使用了这两个链接:
public bool IsAccountPasswordProtected(String userName)
{
String entryString = "WinNT://" + Environment.MachineName + ",Computer";
DirectoryEntry dirEntry = new DirectoryEntry(entryString);
DirectoryEntry user = dirEntry.Children.Find(userName, "User");
////EDIT: this flag can also be set, if the account has a password
//int userFlags = (int)user.Properties["UserFlags"].Value;
//if ((userFlags & (int)ActiveDs.ADS_USER_FLAG.ADS_UF_PASSWD_NOTREQD) != 0)
// return false;
IntPtr token;
bool result = LogonUser(
user.Name, Environment.UserDomainName,
"",
LogonTypes.Interactive,
LogonProviders.Default,
out token);
if (result)
{
CloseHandle(token);
return false;
}
else
{
int err = Marshal.GetLastWin32Error();
if (err == 1327) // ERROR_ACCOUNT_RESTRICTION
return false;
//if(err == 1331) // ERROR_ACCOUNT_DISABLED
return true;
}
}
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(
string principal,
string authority,
string password,
LogonTypes logonType,
LogonProviders logonProvider,
out IntPtr token);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
enum LogonTypes : uint
{
Interactive = 2,
Network,
Batch,
Service,
NetworkCleartext = 8,
NewCredentials
}
enum LogonProviders : uint
{
Default = 0, // default for platform (use this!)
WinNT35, // sends smoke signals to authority
WinNT40, // uses NTLM
WinNT50 // negotiates Kerb or NTLM
}
答案 1 :(得分:0)
如果您可以获取给定帐户的UPN名称或用户令牌(user
对象的某个属性应该告诉您),那么您应该只能使用WindowsIdentity
类像这样的东西:
using System.Security.Principal;
// ...
var identity = new WindowsIdentity("foo-UPN");
var requiresPassword = identity.AuthenticationType != string.Empty;