Как заставить LogonUser использовать кешированные учетные данные?

Я использую LogonUser для проверки пользовательского набора учетных данных домена.

LogonUser(accountName, domain, password, 
      LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, ref token);

С возмутительными результатами:

 LogonType    Current Password                Old password
 ===========  ==============================  ========================
 Network      Succeeds                        Succeeds
 Batch        Fails (0x00000569)              Fails (invalid password)
 Interactive  Succeeds                        Fails (invalid password)

Коды сбоев:

  • 0x00000569: Ошибка входа в систему: пользователю не был предоставлен запрашиваемый тип входа на этом компьютере.
  • 0x0000052E: сбой входа: неизвестное имя пользователя или пароль

Подробнее:

  • Если пользователь вводит учетные данные достоверные, функция возвращает true. (Хорошо)
  • если пользователь вводит недействительные учетные данные, функция возвращает false. (Хорошо)

  • если пользователь изменяет свой пароль и вводит свои новые действительные учетные данные, функция возвращает true. (хорошо)

  • если пользователь вводит недействительные учетные данные, функция возвращает false. (Хорошо)

  • если пользователь вводит свои старые учетные данные, функция возвращает true. (плохо)

Примечание:, если пользователь переместится на другой компьютер (тот, к которому они никогда не вошли ранее) и введите старые учетные данные, LogonUser продолжает возвращаться True. Это означает, что кэширование не происходит на локальной машине, но как-то "в сети".

  • если пользователь снова изменит свой пароль и добавит новые новые новые функции, функция возвращает true. (Хорошо)
  • если пользователь вводит свои старые учетные данные, функция возвращает true. (Плохо)
  • если пользователь вводит свои старые старые учетные данные, функция возвращает false. (Хорошо)

Как при вызове LogonUser я могу поручить ему указать домену не использовать кэшированные учетные данные.

Примечание. Если пользователь пытается войти в Windows со старым (или старым старым) паролем, они получают недопустимую ошибку пароля.


От MSDN:

LOGON32_LOGON_NETWORK
Этот тип входа предназначен для высокопроизводительных серверов для аутентификации паролей открытого текста. Функция LogonUser не кэширует учетные данные для этого типа входа.

LOGON32_LOGON_INTERACTIVE
Этот тип входа предназначен для пользователей, которые будут интерактивно работать с компьютером, например, с помощью пользователя terminal, удаленной оболочки, или аналогичный процесс. Этот тип входа имеет дополнительные расходы на кэширование информации входа для отключенных операций; поэтому не подходит для некоторых клиент-серверных приложений, таких как почтовый сервер.

LOGON32_LOGON_BATCHЭтот тип входа предназначен для пакетных серверов, где процессы могут выполняться от имени пользователя без их прямого вмешательства. Этот тип также предназначен для серверов с более высокой производительностью, которые обрабатывают много попыток аутентификации обычного текста за один раз, таких как почтовые или веб-серверы.

i am аутентификация паролей с открытым текстом, поэтому используйте LOGON32_LOGON_NETWORK. Интерактивный вход в систему кэширует учетные данные, которые здесь не разрешены. Пакет, в то время как недокументированный, когда он должен использоваться, просто терпит неудачу.


Обновление. Домен разрешает только:

  • предыдущий пароль (не более поздний)
  • всего 60 минут.

Мне ясно, что это "функция" Active Directory, дающая льготный период в 1 час.

Кроме того, я не хочу льготного периода, и я не хочу изменять какие-либо настройки в домене (так как я не знаю никаких настроек в домене, которые позволят использовать один час льготного периода использования вашего домена старый пароль).

Ответ 1

Это особенность NTLM. Вы можете изменить значение по умолчанию 60 мин. добавив значение OldPasswordAllowedPeriod DWORD в минутах до HKLM\SYSTEM\CurrentControlSet\Control\Lsa на контроллере домена или вы можете отключить политику "Использовать историю паролей". Вы также можете попробовать использовать другого поставщика входа в систему, например LOGON32_PROVIDER_WINNT50.

Кстати, если вы уже предоставляете графический интерфейс, я не вижу недостатка, используя LOGON32_LOGON_INTERACTIVE.