3

C# でプログラムによって 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

4 に答える 4

4

アカウントを無効にするために使用しているアカウントに、アカウントを無効にするための十分な権限があることを確認してください。Microsoftのこの例を参照してください。

于 2008-10-07T14:39:56.897 に答える
2

このコードは、ADでユーザーをロックするために機能します

/// <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();
}
于 2011-10-28T14:53:51.890 に答える
1

Active Directory ポリシーによっては、アカウントをロックするために対話型ログインの試行が必要になる場合があります。LogonUseradvapi32.dllのメソッドを使用してそれらをシミュレートできます。私のテストでは、このループを 100 回実行しても、ドメイン コントローラーで 100 回の不正なパスワードの試行が保証されないことがわかったので、ユーザーがロックアウトされていることを確認し、必要に応じてさらに試行する必要があります。

これの要点は、アカウントをロックしようとするのではなく、アカウントを無効にする必要があるということです. ロックされたアカウントと無効なアカウントに機能的な違いはありません。以下のコードはハックです。

using System;
using System.Runtime.InteropServices;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr token = IntPtr.Zero;
            string userPrincipalName = "userID@domain.com";
            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
        }
    }
}
于 2015-02-17T16:01:09.773 に答える
0

ディレクトリエントリオブジェクトを取得すると、これが機能します。

DirectoryEntry de = result.GetDirectoryEntry();
int val = (int)de.Properties["userAccountControl"].Value;
de.Properties["userAccountControl"].Value = val | 0x0002;
于 2011-06-17T18:16:01.460 に答える