Почему моя реализация Clojure функции результатов поиска по LDAP не работает? - PullRequest
0 голосов
/ 07 марта 2012

TLDR; это не очень хорошо сформулированный вопрос, поэтому вам, вероятно, не стоит беспокоиться об этом. Я удалю его в ближайшем будущем, если только люди не подумают, что у него есть какая-то функция выкупа, кроме того, что это хороший пример того, как не задавать вопрос о переполнении стека.

Я использую UnboundID LDAP SDK для одного из моих проектов. В настоящее время я застрял в реализации поиска по постраничным результатам (описано в RFC2696), для которого у меня есть рабочая реализация Java. Я проверил код Java и знаю, что он корректно работает с моим тестовым каталогом LDAP. Основной частью реализации Java является следующий цикл do.. while:

do
{
  /*
   * Set the simple paged results control (if the cookie is null
   * this indicates the first time through the loop).
   */
  final SimplePagedResultsControl simplePagedResultsRequestControl =
      new SimplePagedResultsControl(pageSize,cookie);
  searchRequest.setControls(simplePagedResultsRequestControl);

  /*
   * Issue the search request:
   */
  SearchResult searchResult;
  searchResult = ldapConnection.search(searchRequest);
  final String msg =
      String
          .format(
              "searchRequest transmitted, pageSize: %d, entries returned: %d",
              Integer.valueOf(pageSize),
              Integer.valueOf(searchResult.getEntryCount()));
  final LogRecord record = new LogRecord(Level.INFO,msg);
  ldapCommandLineTool.out(new MinimalLogFormatter().format(record));
  total += searchResult.getEntryCount();
  /*
   * Get the cookie from the paged results control.
   */
  cookie = null;
  final SimplePagedResultsControl c =
      SimplePagedResultsControl.get(searchResult);
  if(c != null)
  {
    cookie = c.getCookie();
  }
}
while(cookie != null && cookie.getValueLength() > 0);

Запрос «управление» добавляется к поисковому запросу, указывая серверу, что он должен отправить обратно подмножество совпадающих записей. Предполагая, что первоначальный запрос действителен, сервер LDAP возвращает записи pageSize и элемент управления ответом, содержащий специальный «cookie». Чтобы получить следующую «страницу» результатов, клиент повторно отправляет запрос со cookie, включенным в элемент управления запросом, и сервер включает новый cookie с последующим ответом. Этот цикл продолжается до тех пор, пока не будет больше записей для возврата, и в этом случае клиенту не будут возвращены файлы cookie и запрос на поиск завершен.

Я попытался перенести вышеуказанный код на Clojure, но до сих пор не смог заставить его работать. Вот код:

(defn fetch-all
  [& attrs]
  (with-connection
    (let [attrs (into-array (if attrs (map name attrs) ["*"]))
          scope SearchScope/SUB
          request (SearchRequest. searchbase scope account-filter attrs)]
      (loop [results [] cookie nil]
        (let [control [(SimplePagedResultsControl. page-size cookie)]]
          (doto request
            (.setSizeLimit 12345)
            (.setTimeLimitSeconds 60)
            (.setControls control))
          (let [result (.search *conn* request)
                results (concat result results)
                cookie (.. SimplePagedResultsControl (get result) getCookie)]
            (println "entries returned:" (.getEntryCount result))
            (when-not (> 0 (.getValueLength cookie))
              results
              (recur
               results cookie))))))))

Java-код извлекает 1720 записей с 18 запросами, но у меня происходит сбой с LDAPSearchException «превышение размера» после пяти запросов.

Мой вопрос к вам, ребята, почему две реализации ведут себя по-разному? Я знаю, что отправляю полученный файл cookie с каждым новым запросом, поскольку создается исключение, если один и тот же файл cookie используется дважды Я также думаю, что знаю, что получаю последующие страницы результатов, потому что набор записей, возвращаемых на каждой странице, отличается.

Я в замешательстве, и мне не нравится мысль о том, чтобы вытянуть Ettercap для анализа трафика. Конечно, в моем коде явно что-то не так, что вызывает другое поведение.

Ответы [ 2 ]

1 голос
/ 07 марта 2012

Хорошо, две ошибки и недочёт в RFC:

  • (ошибка) конкатенация результата с результатами должна была быть (concat (.getSearchEntries result) results),
  • (ошибка) тест 'когда-нет' в нижней части цикла должен был быть 'если' или 'если-нет'.
  • (понял) в разделе 6 RFC, «Вопросы безопасности», предлагается, чтобы «Реализация серверов могла приводить в действие переопределенный sizelimit», то есть, как непривилегированный пользователь, я все равно достигну предела, постраничные результаты или нет. Различие в поведении между реализациями было просто из-за того, что я выполнял код Java с правами администратора и код Clojure анонимно (дох!).
1 голос
/ 07 марта 2012

(let [control [(SimplePagedResultsControl. page-size cookie)]]

Привязать элемент управления к вектору одного объекта управления результатами. Этот вектор затем передается в

(.setControls control)

, который, кажется, принимает один объект управления результатами, а не вектор, как ваш код Java.

...