ldap_sasl_bind_s (GSSAPI) - что должно быть предусмотрено в структуре BERVAL для учетных данных - PullRequest
9 голосов
/ 30 июня 2010

Я пытаюсь использовать метод ldap_sasl_bind_s из SDK Microsoft LDAP C, с 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.Однако в Microsoft SDK нет ldap_sasl_interactive_bind_s.

В качестве дополнительного примечания, цель состоит в том, чтобы иметь возможность привязки через SASL к различным серверам LDAP;на данный момент: ActiveDirectory и OpenLDAP.

Любые указатели будут с благодарностью.

Ответы [ 3 ]

14 голосов
/ 08 августа 2010

Мне удалось выполнить связывание LDAP SASL через GSSAPI, используя ldap_sasl_bind_s.Для тех, кто заинтересован, вот несколько указателей.

Для абстрактного описания действий, которые клиент и сервер должны выполнить во время аутентификации SASL GSSAPI, "Простая аутентификация Kerberos V5 (" GSSAPI ") иМеханизм уровня безопасности (SASL) " Следует прочитать RFC;В частности, интерес представляет раздел «Клиентская сторона Exchange по протоколу аутентификации», поскольку в нем указывается последовательность действий, которые нам необходимо выполнить для успешного связывания с сервером LDAP через Kerberos.

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

В Microsoft SDK Kerberos доступен через SSPI - что примерно соответствует реализации GSSAPI от Microsoft.;методы, которые относятся к нашему конкретному случаю: AcquireCredentialsHandle, InitializeSecurityContext, DecryptMessage, EncryptMessage

Связывание LDAP SASL с Kerberos имеет 3 фазы.

Фаза 1

Вызов AcquireCredentialsHandle и InitializeSecurityContext.
Важные примечания:

  • передача AcquireCredentialsHandle указателя на структуру SEC_WINNT_AUTH_IDENTITY, содержащую фактические учетные данные (область), имя пользователя, пароль) или NULL, если должны использоваться учетные данные текущего потока
  • целевое имя должно быть именем участника-службы, сопоставленным с учетной записью, под которой работает сервер 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.

2 голосов
/ 31 января 2011

Я обнаружил проблему.

Согласно этой теме (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 иучетные данные возвращены правильно.

0 голосов
/ 08 августа 2010

Артикул от Солнце и 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 );
...