2009-06-26 53 views
1

我想知道,如果一個Windows帳戶是密碼保護。C#:如何弄清楚,如果一個Windows帳戶是密碼保護

出於安全原因,您無法獲取密碼,這很清楚,但必須有辦法找出密碼是否已設置。

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

試圖登錄爲他們= P – DevinB 2009-06-26 14:26:22

回答

0

如果你能得到的UPN名或用戶令牌對於給定的帳戶(user對象的屬性之一應該告訴你),那麼你就應該能夠使用WindowsIdentity類是這樣的:

using System.Security.Principal; 

// ... 

var identity = new WindowsIdentity("foo-UPN"); 
var requiresPassword = identity.AuthenticationType != string.Empty; 
+0

我測試的「identity.AuthenticationType」值與「的WindowsIdentity兩個帳戶GetCurrent()「,一個帶密碼,另一個沒有,在兩種情況下,值都是」NTLM「。 「DirectoryEntry用戶」也有一個「AuthenticationType」,但對於我測試的帳戶,它總是「安全」。 – Fry 2009-06-29 09:36:44

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 
}