Hi,

After a few hours of hacking at this I managed to get something working.
Thank you Emmanuel for your pointers.

I would like to improve startup time and avoid loading all (any of) the schemas.

I am using DefaultDirectoryServiceFactory and LdapServer .
I replace the AuthenticatorInterceptor with my own.

I am able to run a simple ldap query and I log the username and passowrd:

ldapsearch -x -b "ou=system" -H ldap://localhost:10389 -D "uid=admin,ou=system" -w secret

Using DefaultDirectoryServiceFactory loads all the schemas and does some disk IO + starts slow.

Can I avoid loading the schemas and doing this much IO ?
I don't plan to use the schemas at all.

I gave it a shot but did not get far with that since DefaultDirectoryService requires locks the disk and has some schema initialization hardcoded inside - at specific paths.

I tink this logic could be made to be all in memory or to use a single file but the code is too complex for me to figure out right now.


Thanks,
Eugen


For who is interested, the code is bellow (clojure) :


----
(ns ieugen.ldap-auth-provider.core
  (:require [babashka.fs :as fs]
            [taoensso.timbre :as log])
(:import (org.apache.directory.api.ldap.model.constants AuthenticationLevel)
           (org.apache.directory.server.core.api LdapPrincipal)
(org.apache.directory.server.core.api.interceptor.context BindOperationContext)
           (org.apache.directory.server.core.authn Authenticator)
(org.apache.directory.server.core.authn AuthenticationInterceptor) (org.apache.directory.server.core.factory DefaultDirectoryServiceFactory)
           (org.apache.directory.server.ldap LdapServer)
           (org.apache.directory.server.protocol.shared.transport Transport

TcpTransport)))


(defn ->transport
  "Create a Transport for ^LdapServer."
  (^Transport [& {:keys [address port nbThreads backlog]
                  :or {address "localhost"
                       port 389
                       nbThreads 3
                       backlog 50}}]
(into-array Transport [(TcpTransport. address port nbThreads backlog)])))

(defn authenticate
  (^LdapPrincipal [schema-manager _this ^BindOperationContext bind-context]
   (let [credentials (.getCredentials bind-context)
         principal (.getPrincipal bind-context)
         dn (.getDn bind-context)
         dn-name (.getName dn)
         auth-rdn (.getRdn dn)
         username (.getValue auth-rdn)
         auth-lvl (.getAuthenticationLevel bind-context)]
     (log/info "Create principal with"
               (String. credentials "UTF-8")
               "principal" principal
               "->" dn-name
               "type -> val:" (.getType auth-rdn) "->" username
               " | " (.getRdns dn))
     (LdapPrincipal. schema-manager dn auth-lvl credentials))))

(defn delegating-authenticator
  ([schema-manager]
   (reify Authenticator
     (getAuthenticatorType [_this]
       (log/info "getAuthenticatorType")
       AuthenticationLevel/SIMPLE)
     (init [_this directory-service]
       (log/info "init" directory-service))
     (destroy [_this]
       (log/info "destroy"))
     (invalidateCache [_this bind-dn]
       (log/info "invalidateCache" bind-dn))
     (authenticate [_this bind-context]
       (log/info "authenticate" bind-context)
       (authenticate schema-manager _this bind-context))
     (checkPwdPolicy [_this user-entry]
       (log/info "checkPwdPolicy" user-entry))
     (isValid [_this bind-dn]
       (log/info "isValid" bind-dn)
       true)
     (getBaseDn [_this]
       (log/info "getBaseDn"))
     (setBaseDn [_this base-dn]
       (log/info "setBaseDn" base-dn)))))

(defn authentication-interceptor
  []
  (proxy [AuthenticationInterceptor]
         []
    (loadPwdPolicyStateAttributeTypes []
      (log/info "loadPwdPolicyStateAttributeTypes"))))

(defn index-of-class [clazz coll]
  (count (take-while #(not (instance? clazz %)) coll)))

(comment
  (let [_ (do
            (System/setProperty "workingDirectory" "tmp")
            (fs/create-dirs "tmp"))
        ds-factory  (DefaultDirectoryServiceFactory.)
        ds (doto (.getDirectoryService ds-factory)
             (.setShutdownHookEnabled true)
             (.setAllowAnonymousAccess true))
        schema-manager (.getSchemaManager ds)
        interceptors (.getInterceptors ds)
        my-delegate-auth (delegating-authenticator schema-manager)
        my-auth-interceptor (doto (authentication-interceptor)
(.setAuthenticators (java.util.HashSet. [my-delegate-auth]))) auth-interceptor-idx (index-of-class AuthenticationInterceptor interceptors)
        _ (.set interceptors auth-interceptor-idx my-auth-interceptor)
        _ (.setInterceptors ds interceptors)
        ldap-server (doto (LdapServer.)
                      (.addTransports (->transport :port 10389))
                      (.setDirectoryService ds))

        _ (do
            (def ldaps ldap-server)
            (-> ds .getChangeLog (.setEnabled true))
            _ (.init ds-factory "ldap-auth-provider"))]
    (log/info "Starting server")
    (.start ldap-server)

    (log/info "Server started"))

  (.stop ldaps))
----


--
Eugen Stan

+40770 941 271  / https://www.netdava.com
begin:vcard
fn:Eugen Stan
n:Stan;Eugen
email;internet:[email protected]
tel;cell:+40720898747
x-mozilla-html:FALSE
url:https://www.netdava.com
version:2.1
end:vcard

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to