2008-10-07 70 views
3

我必須在C#中以編程方式鎖定Active Directory中的用戶帳戶。以編程方式鎖定Active Directory帳戶

不幸的是,它不能通過userAccountControl屬性工作。每次我將userAccountControl設置爲528(=正常帳戶帶鎖定標誌)時,Active Directory將不會接受該值並將其重置爲512(=普通帳戶),而不會另行通知。

現在我試圖通過提供不正確的憑據來鎖定帳戶(見下文),但這也不起作用。

int retries = 0; 
while (!adsUser.IsAccountLocked && retries < MAX_LOCK_RETRIES) 
{ 
    retries++; 

    try 
    { 
     new DirectoryEntry(userPath, logonName, incorrectPassword).RefreshCache(); 
    } 
    catch (Exception) 
    { 
     /* ... */ 
    } 
    adsUser.GetInfo(); 
} 

任何想法?

回答

4

確保您用來禁用帳戶的帳戶具有足夠的權限來禁用帳戶。請參閱Microsoft的this example

0

一旦你擁有目錄輸入對象,這將起作用。

DirectoryEntry de = result.GetDirectoryEntry(); 
int val = (int)de.Properties["userAccountControl"].Value; 
de.Properties["userAccountControl"].Value = val | 0x0002; 
+0

這將禁用帳戶,這不會鎖定它。 – KoenVosters 2012-02-22 12:32:46

0

此代碼將工作於公元

/// <summary> 
/// Locks a user account 
/// </summary> 
/// <param name="userName">The name of the user whose account you want to unlock</param> 
/// <remarks> 
/// This actually trys to log the user in with a wrong password. 
/// This in turn will lock the user out 
/// </remarks> 
public void LockAccount(string userName) 
{ 
    DirectoryEntry user = GetUser(userName); 
    string path = user.Path; 
    string badPassword = "SomeBadPassword"; 
    int maxLoginAttempts = 10; 

    for (int i = 0; i &lt maxLoginAttempts; i++) 
    { 
     try 
     { 
      new DirectoryEntry(path, userName, badPassword).RefreshCache(); 
     } 
     catch (Exception e) 
     { 

     } 
    } 
    user.Close(); 
} 
1

鎖定用戶根據您的Active Directory的政策,可能需要交互式登錄嘗試鎖定帳戶。您可以使用LogonUser method of advapi32.dll來模擬這些。在我的測試中,我發現運行此循環100次並不能保證在域控制器上嘗試100次錯誤的密碼嘗試,所以您應該check the user is locked out,並在必要時進行更多嘗試。

對此的底線是您應該禁用帳戶而不是試圖鎖定它。有no functional difference between locked and disabled accounts。下面的代碼是一個黑客。

using System; 
using System.Runtime.InteropServices; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      IntPtr token = IntPtr.Zero; 
      string userPrincipalName = "[email protected]"; 
      string authority = null; // Can be null when using UPN (user principal name) 
      string badPassword = "bad"; 

      int maxTries = 100; 
      bool res = false; 

      for (var i = 0; i < maxTries; i++) 
      { 
       res = LogonUser(userPrincipalName, authority, badPassword, LogonSessionType.Interactive, LogonProvider.Default, out token); 
       CloseHandle(token); 
      } 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     static extern bool LogonUser(
      string principal, 
      string authority, 
      string password, 
      LogonSessionType logonType, 
      LogonProvider logonProvider, 
      out IntPtr token); 

     [DllImport("kernel32.dll", SetLastError = true)] 
     static extern bool CloseHandle(IntPtr handle); 
     enum LogonSessionType : uint 
     { 
      Interactive = 2, 
      Network, 
      Batch, 
      Service, 
      NetworkCleartext = 8, 
      NewCredentials 
     } 

     enum LogonProvider : uint 
     { 
      Default = 0, // default for platform (use this!) 
      WinNT35,  // sends smoke signals to authority 
      WinNT40,  // uses NTLM 
      WinNT50  // negotiates Kerb or NTLM 
     } 
    } 
} 
相關問題