Pass a threadsafe ctx into fr_connection_pool create callback
[freeradius.git] / src / modules / rlm_ldap / ldap.h
1 /**
2  * $Id$
3  * @file ldap.h
4  * @brief LDAP authorization and authentication module headers.
5  *
6  * @author Arran Cudbard-Bell <a.cudbardb@freeradius.org>
7  * @copyright 2013 Network RADIUS SARL<info@networkradius.com>
8  * @copyright 2013 The FreeRADIUS Server Project.
9  */
10 #ifndef _RLM_LDAP_H
11 #define _RLM_LDAP_H
12
13 #include        <freeradius-devel/radiusd.h>
14 #include        <freeradius-devel/modules.h>
15 #include        <ldap.h>
16
17 /*
18  *      For compatibility with other LDAP libraries
19  */
20 #if !defined(LDAP_SCOPE_BASE) && defined(LDAP_SCOPE_BASEOBJECT)
21 #  define LDAP_SCOPE_BASE LDAP_SCOPE_BASEOBJECT
22 #endif
23
24 #if !defined(LDAP_SCOPE_ONE) && defined(LDAP_SCOPE_ONELEVEL)
25 #  define LDAP_SCOPE_ONE LDAP_SCOPE_ONELEVEL
26 #endif
27
28 #if !defined(LDAP_SCOPE_SUB) && defined(LDAP_SCOPE_SUBTREE)
29 #  define LDAP_SCOPE_SUB LDAP_SCOPE_SUBTREE
30 #endif
31
32 #if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER)
33 #  define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
34 #endif
35
36 #ifndef LDAP_CONST
37 #  define LDAP_CONST
38 #endif
39
40 #define LDAP_MAX_ATTRMAP                128             //!< Maximum number of mappings between LDAP and
41                                                         //!< FreeRADIUS attributes.
42 #define LDAP_MAP_RESERVED               4               //!< Number of additional items to allocate in expanded
43                                                         //!< attribute name arrays. Currently for enable attribute,
44                                                         //!< group membership attribute, valuepair attribute,
45                                                         //!< and profile attribute.
46
47 #define LDAP_MAX_CACHEABLE              64              //!< Maximum number of groups we retrieve from the server for
48                                                         //!< a given user. If more than this number are retrieve the
49                                                         //!< module returns invalid.
50
51 #define LDAP_MAX_GROUP_NAME_LEN         128             //!< Maximum name of a group name.
52 #define LDAP_MAX_ATTR_STR_LEN           256             //!< Maximum length of an xlat expanded LDAP attribute.
53 #define LDAP_MAX_FILTER_STR_LEN         1024            //!< Maximum length of an xlat expanded filter.
54 #define LDAP_MAX_DN_STR_LEN             2048            //!< Maximum length of an xlat expanded DN.
55
56 typedef struct ldap_acct_section {
57         CONF_SECTION    *cs;                            //!< Section configuration.
58
59         char const *reference;                          //!< Configuration reference string.
60 } ldap_acct_section_t;
61
62 typedef struct ldap_instance {
63         CONF_SECTION    *cs;                            //!< Main configuration section for this instance.
64         fr_connection_pool_t *pool;                     //!< Connection pool instance.
65
66         char const      *server;                        //!< Initial server to bind to.
67         int             is_url;                         //!< Whether ldap_is_ldap_url says 'server' is an
68                                                         //!< ldap[s]:// url.
69         uint16_t        port;                           //!< Port to use when binding to the server.
70
71         char const      *admin_dn;                      //!< DN we bind as when we need to query the LDAP
72                                                         //!< directory.
73         char const      *password;                      //!< Password used in administrative bind.
74
75         char const      *dereference_str;               //!< When to dereference (never, searching, finding, always)
76         int             dereference;                    //!< libldap value specifying dereferencing behaviour.
77
78         bool            chase_referrals;                //!< If the LDAP server returns a referral to another server
79                                                         //!< or point in the tree, follow it, establishing new
80                                                         //!< connections and binding where necessary.
81         bool            chase_referrals_unset;          //!< If true, use the OpenLDAP defaults for chase_referrals.
82
83         bool            rebind;                         //!< Controls whether we set an ldad_rebind_proc function
84                                                         //!< and so determines if we can bind to other servers whilst
85                                                         //!< chasing referrals. If this is false, we will still chase
86                                                         //!< referrals on the same server, but won't bind to other
87                                                         //!< servers.
88
89         uint32_t        ldap_debug;                     //!< Debug flag for the SDK.
90
91         char const      *xlat_name;                     //!< Instance name.
92
93         bool            expect_password;                //!< True if the user_map included a mapping between an LDAP
94                                                         //!< attribute and one of our password reference attributes.
95
96         /*
97          *      RADIUS attribute to LDAP attribute maps
98          */
99         value_pair_map_t *user_map;                     //!< Attribute map applied to users and profiles.
100
101         /*
102          *      User object attributes and filters
103          */
104         char const      *userobj_filter;                //!< Filter to retrieve only user objects.
105         char const      *userobj_base_dn;               //!< DN to search for users under.
106         char const      *userobj_scope_str;             //!< Scope (sub, one, base).
107         int             userobj_scope;                  //!< Search scope.
108
109         char const      *userobj_membership_attr;       //!< Attribute that describes groups the user is a member of.
110         char const      *userobj_access_attr;           //!< Attribute to check to see if the user should be locked out.
111         bool            access_positive;                //!< If true the presence of the attribute will allow access,
112                                                         //!< else it will deny access.
113
114         char const      *valuepair_attr;                //!< Generic dynamic mapping attribute, contains a RADIUS
115                                                         //!< attribute and value.
116
117         /*
118          *      Group object attributes and filters
119          */
120
121         char const      *groupobj_filter;               //!< Filter to retrieve only group objects.
122         char const      *groupobj_base_dn;              //!< DN to search for users under.
123         char const      *groupobj_scope_str;            //!< Scope (sub, one, base).
124         int             groupobj_scope;                 //!< Search scope.
125
126         char const      *groupobj_name_attr;            //!< The name of the group.
127         char const      *groupobj_membership_filter;    //!< Filter to only retrieve groups which contain
128                                                         //!< the user as a member.
129
130         bool            cacheable_group_name;           //!< If true the server will determine complete set of group
131                                                         //!< memberships for the current user object, and perform any
132                                                         //!< resolution necessary to determine the names of those
133                                                         //!< groups, then right them to the control list (LDAP-Group).
134
135         bool            cacheable_group_dn;             //!< If true the server will determine complete set of group
136                                                         //!< memberships for the current user object, and perform any
137                                                         //!< resolution necessary to determine the DNs of those groups,
138                                                         //!< then right them to the control list (LDAP-GroupDN).
139
140         char const      *cache_attribute;               //!< Sets the attribute we use when creating and retrieving
141                                                         //!< cached group memberships.
142
143         DICT_ATTR const *cache_da;                      //!< The DA associated with this specific version of the
144                                                         //!< rlm_ldap module.
145
146         DICT_ATTR const *group_da;                      //!< The DA associated with this specific version of the
147                                                         //!< rlm_ldap module.
148
149         /*
150          *      Dynamic clients
151          */
152         char const      *clientobj_filter;              //!< Filter to retrieve only client objects.
153         char const      *clientobj_base_dn;             //!< DN to search for clients under.
154         char const      *clientobj_scope_str;           //!< Scope (sub, one, base).
155         int             clientobj_scope;                //!< Search scope.
156
157         char const      *clientobj_identifier;          //!< IP/FQDN/IP Prefix for the NAS.
158         char const      *clientobj_shortname;           //!< Short/Friendly name to assign.
159         char const      *clientobj_type;                //!< Type of NAS (not usually used).
160         char const      *clientobj_secret;              //!< RADIUS secret.
161         char const      *clientobj_server;              //!< Virtual server to associate the client with.
162         char const      *clientobj_require_ma;          //!< Require message-authenticator.
163
164         bool            do_clients;                     //!< If true, attempt to load clients on instantiation.
165
166         /*
167          *      Profiles
168          */
169         char const      *default_profile;               //!< If this is set, we will search for a profile object
170                                                         //!< with this name, and map any attributes it contains.
171                                                         //!< No value should be set if profiles are not being used
172                                                         //!< as there is an associated performance penalty.
173         char const      *profile_attr;                  //!< Attribute that identifies profiles to apply. May appear
174                                                         //!< in userobj or groupobj.
175         char const      *profile_filter;                //!< Filter to retrieve only retrieve group objects.
176
177         /*
178          *      Accounting
179          */
180         ldap_acct_section_t *postauth;                  //!< Modify mappings for post-auth.
181         ldap_acct_section_t *accounting;                //!< Modify mappings for accounting.
182
183         /*
184          *      TLS items.  We should really normalize these with the
185          *      TLS code in 3.0.
186          */
187         int             tls_mode;
188         bool            start_tls;                      //!< Send the Start TLS message to the LDAP directory
189                                                         //!< to start encrypted communications using the standard
190                                                         //!< LDAP port.
191
192         char const      *tls_ca_file;                   //!< Sets the full path to a CA certificate (used to validate
193                                                         //!< the certificate the server presents).
194
195         char const      *tls_ca_path;                   //!< Sets the path to a directory containing CA certificates.
196
197         char const      *tls_certificate_file;          //!< Sets the path to the public certificate file we present
198                                                         //!< to the servers.
199
200         char const      *tls_private_key_file;          //!< Sets the path to the private key for our public
201                                                         //!< certificate.
202
203         char const      *tls_random_file;               //!< Path to the random file if /dev/random and /dev/urandom
204                                                         //!< are unavailable.
205
206         char const      *tls_require_cert_str;          //!< Sets requirements for validating the certificate the
207                                                         //!< server presents.
208
209         int             tls_require_cert;               //!< OpenLDAP constant representing the require cert string.
210
211         /*
212          *      Options
213          */
214
215         uint32_t        net_timeout;                    //!< How long we wait for new connections to the LDAP server
216                                                         //!< to be established.
217         uint32_t        res_timeout;                    //!< How long we wait for a result from the server.
218         uint32_t        srv_timelimit;                  //!< How long the server should spent on a single request
219                                                         //!< (also bounded by value on the server).
220
221 #ifdef WITH_EDIR
222         /*
223          *      eDir support
224          */
225         bool            edir;                           //!< If true attempt to retrieve the user's cleartext password
226                                                         //!< using the Universal Password feature of Novell eDirectory.
227         bool            edir_autz;                      //!< If true, and we have the Universal Password, bind with it
228                                                         //!< to perform additional authorisation checks.
229 #endif
230         /*
231          *      For keep-alives.
232          */
233 #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
234         uint32_t        keepalive_idle;                 //!< Number of seconds a connections needs to remain idle
235                                                         //!< before TCP starts sending keepalive probes.
236 #endif
237 #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
238         uint32_t        keepalive_probes;               //!< Number of missed timeouts before the connection is
239                                                         //!< dropped.
240 #endif
241 #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
242         uint32_t        keepalive_interval;             //!< Interval between keepalive probes.
243 #endif
244
245 } ldap_instance_t;
246
247 typedef struct ldap_handle {
248         LDAP            *handle;                        //!< LDAP LD handle.
249         int             rebound;                        //!< Whether the connection has been rebound to something
250                                                         //!< other than the admin user.
251         int             referred;                       //!< Whether the connection is now established a server
252                                                         //!< other than the configured one.
253         ldap_instance_t *inst;                          //!< rlm_ldap configuration.
254 } ldap_handle_t;
255
256 typedef struct rlm_ldap_map_xlat {
257         value_pair_map_t const *maps;
258         char const *attrs[LDAP_MAX_ATTRMAP + LDAP_MAP_RESERVED + 1]; //!< Reserve some space for access attributes
259                                                                      //!< and NULL termination.
260         int count;
261 } rlm_ldap_map_xlat_t;
262
263 typedef struct rlm_ldap_result {
264         struct berval   **values;                       //!< libldap struct containing bv_val (char *)
265                                                         //!< and length bv_len.
266         int             count;                          //!< Number of values.
267 } rlm_ldap_result_t;
268
269 typedef enum {
270         LDAP_PROC_SUCCESS = 0,                          //!< Operation was successfull.
271
272         LDAP_PROC_ERROR = -1,                           //!< Unrecoverable library/server error.
273
274         LDAP_PROC_RETRY = -2,                           //!< Transitory error, caller should retry the operation
275                                                         //!< with a new connection.
276
277         LDAP_PROC_NOT_PERMITTED = -3,                   //!< Operation was not permitted, either current user was
278                                                         //!< locked out in the case of binds, or has insufficient
279                                                         //!< access.
280
281         LDAP_PROC_REJECT = -4,                          //!< Bind failed, user was rejected.
282
283         LDAP_PROC_BAD_DN = -5,                          //!< Specified an invalid object in a bind or search DN.
284
285         LDAP_PROC_NO_RESULT = -6                        //!< Got no results.
286 } ldap_rcode_t;
287
288 /*
289  *      Some functions may be called with a NULL request structure, this
290  *      simplifies switching certain messages from the request log to
291  *      the main log.
292  */
293 #define LDAP_INFO(fmt, ...) INFO("rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
294 #define LDAP_WARN(fmt, ...) WARN("rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
295
296 #define LDAP_DBGW(fmt, ...) radlog(L_DBG_WARN, "rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
297 #define LDAP_DBGW_REQ(fmt, ...) do { if (request) {RWDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_DBGW(fmt, ##__VA_ARGS__);}} while (0)
298
299 #define LDAP_DBG(fmt, ...) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
300 #define LDAP_DBG_REQ(fmt, ...) do { if (request) {RDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
301
302 #define LDAP_DBG2(fmt, ...) if (debug_flag >= L_DBG_LVL_2) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
303 #define LDAP_DBG_REQ2(fmt, ...) do { if (request) {RDEBUG2(fmt, ##__VA_ARGS__);} else if (debug_flag >= L_DBG_LVL_2) {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
304
305 #define LDAP_DBG3(fmt, ...) if (debug_flag >= L_DBG_LVL_3) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
306 #define LDAP_DBG_REQ3(fmt, ...) do { if (request) {RDEBUG3(fmt, ##__VA_ARGS__);} else if (debug_flag >= L_DBG_LVL_3) {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
307
308 #define LDAP_ERR(fmt, ...) ERROR("rlm_ldap (%s): " fmt, inst->xlat_name, ##__VA_ARGS__)
309 #define LDAP_ERR_REQ(fmt, ...) do { if (request) {REDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_ERR(fmt, ##__VA_ARGS__);}} while (0)
310
311 #define LDAP_EXT() if (extra) LDAP_ERR(extra)
312 #define LDAP_EXT_REQ() do { if (extra) { if (request) REDEBUG("%s", extra); else LDAP_ERR("%s", extra); }} while (0)
313
314 extern FR_NAME_NUMBER const ldap_scope[];
315 extern FR_NAME_NUMBER const ldap_tls_require_cert[];
316
317 /*
318  *      ldap.c - Wrappers arounds OpenLDAP functions.
319  */
320 size_t rlm_ldap_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg);
321
322 int rlm_ldap_is_dn(char const *str);
323
324 ssize_t rlm_ldap_xlat_filter(REQUEST *request, char const **sub, size_t sublen, char *out, size_t outlen);
325
326 ldap_rcode_t rlm_ldap_bind(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn,
327                           char const *password, bool retry);
328
329 char const *rlm_ldap_error_str(ldap_handle_t const *conn);
330
331 ldap_rcode_t rlm_ldap_search(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
332                              char const *dn, int scope, char const *filter, char const * const *attrs,
333                              LDAPMessage **result);
334
335 ldap_rcode_t rlm_ldap_modify(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
336                              char const *dn, LDAPMod *mods[]);
337
338 char const *rlm_ldap_find_user(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
339                                char const *attrs[], int force, LDAPMessage **result, rlm_rcode_t *rcode);
340
341 rlm_rcode_t rlm_ldap_check_access(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t const *conn,
342                                   LDAPMessage *entry);
343
344 void rlm_ldap_check_reply(ldap_instance_t const *inst, REQUEST *request);
345
346 /*
347  *      ldap.c - Callbacks for the connection pool API.
348  */
349 void *mod_conn_create(TALLOC_CTX *ctx, void *instance);
350
351 ldap_handle_t *rlm_ldap_get_socket(ldap_instance_t const *inst, REQUEST *request);
352
353 void rlm_ldap_release_socket(ldap_instance_t const *inst, ldap_handle_t *conn);
354
355 /*
356  *      groups.c - Group membership functions.
357  */
358
359 rlm_rcode_t rlm_ldap_cacheable_userobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
360                                        LDAPMessage *entry, char const *attr);
361
362 rlm_rcode_t rlm_ldap_cacheable_groupobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn);
363
364 rlm_rcode_t rlm_ldap_check_groupobj_dynamic(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
365                                             VALUE_PAIR *check);
366
367 rlm_rcode_t rlm_ldap_check_userobj_dynamic(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
368                                            char const *dn, VALUE_PAIR *check);
369
370 rlm_rcode_t rlm_ldap_check_cached(ldap_instance_t const *inst, REQUEST *request, VALUE_PAIR *check);
371
372 /*
373  *      attrmap.c - Attribute mapping code.
374  */
375 int rlm_ldap_map_verify(ldap_instance_t *inst, value_pair_map_t **head);
376
377 void rlm_ldap_map_xlat_free(rlm_ldap_map_xlat_t const *expanded);
378
379 int rlm_ldap_map_xlat(REQUEST *request, value_pair_map_t const *maps, rlm_ldap_map_xlat_t *expanded);
380
381 void rlm_ldap_map_do(ldap_instance_t const *inst, REQUEST *request, LDAP *handle,
382                      rlm_ldap_map_xlat_t const *expanded, LDAPMessage *entry);
383
384 rlm_rcode_t rlm_ldap_map_profile(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
385                                  char const *profile, rlm_ldap_map_xlat_t const *expanded);
386
387 /*
388  *      clients.c - Dynamic clients (bulk load).
389  */
390 int  rlm_ldap_load_clients(ldap_instance_t const *inst);
391
392 /*
393  *      edir.c - Magic extensions for Novell
394  */
395 int nmasldap_get_password(LDAP *ld, char const *dn, char *password, size_t *len);
396
397 char const *edir_errstr(int code);
398
399 #endif