Nick Porter [Mon, 11 Oct 2021 17:46:52 +0000 (18:46 +0100)]
v4: Final set of background changes to LDAP code (#4264)
* s/LDAP_OPT_ERROR_NUMBER/LDAP_OPT_RESULT_CODE/
LDAP_OPT_RESULT_CODE is the current name for this option.
* Define custom LDAP results parser
Used where LDAP queries are not part of processing a request, e.g.
querying the rootDSE after a connection comes up to establish which type
of directory server is connected to.
* Define async method to retrieve LDAP directory type
For use with trunk connections
* Queue a query to discover LDAP directory type for trunk connections
* Launch LDAP trunk connections for module default server
* We handle referral chasing so always set libldap option to off
* No need to re-bind since the trunk is only ever bound as admin user
* Move definition of fr_ldap_bind_ctx_t to base.h
* Define fr_ldap_bind_auth_ctx_t for holding details of bind auth requests
* Define fr_ldap_bind_auth_cmp for comparing two bind requests
* Define callbacks for handling LDAP bind responses
* Define watcher to add handlers to LDAP connection being used for bind auths
* Initialise a thread specific LDAP connection for bind auths
* Old referral rebind callback no longer needed
* Define callbacks to support use of async LDAP binds in place of sync ones
A temporary set of wrapper functions before fully rewriting rlm_ldap to
be fully async
Alan T. DeKok [Sat, 9 Oct 2021 17:33:17 +0000 (13:33 -0400)]
decode TLVs in OPT 41, too
the struct encoder does not yet accept the VPs returned by the decoder.
it's not clear if the decoder is wrong, or if the struct encoder
has issues. More debugging later.
Decoder functions should write directly to fr_pair_list_t and not to a cursor
The cursors are mostly legacy since we moved to dlists, and for efficient lookups we cannot modify pair lists using dcursors as we need to keep the attr tree in sync.
Nick Porter [Thu, 7 Oct 2021 12:09:42 +0000 (13:09 +0100)]
v4: Ground work for moving LDAP connections to per thread trunks (#4248)
* Define fr_ldap_thread_t to hold thead specific data
* Define fr_ldap_thread_trunk_t to hold LDAP connection details
* Add fr_ldap_trunk_cmp() to compare two thread LDAP trunks
* Define mod_thread_instantiate and mod_thread_detach for rlm_ldap
* Define types of LDAP requests
* Define LDAP query result codes
* Define fr_ldap_query_t to store individual LDAP queries
* Add fr_ldap_query_cmp() to compare two fr_ldap_query_t
* Define fr_ldap_referral_t to hold parsed LDAP referrals while they are followed
A given LDAP resonse which contains referral details can consist of
multiple referral URLs all of which should be capable of returning the
same data.
We parse all of the URLs and firstly attempt to query a server that
already has an active trunk connection.
All the possible referral URLs may need to be parsed to find an active
connection.
If none of the referral URLs point to an active connection, then the
parsed data stored in this structure is used to create new connections,
rather than re-parsing.
* Define fr_ldap_referral_alloc and _fr_ldap_referral_free
fr_ldap_referrer_t contains a LDAPURLDesc which needs to be freed using
libldap function ldap_free_urldesc
* Define destructor for fr_ldap_query_t
Frees any remaining libldap allocated structures
* Define allocator for fr_ldap_query_t
* Add LDAP config options of referral_depth and idle_timeout
referral depth - maximum number of referrals to follow
idle_timeout - how log to keep unused LDAP connections open
* Add tree to hold outstanding LDAP queries to fr_ldap_connection_t
* Define callback for closing an idle LDAP trunk
* Add return code for when an LDAP query results in a referral
* Add lookup table to provide readable names of LDAP message types
* Thread connection specific config is not talloc'd
* Define ldap_trunk_connection_alloc() to allocate LDAP connections
* Define I/O callbacks for LDAP trunks
* Setup I/O callbacks requested by LDAP trunk connection
* Define callback for cancelling LDAP queries
* Define _ldap_referral_send - a trunk watcher function...
... for sending referral queries when a trunk becomes active.
This allows for referrals which have multiple potential URLs to follow
to launch a number of trunk connections and the first one to become
active will receive the query.
* Define fr_thread_ldap_trunk_state() to find the state of a LDAP trunk
Looked up by URI and bind DN
* Define fr_ldap_referral_follow() to parse referral URLs and despatch ...
... queries to chase the referrals
* Define fr_ldap_referral_next() to follow subsequent LDAP referrals if the ...
... first one followed returns an error.
* Define ldap_trunk_request_mux() for sending LDAP queries on trunk connections
* Define ldap_trunk_request_demux() to handle LDAP query responses
* Define fr_thread_ldap_trunk_get() to find / create an LDAP trunk...
... for the required host / bind dn
* Define fr_ldap_modify_async() to initiate async LDAP modifications
James Jones [Thu, 7 Oct 2021 01:39:58 +0000 (20:39 -0500)]
Add fr_{lst, heap}_foreach() and tests thereof. (#4237)
Note that because we have to declare an fr_{lst, heap}_iter as well
as a variable of type pointer to the element type of the {lst, heap},
we must take the approach of fr_dlist_foreach_safe(). Correct uses
will thus look like they have unbalanced braces.