Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Windows 7 x64; Компьютер в домене; .NET Framework 4.0.

Требуется проверить статус доменной учётной записи: заблокирована или нет. Использую код, помеченный в качестве ответа здесь.

Проверяю код на двух записях: заблокированной и не заблокированной. Статус заблокированной записи предварительно подтвердили администраторы. На всякий случай я попробовал зайти под заблокированной учёткой и получил сообщение, что мол аккаунт отключен, обратитесь к администрации, так что одна из записей 100% заблокирована.

// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
 
// find a user
// Unlocked account
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "myAccount");
if (user != null) {
    string displayName = user.DisplayName;
 
    if (user.IsAccountLockedOut()) {
        Console.WriteLine("{0} is locked.", displayName);
    }
    else {
        Console.WriteLine("{0} is unlocked.", displayName); // I am here
    }
}
 
// find a user
// Locked account
UserPrincipal user2 = UserPrincipal.FindByIdentity(ctx, "lockedUserAccount");
if (user2 != null) {
    string displayName2 = user2.DisplayName;
 
    if (user2.IsAccountLockedOut()) {
        Console.WriteLine("{0} is locked.", displayName2);
    }
    else {
        Console.WriteLine("{0} is unlocked.", displayName2); // Oops... I am here again
    }
}


Однако по факту для обоих записей обозначенный код выдаёт идентичный результат - мол они обе не заблокированы... В качестве аккаунта указывал значение UserPrincipal.SamAccountName. Аккаунты уникальны в рамках домена.

Меня интересуют два вопроса:

1. Почему я получаю неверный результат?
2. Как получить правильный результат?

Спасибо
16 дек 15, 15:14    [18568279]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
Compositum,

ADS_UF_ACCOUNTDISABLE и ADS_UF_LOCKOUT - это два разных флага атрибута User-Account-Control учетки AD. Вас интересует состояние именно locked out, или всё-таки enabled? Если второе - то надо использовать AuthenticablePrincipal.Enabled (от которого UserPrincipal наследует аналогичное).
16 дек 15, 15:37    [18568426]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Сон Веры Павловны,

Спасибо! AuthenticablePrincipal.Enabled - то, что нужно! А какому свойству это соответствует в LDAP-запросе? А то если вызывать в цикле код

// This way of account status checking is VERY SLOWLY for 
// big count of users...
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain)) {
    using (UserPrincipal userPrincipal = UserPrincipal
        .FindByIdentity(ctx, account)) {
        isEnabled = userPrincipal.Enabled.Value;
    }
}

то на это уходит ОЧЕНЬ много времени....
16 дек 15, 15:58    [18568568]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
Compositum,

это соответсвует проверке (userAccountControl & 2)=2 (если true, то учетка заблокирована)
16 дек 15, 16:21    [18568694]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Сон Веры Павловны,

Ещё раз спасибо! Заменил предыдущий код на такой:
if (record.ContainsKey("useraccountcontrol") &&
    record["useraccountcontrol"].Count > 0) {
    isEnabled = (((Int32)record["useraccountcontrol"][0])
        & 2) == 0;
}

Теперь информация извлекается за 1 секунду вместо 18-ти. Благодарю!
16 дек 15, 16:45    [18568815]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Сон Веры Павловны,

Вы не в курсе, как в LDAP запросе получить разрядность операционной системы компьютера (x86 или x64)?
16 дек 15, 17:14    [18569002]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
Compositum
Сон Веры Павловны,

Вы не в курсе, как в LDAP запросе получить разрядность операционной системы компьютера (x86 или x64)?

зайдите в оснастку Users & Computers, откройте компьютер на редактирование,
зайдите во вкладку Attribute Editor, поставьте галочку "Show only exist values" или как то так. Изучайте.

если с оснасткой проблема, есть еще одна AdsiEdit она идет в комплекте с виндой, но непредустановлена, найти можно в компонентах через Win+R => appwiz.cpl => Enter
16 дек 15, 17:23    [18569065]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
Compositum
Сон Веры Павловны,

Вы не в курсе, как в LDAP запросе получить разрядность операционной системы компьютера (x86 или x64)?

Я сомневаюсь, что это вообще можно получить - из известных мне трех атрибутов учетки компьютера, содержащих сведения об ОС (Operating-System, Operating-System-Hotfix, Operating-System-Service-Pack) ни один не содержит сведений о разрядности ОС. Думаю, тут нужно смотреть в сторону remote WMI.
И да, если вам нужно определять заблокированность/незаблокированность учетной записи не в цикле, а задавать как условие LDAP-запроса, то изучите вот это (эти фильтры вполне применимы для DirectorySearcher).
16 дек 15, 17:42    [18569213]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Сон Веры Павловны
из известных мне трех атрибутов учетки компьютера, содержащих сведения об ОС (Operating-System, Operating-System-Hotfix, Operating-System-Service-Pack) ни один не содержит сведений о разрядности ОС.

Эти свойства я получил до того, как задать вопрос. Для полноты картины не хватает разрядности ОС.

Сон Веры Павловны
И да, если вам нужно определять заблокированность/незаблокированность учетной записи не в цикле, а задавать как условие LDAP-запроса, то изучите вот это (эти фильтры вполне применимы для DirectorySearcher).

Я это видел и на основе этой информации как раз и создаю фильтры. Проблема иногда возникает в том, какое свойство нужно смотреть в той или иной ситуации и как трактовать его значение (не всегда это очевидно). На данный момент все интересующие меня свойства, по отношению к компьютерам и пользователям я получаю успешно (за исключением разрядности ОС).

Сон Веры Павловны
Думаю, тут нужно смотреть в сторону remote WMI.

Спасибо, попробую. Возможно через WMI удастся получить и аккаунты учётных записей, имеющихся на удалённой машине, а так же проверить каждую из них на наличие административных прав на том компьютере. На данный момент наличие таких учёток я определяю через удалённый реестр, но эту операцию приходится выполнять с правами админа, т.к. соответствующая служба в Win7 и новее по умолчанию отключена (т.о. приходится на время запроса программно включать её и затем отключать).
16 дек 15, 17:56    [18569311]     Ответить | Цитировать Сообщить модератору
 Re: Не удаётся корректно проверить статус доменной учётной записи (заблокирована или нет)  [new]
Compositum
Member

Откуда: Санкт-Петербург
Сообщений: 5967
Сон Веры Павловны
Думаю, тут нужно смотреть в сторону remote WMI.

Сделал так:
ConnectionOptions options = new ConnectionOptions();
// Username & Password are necessary when process hasn't admin rights.
options.Username = @"domainName\adminAccount";
options.Password = "adminPassword";

ManagementScope scope = new ManagementScope(@"\\remoteMachineName\root\cimv2",
    options);
ObjectQuery query = new ObjectQuery(
    "SELECT OSArchitecture FROM Win32_OperatingSystem");

using (ManagementObjectSearcher searcher =
    new ManagementObjectSearcher(scope, query))
using (ManagementObjectCollection queryCollection = searcher.Get()) {
    foreach (var item in queryCollection) {
        foreach (var prop in item.Properties) {
            Console.WriteLine("{0}: {1}", prop.Name, prop.Value); // OSArchitecture: 64-bit
        }
    }
}
16 дек 15, 18:35    [18569525]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить