Ошибка обработки 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. Фактическое открытие соединения произойдет, когда будет предпринята первая операция.

Другие вопросы по тегам