ldap SASL bind s ( GSSAPI) - что должно быть предоставлено в структуре учетных данных BERVAL
Я пытаюсь использовать ldap_sasl_bind_s
метод из Microsoft LDAP C SDK, с gssapi с как механизм аутентификации. ldap_sasl_bind_s
ожидает учетные данные как BERVAL
структура, которая непрозрачна.
учитывая имя пользователя (или DN) и пароль, как мне добраться до BERVAL
структура это я должен передать ldap_sasl_bind_s
?
примеры, которые я нашел до сих пор
- из других SDK LDAP C - не от Microsoft
- использовать
ldap_sasl_bind_s
когда требуется простая аутентификация - но мне нужно использовать GSSAPI - использовать
ldap_sasl_interactive_bind_s
когда другие механизмы аутентификации SASL желательны. Однако, нетldap_sasl_interactive_bind_s
в Microsoft SDK.
в качестве примечания, цель состоит в том, чтобы иметь возможность привязать через SASL к различным серверам LDAP; на данный момент: ActiveDirectory и OpenLDAP.
любые указатели будут высоко оценены.
3 ответов
мне удалось выполнить привязку SASL LDAP через GSSAPI, используя ldap_sasl_bind_s
. Для тех, кто заинтересован, вот несколько советов.
для абстрактного описания действий, которые клиент и сервер должны выполнить во время аутентификации SASL GSSAPI,"механизм простой аутентификации и уровня безопасности Kerberos V5 ("GSSAPI")" RFC следует прочитать; в частности, раздел "клиентская сторона обмена протоколами аутентификации" представляет интерес, потому что он дает указание последовательности действий, которые необходимо выполнить для успешной привязки к серверу LDAP через Kerberos.
полномочия ldap_sasl_bind_s
ожидает-их форма и их значение - зависят от фактического используемого механизма аутентификации, который в нашем случае является Kerberos.
в Microsoft SDK Kerberos доступен через SSPI-который является примерно реализацией Gssapi Microsoft; методы, которые имеют отношение к нашему конкретному случаю:AcquireCredentialsHandle
, InitializeSecurityContext
, DecryptMessage
, EncryptMessage
привязка SASL LDAP через Kerberos имеет 3 фазы.
Этап 1
вызов AcquireCredentialsHandle
и InitializeSecurityContext
.
Важные замечания здесь:
- передать
AcquireCredentialsHandle
указатель наSEC_WINNT_AUTH_IDENTITY
структура, содержащая фактические учетные данные (область, имя пользователя, пароль) илиNULL
если учетные данные текущего потока следует использовать - целевое имя должно быть SPN, сопоставленным с учетной записью, под которой LDAP сервер запущен
- при вызове
InitializeSecurityContext
, взаимная аутентификация должна быть запрошена.
если все важные аргументы верны-действительные учетные данные, действительный SPN,NULL
входной маркер -InitializeSecurityContext
вызов должен вернуть SEC_I_CONTINUE_NEEDED
и правильно заполните выходной токен. Содержимое этого выходного токена должно идти в BERVAL
структура ldap_sasl_bind_s
ожидает в качестве учетных данных клиента.
вызов ldap_sasl_bind_s
с выходным токеном от InitializeSecurityContext
в качестве клиента полномочия. Если все аргументы верны-пустое DN, GSSAPI в качестве имени механизма-фактический вызов должен возвращать LDAP_SUCCESS
и самая последняя ошибка LDAP для сеанса LDAP должна быть LDAP_SASL_BIND_IN_PROGRESS
.
в качестве примечания, самая последняя ошибка LDAP для сеанса LDAP может быть обнаружена путем вызова ldap_get_option
на сессии LDAP_OPT_ERROR_NUMBER
как вариант.
Этап 2
после успешного вызова ldap_sasl_bind_s
, его последний аргумент указывает на BERVAL
структура, содержащая учетные данные сервера. Содержание этого BERVAL
структура теперь должна использоваться как входной токен для второго вызова InitializeSecurityContext
.
этот второй вызов InitializeSecurityContext
должен возвратить SEC_OK
и пустой выходной маркер.
этот пустой выходной токен должен использоваться в качестве учетных данных клиента для другого вызова ldap_sasl_bind_s
. Этот второй звонок ldap_sasl_bind_s
должен возвратить LDAP_SUCCESS
, С самой последней ошибкой LDAP для сеанса LDAP LDAP_SASL_BIND_IN_PROGRESS
.
Этап 3
после второго успешного вызова ldap_sasl_bind_s
, его последний аргумент указывает на BERVAL
структура, содержащая данные сервера. Эти данные сервера должны быть введены в DecryptMessage
. Как указано в ранее упомянутом RFC, расшифрованные данные должны быть длиной 4 байта.
клиент должен построить свой ответ согласно информации в том же RFC.
Примечание: в моем случае я опустил идентификатор авторизации упоминается в RFC. Насколько я понимаю, пустой идентификатор авторизации приводит к тому, что идентификатор аутентификации также используется для авторизации.
ответ, который построил клиент, должен быть передан как вход в EncryptMessage
. Выход EncryptMessage
вызов должен быть передан в качестве учетных данных клиента для третьего и последнего вызова ldap_sasl_bind_s
.
Примечание: документация MSDN для использования EncryptMessage
под Kerberos кажется неполным. Поиск кода Google должен помочь с рабочим примером. Кроме того, для рабочего примера потока, описанного выше, можно ознакомиться с исходным кодом Samba.
Я нашел проблему.
в соответствии с этой нитью ( https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/9c13fe85e520f0b4/820a136e032946e9?pli=1) существует ошибка с ldap_sasl_bind_s возвращая пустые учетные данные сервера в Windows XP. Я протестировал свое приложение под Windows 2008 Server, и учетные данные правильно возвращаются.
статьи Солнце и MSDN. Наверное, если вы можете попробовать создать образец программы вы можете получить ответы
псевдокод
struct berval cred;
char mechanism[BUFSIZ];
getline( mechanism, sizeof(mechanism), stdin, "mechanism? " );
getline( passwd, sizeof(passwd), stdin,"credentials? " );
cred.bv_val = passwd;
cred.bv_len = strlen( passwd );
rc = ldap_sasl_bind_s( ld, dn, mechanism, &cred, NULL, NULL, NULL );