Общие сведения
У меня возникли проблемы с обработкой функции ldap_initialize
в C.
Прочитав многочисленные документы (большинство из которых представляют собой просто копии справочных страниц), я нашел несколько способов (которые, возможно, вводят в заблуждение или неверны) для обработки ошибок этой функции.
Вот код, с которым у меня возникли проблемы:
//--------------------------------------
// declarations
//--------------------------------------
int status = 0;
int optionHandlingStatus = 0;
char * ldapErrorString = NULL;
char serverAddress[PLS_STRING_ARRAY_SIZE];
//--------------------------------------
// prepare the server's address
//--------------------------------------
sprintf(
serverAddress,
"ldap://%s:%s",
settings->serverAddress,
settings->serverPort
);
//writeDebugLog("LDAP server address set to [%s].", serverAddress);
//--------------------------------------
// connect to the server
//--------------------------------------
status = ldap_initialize(&ldapServerConnection, serverAddress);
optionHandlingStatus = ldap_get_option(ldapServerConnection, LDAP_OPT_RESULT_CODE, &status);
if (status != LDAP_SUCCESS || errno != LDAP_SUCCESS) { //the specs are strange
if (status && errno) {
writeDebugLog("CONNECTION Fail!.");
writeSyslog("CONNECTION Fail!.");
}
ldapErrorString = ldap_err2string(status);
writeDebugLog("Connection to server failed with [%s].", ldapErrorString);
writeSyslog(
"LDAP server initalization error. Check [%s] server's status.",
serverAddress
);
return(NULL);
}
Проблема
В документах говорится, что ldap_initialize
должен:
1. возвращать указатель NULL в случае ошибки соединения (если я использую ldap_init
)
2. возвращать статус ошибки который можно получить с помощью ldap_get_option
Однако ни один из этих методов не является надежным. Я провел тщательное тестирование функции, которую я создал для запуска подключения к моему серверу LDAP. Иногда ldap_init
возвращает действительный указатель на объект LDAP, ldap_initialize
возвращает код ошибки LDAP Success (при использовании ldap_get_option
), а ldap_get_option успешно возвращает коды ошибок.
Я обнаружил, что если я проверю переменную errno
C, я могу довольно точно получить статус соединения функции ldap_initialize
, поскольку она, кажется, устанавливает ошибку при сбое (errno == 2
) => "Нет такого файла или каталога".
Когда я указываю случайные неиспользуемые порты в своей программе, это обычно верно. Однако я решил более тщательно протестировать свою программу с помощью программы с именем pamtester
, и она не смогла аутентифицировать пользователей, которых я указал. Ошибка, которая была установлена, была «Нет такого файла или каталога» сразу после моего вызова ldap_initialize
.
Я принудительно установил C (errno = 0
) после ldap_initialize, и мне удалось успешно аутентифицировать пользователей в моей базе данных LDAP.
Вопросы
1. Как правильно обработать ошибку функции ldap_initialize
?
2. Должен ли я использовать другую функцию для инициализации подключения LDAP?
3. Если ошибка статус на самом деле обрабатывается флагом C errno, а не ldap_get_options
, почему все справочные страницы и примеры говорят об обратном?
errno
только в том случае, еслиldap_initilize
вернул что-то отличное отLDAP_SUCCESS
. Также сделайте это сразу после возвращенияldap_initilize
, иначеerrno
мог быть испорчен. В качестве альтернативы сохраните значениеerrno
после возврата ldap_initilize. - person alk   schedule 30.04.2014ldap_initialize
возвращаетLDAP_SUCCESS
при недопустимом соединении, ноerrno
будет установлено. Обработка ошибок постоянно конфликтовала, оставляя меня в замешательстве, поэтому я написал здесь. - person Dodzi Dzakuma   schedule 30.04.2014errno
не имеет смысла, если только функция не вернула значение, указывающее на ошибку. Библиотечные функции не устанавливают для errno значение 0 в случае успеха. Попробуйте установить для errno значение 0 перед вызовом функции, и оно должно быть равно 0 после успешного завершения функции. - person ooga   schedule 30.04.2014ldap_initialize
возвращает LDAP_SUCCESS, ноerrno
установлено значение2
. В этой ситуацииerrno
было правильно, аldap_initialize
— нет. - person Dodzi Dzakuma   schedule 30.04.2014ldap_get_options
, похоже, не имеет ничего общего с ошибками. - person ooga   schedule 30.04.2014LDAP_OPT_RESULT_CODE
, это способ проверить статус, установленный в объекте LDAP при использованииldap_initialize
, посколькуldap_initialize
не возвращает указатель NULL при ошибке. Я могу неправильно читать документы, и, возможно, я не полностью их понимаю. - person Dodzi Dzakuma   schedule 30.04.2014ldap_initialize()
никогда не возвращаетNULL
, так как возвращаетint
, аNULL
является значением указателя. Вы, кажется, путаете"ldap_initialize()
и"ldap_init()
. - person alk   schedule 30.04.2014