我必须在C#中以编程方式锁定Active Directory中的用户帐户。
不幸的是,它不能通过userAccountControl属性工作。每次我将userAccountControl设置为528(=普通帐户w /锁定标志)时,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();
}
有什么想法吗?
答案 0 :(得分:4)
确保您用于停用帐户的帐户具有足够的权限来停用帐户。请参阅Microsoft的this example。
答案 1 :(得分: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 = "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
}
}
}
答案 2 :(得分:0)
一旦你有目录条目对象,这将有效。
DirectoryEntry de = result.GetDirectoryEntry();
int val = (int)de.Properties["userAccountControl"].Value;
de.Properties["userAccountControl"].Value = val | 0x0002;
答案 3 :(得分:0)
此代码可用于锁定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 < maxLoginAttempts; i++)
{
try
{
new DirectoryEntry(path, userName, badPassword).RefreshCache();
}
catch (Exception e)
{
}
}
user.Close();
}