Ошибка ldap при смене пароля

Ozzy

Ozzy

Случайный прохожий


  • #1

Всем привет! Подскажите как пофиксить проблему. Пользователи подключаются к чекпойнту через endpoint security vpn по логину и паролю. Если у пользователя просрочен пароль то клиент предлагает его сменить или обновить, но это сделать не удается. Появляется ошибка: Failed to modify password, LDAP Error
Где искать правду ?

1.png

Последнее редактирование: 07.03.2022

  • #5

Такое ощущение что как будто нет разрешений на смену пароля в AD

А если к примеру домен админ будет так пытаться пароль поменять через gaia или через endpoint security VPN?

  • #10

По моему опыту оно вообще через раз работает. И работоспособность сильно зависит от версии клиента.

I currently try to change passwords in our Active Directory Envoirenment via LDAP on Linux since the users in question do not have access to a windows-machine and we want to keep it that way.
In order to change the password I am currently stuck figuring out how to use ldapmodify to do so. After a lot of reading on different sites/forums/newsgroups I am much more confused than before

However:
I try the following command to do so:

ldapmodify -f ldif.example -H ldaps://lab01-dc01.example.com -D 'CN=test,CN=users,DC=lab01,DC=example,DC=com' -x -W

The contents of the ldif.example:

dn: CN=test,CN=Users,DC=lab01,DC=example,DC=com
changetype: modify
delete: unicodePwd
unicodePwd:: V3VQdXV1STEyLg==
-
add: unicodePwd
unicodePwd:: QmxhVVVraTEyLg==
-

(Don’t worry — those passwords are not used anywhere and it is not a production envoirenment)

Now — every time I execute the command I get the following error:

modifying entry CN=test,CN=Users,DC=lab01,DC=example,DC=com"
ldapmodify: Constraint violation (19)
 additional info: 0000216C: AtrErr: DSID-03190EB0, #1:
 0: 0000216C: DSID-03190EB0, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 9005a (unicodePwd)

Now, after what I read the reason for this error is either that the password is badly formatted or that the password policy doesn’t allow the password I used. I checked the policy — multiple times now — and the new password definetly complies to the policy by all the criteria. If I set the password using a Windows-machine it also works well (of course I changed the «oldpassword» and «newpassword» afterwards since I am not allowed by the policy to change to an earlier password). The password I enter after passing the «-W» option to ldapmodify is also definetly right, otherwise the error spit out by ldapmodify is that I used invalid credentials instead of a constraint violation.
So — the sole reason I can think of is indeed a bad formatted password — but I can’t figure out where the bad formatting should come from since I use the normal base64 algorythm to encode the password.

Has anyone an idea what is going on?
Can anyone push me in the right direction?

Help is very appreciated and I thank you in advance.

Edit:
Something which bugs me:
When I run the base encoded strings through base64 it keeps telling me «Invalid Input». Now — I went ahead and just re-coded the passwords with the use of base64 on the linux machine — but when I run the generated string through the decode function again, base64 keeps telling me «Invalid Input»… The strings however slightly changed between the windows-base64 encoded string and the linux encoded string. But base64 just says «Invalid input» no matter what I put in there.

Edit2:
Nevermind — reading the purpose of the function I gather that it throws this error because of the dots and the exclamation mark in the password.

Ozzy

Ozzy

Случайный прохожий
  • #1

Всем привет! Подскажите как пофиксить проблему. Пользователи подключаются к чекпойнту через endpoint security vpn по логину и паролю. Если у пользователя просрочен пароль то клиент предлагает его сменить или обновить, но это сделать не удается. Появляется ошибка: Failed to modify password, LDAP Error
Где искать правду ?

1.png

Последнее редактирование: 07.03.2022

  • #5

Такое ощущение что как будто нет разрешений на смену пароля в AD

А если к примеру домен админ будет так пытаться пароль поменять через gaia или через endpoint security VPN?

  • #10

По моему опыту оно вообще через раз работает. И работоспособность сильно зависит от версии клиента.

I currently try to change passwords in our Active Directory Envoirenment via LDAP on Linux since the users in question do not have access to a windows-machine and we want to keep it that way.
In order to change the password I am currently stuck figuring out how to use ldapmodify to do so. After a lot of reading on different sites/forums/newsgroups I am much more confused than before

However:
I try the following command to do so:

ldapmodify -f ldif.example -H ldaps://lab01-dc01.example.com -D 'CN=test,CN=users,DC=lab01,DC=example,DC=com' -x -W

The contents of the ldif.example:

dn: CN=test,CN=Users,DC=lab01,DC=example,DC=com
changetype: modify
delete: unicodePwd
unicodePwd:: V3VQdXV1STEyLg==
-
add: unicodePwd
unicodePwd:: QmxhVVVraTEyLg==
-

(Don’t worry — those passwords are not used anywhere and it is not a production envoirenment)

Now — every time I execute the command I get the following error:

modifying entry CN=test,CN=Users,DC=lab01,DC=example,DC=com"
ldapmodify: Constraint violation (19)
 additional info: 0000216C: AtrErr: DSID-03190EB0, #1:
 0: 0000216C: DSID-03190EB0, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 9005a (unicodePwd)

Now, after what I read the reason for this error is either that the password is badly formatted or that the password policy doesn’t allow the password I used. I checked the policy — multiple times now — and the new password definetly complies to the policy by all the criteria. If I set the password using a Windows-machine it also works well (of course I changed the «oldpassword» and «newpassword» afterwards since I am not allowed by the policy to change to an earlier password). The password I enter after passing the «-W» option to ldapmodify is also definetly right, otherwise the error spit out by ldapmodify is that I used invalid credentials instead of a constraint violation.
So — the sole reason I can think of is indeed a bad formatted password — but I can’t figure out where the bad formatting should come from since I use the normal base64 algorythm to encode the password.

Has anyone an idea what is going on?
Can anyone push me in the right direction?

Help is very appreciated and I thank you in advance.

Edit:
Something which bugs me:
When I run the base encoded strings through base64 it keeps telling me «Invalid Input». Now — I went ahead and just re-coded the passwords with the use of base64 on the linux machine — but when I run the generated string through the decode function again, base64 keeps telling me «Invalid Input»… The strings however slightly changed between the windows-base64 encoded string and the linux encoded string. But base64 just says «Invalid input» no matter what I put in there.

Edit2:
Nevermind — reading the purpose of the function I gather that it throws this error because of the dots and the exclamation mark in the password.

Ситуация:

Есть Samba3 PDC, в него входят пользователи. Когда время пароля истекает -> они меняют его средствами win.

Задача:

Сделать синхронизацию паролей samba3<->posix account

Для чего был поставлен скрипт ldapsync.pl. Теперь, когда клиент

меняет свой пароль, у него ошибка, но пароль _успешно_ меняется!

Вопрос:

как сделать так чтобы клиент не получал ошибки на своей стороне.

Вот лог файл:

[2004/08/04 11:46:52, 3] smbd/chgpasswd.c:chat_with_program(424)

chat_with_program: Dochild for user g-marchenko (uid=0,gid=0) (as_root = Yes)

[2004/08/04 11:46:52, 10] smbd/chgpasswd.c :Dochild(217)

Invoking ‘/usr/local/bin/ldapsync.pl -o g-marchenko’ as password change program.

[2004/08/04 11:46:52, 10] lib/util_sock.c:read_socket_with_timeout(263)

read_socket_with_timeout: timeout read. select timed out.

[2004/08/04 11:46:52, 100] smbd/chgpasswd.c:expect(274)

expect: expected [*New*Password*] received [New password for user g-marchenko: ] match yes

[2004/08/04 11:46:52, 10] smbd/chgpasswd.c:expect(285)

expect: returning True

[2004/08/04 11:46:52, 100] smbd/chgpasswd.c:expect(237)

expect: sending [test2

]

[2004/08/04 11:46:52, 10] lib/util_sock.c:read_socket_with_timeout(263)

read_socket_with_timeout: timeout read. select timed out.

[2004/08/04 11:46:52, 100] smbd/chgpasswd.c:expect(274)

expect: expected [*Retype*new*password*] received [

Retype new password for user g-marchenko: ] match yes

[2004/08/04 11:46:52, 10] smbd/chgpasswd.c:expect(285)

expect: returning True

[2004/08/04 11:46:52, 100] smbd/chgpasswd.c:expect(237)

expect: sending [test2

]

[2004/08/04 11:46:52, 0] lib/util_sock.c:read_socket_with_timeout(279)

read_socket_with_timeout: timeout read. read error = Input/output error.

[2004/08/04 11:46:52, 100] smbd/chgpasswd.c:expect(274)

expect: expected [*modifying*] received [

modifying entry «uid=g-marchenko,ou=People,o=office,dc=test,dc=ru»

] match yes

[2004/08/04 11:46:52, 10] smbd/chgpasswd.c:expect(285)

expect: returning True

[2004/08/04 11:46:52, 3] smbd/chgpasswd.c:chat_with_program(440)

chat_with_program: Password change successful for user g-marchenko

[2004/08/04 11:46:52, 2] passdb/pdb_ldap.c:init_ldap_from_sam(769)

init_ldap_from_sam: Setting entry for user: g-marchenko

[2004/08/04 11:46:52, 11] passdb/pdb_get_set.c :pdb_get_init_flags(189)

[2004/08/04 11:46:52, 5] lib/smbldap.c:smbldap_modify(976)

smbldap_modify: dn => [uid=g-marchenko,ou=People,o=office,dc=test,dc=ru]

[2004/08/04 11:46:52, 11] lib/smbldap.c:smbldap_open(828)

smbldap_open: already connected to the LDAP server

[2004/08/04 11:46:52, 1] passdb/pdb_ldap.c:ldapsam_modify_entry(1217)

ldapsam_modify_entry: Failed to modify user dn= uid=g-marchenko,ou=People,o=office,dc=test,dc=ru with: No such attribute

modify/delete: sambaLMPassword: no such value

[2004/08/04 11:46:52, 0] passdb/pdb_ldap.c:ldapsam_update_sam_account(1417)

ldapsam_update_sam_account: failed to modify user with uid = g-marchenko, error: modify/delete: sambaLMPassword: no such value (Success)

[2004/08/04 11:46:52, 3] smbd/sec_ctx.c :pop_sec_ctx(386)

pop_sec_ctx (65534, 65534) — sec_ctx_stack_ndx = 1

[2004/08/04 11:46:52, 5] rpc_parse/parse_samr.c:init_samr_r_chgpasswd_user(7120)

init_r_chgpasswd_user

[2004/08/04 11:46:52, 5] rpc_server/srv_samr_nt.c:_samr_chgpasswd_user(1469)

_samr_chgpasswd_user: 1469

[2004/08/04 11:46:52, 5] rpc_parse/parse_prs.c :prs_debug(82)

000000 samr_io_r_chgpasswd_user

[2004/08/04 11:46:52, 5] rpc_parse/parse_prs.c :prs_ntstatus(665)

0000 status: NT_STATUS_ACCESS_DENIED

Исходя из него мне показалось что samba3 пытается изменить пароль пользователя 2 раза, один раз — с помощью скрипта ldapsync.pl, а второй раз встроенными средствами samba3.

В поиске и мейл листе samba я не нашел подобной ошибки.

Если убрать настройку внешнего скрипта — то все нормально, пароли успешно меняются клиентами, только синхронизации их с паролями linux не происходит. :)

#ldap #opendj

Вопрос:

Я реализую функцию LDAP принудительной смены пароля при первом входе в систему, когда добавляется пользователь или когда администратор меняет пароль пользователя. Я установил ds-cfg-принудительное изменение при добавлении и ds-cfg-принудительное изменение при сбросе в значение true и в соответствии со спецификацией, которая определяет:

  1. Изменение пароля После сброса Эта политика заставляет пользователя выбирать новый пароль при первой привязке или после сброса пароля. После успешной операции привязки с аутентификацией сервер должен проверить, включена ли политика изменения пароля после сброса, и это первый вход в систему. Если это так, сервер должен отправить bindResponse с кодом результата: LDAP_SUCCESS и должен включить элемент управления с истекшим сроком действия пароля в поле элементы управления сообщения bindResponse:

    Тип управления: 2.16.840.1.113730.3.4.4,

    Значение управления: строка октета: «0»,

    критичность: ложная

Действительно, когда я вызываю Client.bind, я получаю возвращаемое значение LDAP_SUCCESS и поле элементов управления, как определено в спецификации.

но —

когда я вызываю Client.bind, когда пользователь находится в пределах интервала предупреждения об истечении срока действия пароля, я получаю поле управления только с типом управления Срок действия пароля (2.16.840.1.113730.3.4.5). Я бы ожидал получить оба элемента ControlType (элементы управления-это массив), но 2.16.840.1.113730.3.4.4 там нет.

Это является серьезной проблемой, потому что, если тип управления 2.16.840.1.113730.3.4.4 отсутствует, пользователь сможет войти в систему, хотя он должен был этого не делать.

Что я здесь упускаю?

Спасибо.

Комментарии:

1. Какой сервер LDAP вы используете? Открывается? ОпенДЖ?

2. Сервер LDAP, который я использую, — это OpenDJ

3. Я думаю, что это правильное поведение: когда пользователь находится в пределах интервала предупреждения об истечении срока действия пароля, его пароль считается установленным, и он еще не истек, поэтому нет LDAP_INVALID_CREDENTIALS, и контроль истечения срока действия пароля 2.16.840.1.113730.3.4.5 указывает время до истечения срока действия пароля. 2.16.840.1.113730.3.4.4 возвращается, когда пользователю должно быть предложено немедленно изменить пароль (это означает, что он уже истек или должен быть установлен пользователем после сброса/1-й привязки).

4. Спасибо, Эриклаво. Я понимаю ваш ответ, но это только усиливает вопрос. Если 2.16.840.1.113730.3.4.5 означает предупреждение о скором изменении пароля, а 2.16.840.1.113730.3.4.4 означает немедленное изменение пароля, то я ожидаю, что в случае, если оба они действительны, — 2.16.840.1.113730.3.4.4 будет возвращено, так как это более сильное уведомление. Но вместо этого сервер возвращает уведомление с предупреждением. 2.16.840.1.113730.3.4.5 выводит предупреждение пользователю, в то время как 2.16.840.1.113730.3.4.4 блокирует вход пользователя, пока он не изменит свой пароль. Не так ли?

Ответ №1:

Элементы управления Netscape очень старые и появились еще до разработки политики паролей OpenDJ. Они существуют только для того, чтобы обеспечить некоторую совместимость с очень старыми приложениями. Новые приложения должны отправить Управление запросом политики паролей (1.3.6.1.4.1.42.2.27.8.5.1) и получат соответствующий ответ управления PwdPolicy.

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

Настройки умолчанию позволяли корректно логинится и изменять себе пароль без проблем, но в случае истекания срока действия пароля начинались странности —
все необходимые атрибуты проверялись успешно и при логине система корректно рапортовала о необходимости обновления пароля:

You are required to change you LDAP password immediately.

,но после столь обнадеживающей фразы процесс смены пароля заканчивался печально

Authentication failed.

Поиск ничего путного не выдавал по данной проблеме, пришлось дебажить и исправлять самостоятельно.

Ищем проблему

Сначала подозрение пало на некорректно настроенные права доступа в OpenLDAP. Включил полный доступ на запись всем, ситуация не изменилась. При таком поведении, подозрения с LDAP’а были сняты, оставался PAM.

PAM

Просмотрев бегло исходники модуля pam_ldap, и не обнаружив ничего подозрительного начал экспериментировать с общими настройками в /etc/pam.d/common-*
В качестве средства дебага, я воспользовался модулем pam_echo для вывода трейсовых сообщений.

В результате проблема локализовалась в account части, ответственной за проверку «протухания» пароля. После того как она отрабатывала для ldap аккаунтов, передача управления в password не происходило.

Решение

Исходный конфиг для common-account при работе unix и ldap аккаунтов в Ubuntu Server выглядит так:

account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 default=die] pam_ldap.so
account requisite pam_deny.so
account required pam_permit.so

В результате экспериментов оказалось, что некорректо были настроены секция контрольных флагов (contol-flags) для модуля pam_ldap. Для правильной обработки истекшего пароля необходимо, как и в секции pam_unix, добавить указание для обработки new_authtok_reqd

account [success=1 new_authtok_reqd=done default=die] pam_ldap.so

При внесении данной правки, при попытке залогиниться пользователем с истекшим паролем, форма логина будет радовать нас предложением ввести новый пароль.
Стоит отметить что использование стандартной директивы sufficient вместо детального указания отдельных флагов тоже исправляет проблему с передачей управления дальше.

Проблема и её решение работают и в других дистрибутивах. Так в ALT Легкий и в ПСПО настройки по умолчанию также не позволяют менять пароль при его «протухании» и исправляются аналогичным образом.

в настоящее время я проверять подлинность пользователей против некоторых ad, используя следующий код:

DirectoryEntry entry = new DirectoryEntry(_path, username, pwd);

try
{
    // Bind to the native AdsObject to force authentication.
    Object obj = entry.NativeObject;

    DirectorySearcher search = new DirectorySearcher(entry) { Filter = "(sAMAccountName=" + username + ")" };
    search.PropertiesToLoad.Add("cn");
    SearchResult result = search.FindOne();
    if (result == null)
    {
        return false;
    }
    // Update the new path to the user in the directory
    _path = result.Path;
    _filterAttribute = (String)result.Properties["cn"][0];
}
catch (Exception ex)
{
    throw new Exception("Error authenticating user. " + ex.Message);
}

это отлично работает для проверки пароля против имени пользователя.

проблема заключается в том, что родовые ошибки всегда возвращается «ошибка входа в систему: неизвестное имя пользователя или неверный пароль.»когда аутентификация не выполняется.

однако аутентификация также может завершиться ошибкой, если учетная запись заблокирована.

Как бы я узнал, если он терпит неудачу из-за того, что он заперто?

я наткнулся на статьи, в которых говорится, что вы можете использовать:

Convert.ToBoolean(entry.InvokeGet("IsAccountLocked"))

или сделать что-то вроде объяснил здесь

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

любое другое предложение о том, как добраться до фактической причины сбоя аутентификации? (учетная запись заблокирована / пароль истек / etc.)

рекламу я подключиться не может скорее быть сервер Windows.

4 ответов


немного поздно, но я оставлю это там.

Если вы хотите действительно иметь возможность определить конкретную причину, по которой учетная запись не проходит проверку подлинности (есть еще много причин, кроме неправильного пароля, истекшего срока действия, блокировки и т. д.), вы можете использовать Windows API LogonUser. Не пугайтесь этого — это легче, чем кажется. Вы просто вызываете LogonUser, и если это не удается, вы смотрите на Маршала.GetLastWin32Error (), который даст вам код возврата, указывающий (очень) конкретная причина сбоя входа в систему.

однако вы не сможете вызвать это в контексте пользователя, которого вы аутентифицируете; вам понадобится учетная запись priveleged-я считаю, что требование SE_TCB_NAME (aka SeTcbPrivilege) — учетная запись пользователя, которая имеет право «действовать как часть операционной системы».

//Your new authenticate code snippet:
        try
        {
            if (!LogonUser(user, domain, pass, LogonTypes.Network, LogonProviders.Default, out token))
            {
                errorCode = Marshal.GetLastWin32Error();
                success = false;
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            CloseHandle(token);    
        }            
        success = true;

если это не удается, вы получите один из кодов возврата (есть больше, что вы можете посмотреть, но это важно из них:

 //See http://support.microsoft.com/kb/155012
    const int ERROR_PASSWORD_MUST_CHANGE = 1907;
    const int ERROR_LOGON_FAILURE = 1326;
    const int ERROR_ACCOUNT_RESTRICTION = 1327;
    const int ERROR_ACCOUNT_DISABLED = 1331;
    const int ERROR_INVALID_LOGON_HOURS = 1328;
    const int ERROR_NO_LOGON_SERVERS = 1311;
    const int ERROR_INVALID_WORKSTATION = 1329;
    const int ERROR_ACCOUNT_LOCKED_OUT = 1909;      //It gives this error if the account is locked, REGARDLESS OF WHETHER VALID CREDENTIALS WERE PROVIDED!!!
    const int ERROR_ACCOUNT_EXPIRED = 1793;
    const int ERROR_PASSWORD_EXPIRED = 1330;  

остальное просто скопируйте / вставьте, чтобы получить DLLImports и значения для передачи в

  //here are enums
    enum LogonTypes : uint
        {
            Interactive = 2,
            Network =3,
            Batch = 4,
            Service = 5,
            Unlock = 7,
            NetworkCleartext = 8,
            NewCredentials = 9
        }
        enum LogonProviders : uint
        {
            Default = 0, // default for platform (use this!)
            WinNT35,     // sends smoke signals to authority
            WinNT40,     // uses NTLM
            WinNT50      // negotiates Kerb or NTLM
        }

//Paste these DLLImports

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

[DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr handle);

Я знаю, что этот ответ опоздал на несколько лет, но мы просто столкнулись с той же ситуацией, что и оригинальный плакат. К сожалению, в нашей среде мы не можем использовать LogonUser — нам нужно чистое решение LDAP. Оказывается, есть способ получить расширенный код ошибки из операции привязки. Это немного уродливо, но это работает:

catch(DirectoryServicesCOMException exc)
{
    if((uint)exc.ExtendedError == 0x80090308)
    {
        LDAPErrors errCode = 0;

        try
        {
            // Unfortunately, the only place to get the LDAP bind error code is in the "data" field of the 
            // extended error message, which is in this format:
            // 80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 52e, v893
            if(!string.IsNullOrEmpty(exc.ExtendedErrorMessage))
            {
                Match match = Regex.Match(exc.ExtendedErrorMessage, @" data (?<errCode>[0-9A-Fa-f]+),");
                if(match.Success)
                {
                    string errCodeHex = match.Groups["errCode"].Value;
                    errCode = (LDAPErrors)Convert.ToInt32(errCodeHex, fromBase: 16);
                }
            }
        }
        catch { }

        switch(errCode)
        {
            case LDAPErrors.ERROR_PASSWORD_EXPIRED:
            case LDAPErrors.ERROR_PASSWORD_MUST_CHANGE:
                throw new Exception("Your password has expired and must be changed.");

            // Add any other special error handling here (account disabled, locked out, etc...).
        }
    }

    // If the extended error handling doesn't work out, just throw the original exception.
    throw;
}

и вам понадобятся определения для кодов ошибок (их намного больше на http://www.lifeasbob.com/code/errorcodes.aspx):

private enum LDAPErrors
{
    ERROR_INVALID_PASSWORD = 0x56,
    ERROR_PASSWORD_RESTRICTION = 0x52D,
    ERROR_LOGON_FAILURE = 0x52e,
    ERROR_ACCOUNT_RESTRICTION = 0x52f,
    ERROR_INVALID_LOGON_HOURS = 0x530,
    ERROR_INVALID_WORKSTATION = 0x531,
    ERROR_PASSWORD_EXPIRED = 0x532,
    ERROR_ACCOUNT_DISABLED = 0x533,
    ERROR_ACCOUNT_EXPIRED = 0x701,
    ERROR_PASSWORD_MUST_CHANGE = 0x773,
    ERROR_ACCOUNT_LOCKED_OUT = 0x775,
    ERROR_ENTRY_EXISTS = 0x2071,
}

Я не мог найти эту информацию в другом месте-все просто говорят, что вы должны использовать LogonUser. Если есть лучшее решение, я с удовольствием его выслушаю. Если нет, я надеюсь, что это поможет другим людям, которые не могут позвонить LogonUser.


проверка «пароль истекает» относительно проста — по крайней мере, в Windows (не уверен, как другие системы справляются с этим): когда значение Int64 «pwdLastSet» равно 0, пользователю придется изменить свой пароль при следующем входе в систему. Самый простой способ проверить это-включить это свойство в DirectorySearcher:

DirectorySearcher search = new DirectorySearcher(entry)
      { Filter = "(sAMAccountName=" + username + ")" };
search.PropertiesToLoad.Add("cn");
search.PropertiesToLoad.Add("pwdLastSet");

SearchResult result = search.FindOne();
if (result == null)
{
    return false;
}

Int64 pwdLastSetValue = (Int64)result.Properties["pwdLastSet"][0];

что касается проверки» учетная запись заблокирована » — сначала это кажется легким, но это не так…. Флаг» UF_Lockout » на «userAccountControl» не выполняет свою работу надежно.

начиная с Windows 2003 AD, есть новый вычисляемый атрибут, который вы можете проверить:msDS-User-Account-Control-Computed.

дали класс directoryentry user, вы можете сделать:

string attribName = "msDS-User-Account-Control-Computed";
user.RefreshCache(new string[] { attribName });

const int UF_LOCKOUT = 0x0010;

int userFlags = (int)user.Properties[attribName].Value;

if(userFlags & UF_LOCKOUT == UF_LOCKOUT) 
{
   // if this is the case, the account is locked out
}

если вы можете использовать .NET 3.5, все стало намного проще-проверьте статья MSDN о том, как обращаться с пользователями и группами в .NET 3.5 с помощью System.DirectoryServices.AccountManagement пространство имен. Е. Г. теперь у вас есть собственность IsAccountLockedOut на классе UserPrincipal который надежно говорит вам является ли учетная запись заблокирована.

надеюсь, что это помогает!

Марк


вот атрибуты ad LDAP, которые изменяются для пользователя, когда пароль заблокирован (первое значение) против, когда пароль не заблокирован (второе значение). badPwdCount и lockoutTime, очевидно, наиболее актуальна. Я не уверен, должны ли uSNChanged и whenChanged обновляться вручную или нет.

$ diff LockedOut.ldif NotLockedOut.ldif:

< badPwdCount: 3
> badPwdCount: 0

< lockoutTime: 129144318210315776
> lockoutTime: 0

< uSNChanged: 8064871
> uSNChanged: 8065084

< whenChanged: 20100330141028.0Z
> whenChanged: 20100330141932.0Z

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

Настройки умолчанию позволяли корректно логинится и изменять себе пароль без проблем, но в случае истекания срока действия пароля начинались странности —
все необходимые атрибуты проверялись успешно и при логине система корректно рапортовала о необходимости обновления пароля:

You are required to change you LDAP password immediately.

,но после столь обнадеживающей фразы процесс смены пароля заканчивался печально

Authentication failed.

Поиск ничего путного не выдавал по данной проблеме, пришлось дебажить и исправлять самостоятельно.

Ищем проблему

Сначала подозрение пало на некорректно настроенные права доступа в OpenLDAP. Включил полный доступ на запись всем, ситуация не изменилась. При таком поведении, подозрения с LDAP’а были сняты, оставался PAM.

PAM

Просмотрев бегло исходники модуля pam_ldap, и не обнаружив ничего подозрительного начал экспериментировать с общими настройками в /etc/pam.d/common-*
В качестве средства дебага, я воспользовался модулем pam_echo для вывода трейсовых сообщений.

В результате проблема локализовалась в account части, ответственной за проверку «протухания» пароля. После того как она отрабатывала для ldap аккаунтов, передача управления в password не происходило.

Решение

Исходный конфиг для common-account при работе unix и ldap аккаунтов в Ubuntu Server выглядит так:

account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 default=die] pam_ldap.so
account requisite pam_deny.so
account required pam_permit.so

В результате экспериментов оказалось, что некорректо были настроены секция контрольных флагов (contol-flags) для модуля pam_ldap. Для правильной обработки истекшего пароля необходимо, как и в секции pam_unix, добавить указание для обработки new_authtok_reqd

account [success=1 new_authtok_reqd=done default=die] pam_ldap.so

При внесении данной правки, при попытке залогиниться пользователем с истекшим паролем, форма логина будет радовать нас предложением ввести новый пароль.
Стоит отметить что использование стандартной директивы sufficient вместо детального указания отдельных флагов тоже исправляет проблему с передачей управления дальше.

Проблема и её решение работают и в других дистрибутивах. Так в ALT Легкий и в ПСПО настройки по умолчанию также не позволяют менять пароль при его «протухании» и исправляются аналогичным образом.

Понравилась статья? Поделить с друзьями:
  • Ошибка ldap 82 0x52 локальная ошибка
  • Ошибка ldap 81 0x51 сервер отключен ошибка win32 58
  • Ошибка lcid cannot run in this locale
  • Ошибка job for nginx service failed
  • Ошибка lci на стиральной машинке самсунг