Ошибка обработки ldap_initalize в C
Фон
У меня проблемы с обработкой ошибок 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. вернуть нулевой указатель в случае ошибки подключения (если я использую ldap_init
)
2. вернуть статус ошибки, который можно получить с помощью ldap_get_option
Однако ни один из этих методов не является надежным. Я провел тщательное тестирование функции, которую я создал, чтобы установить соединение с моим сервером LDAP. Есть моменты ldap_init
возвращает действительный указатель на объект LDAP, ldap_initialize
возвращает с кодом ошибки LDAP success (при использовании ldap_get_option
), и ldap_get_option успешно возвращается при разборе кодов ошибок.
Я обнаружил, что если я проверю C errno
переменная, я могу довольно точно получить статус подключения ldap_initialize
функция, как кажется, устанавливает errno при сбое (errno == 2
) => "Нет такого файла или каталога".
Когда я указываю случайные неиспользуемые порты в моей программе, это обычно точно. Тем не менее, я пошел, чтобы проверить свою программу более тщательно с программой под названием pamtester
и он не смог аутентифицировать пользователей, которых я указал. Ошибка, которая была установлена, была "Нет такого файла или каталога" сразу после моего звонка ldap_initialize
,
Я установил C (errno = 0
) после ldap_initialize, и я смог успешно аутентифицировать пользователей по моей базе данных LDAP.
Вопросы
1. Как правильно обрабатывать ошибки? ldap_initialize
функционировать?
2. Должен ли я использовать другую функцию для инициализации моего соединения LDAP?
3. Если статус ошибки фактически обрабатывается флагом errno в C, а не ldap_get_options
почему все справочные страницы и примеры говорят об обратном?
1 ответ
Только проверка errno
если ldap_initilize
вернул что-то другое тогда LDAP_SUCCESS
, Также сделайте это немедленно после ldap_initilize
вернулся, в остальном errno
возможно, был испорчен.
Код должен выглядеть так:
int status = ldap_initialize(&ldapServerConnection, serverAddress);
if (status != LDAP_SUCCESS)
{
/* int errno_save = errno; */
perror("ldap_initialize() failed"); /* This call shows the error message related to errno. */
/* If on a GNU system also the following will do: */
/* fprintf(stderr, ""ldap_initialize() failed with #%d: '%s'\n", errno_save, strerror(errno_save)); */
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_init*()
Функция не пытается установить соединение, поэтому любые недействительные данные адреса не будут обнаружены как таковые. Для проверки соединения используйте ldap_open()
, но ldsp_init()
,
От мужчиныldap_open
:
ldap_init () действует так же, как ldap_open (), но не открывает соединение с сервером LDAP. Фактическое открытие соединения произойдет, когда будет предпринята первая операция.