C#:如果Windows帐户受密码保护,如何判断

时间:2009-06-26 14:21:08

标签: c# .net active-directory

我想知道,如果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;
}

2 个答案:

答案 0 :(得分:3)

如果没有更好的方法,我将使用LogonUser功能,但这不是我想要的方式。但它总比没有好。 如果我从本地帐户(不是通过网络,因为LogonType)和启用的帐户使用它,它应该可以工作。

我使用了这两个链接:

Calling LogonUser

Detect empty Passwords

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;