1 /**
2  * $Id: c86b097f7428bbf4a9d2767c9be21202e355daa5 $
3  * @file ldap.h
4  * @brief LDAP authorization and authentication module headers.
5  *
6  * @author Arran Cudbard-Bell <a.cudbardb@freeradius.org>
7  * @copyright 2015 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
8  * @copyright 2013 Network RADIUS SARL<info@networkradius.com>
9  * @copyright 2013-2015 The FreeRADIUS Server Project.
10  */
11 #ifndef _RLM_LDAP_H
12 #define _RLM_LDAP_H
13 
14 #include <freeradius-devel/radiusd.h>
15 #include <freeradius-devel/modules.h>
16 
17 /*
18  *	We're mostly using the new API now, but ldap_bind
19  *	is in the list of deprecated functions, at we may
20  *	always need to support that.
21  */
22 #define LDAP_DEPRECATED 1
23 #include <lber.h>
24 #include <ldap.h>
25 #include "config.h"
26 
27 /*
28  *	Ensure the have the ldap_create_sort_keylist()
29  *	function too, else we can't use ldap_create_sort_control()
30  */
31 #if !defined(LDAP_CREATE_SORT_KEYLIST) || !defined(LDAP_FREE_SORT_KEYLIST)
32 #  undef HAVE_LDAP_CREATE_SORT_CONTROL
33 #endif
34 
35 /*
36  *	Because the LTB people define LDAP_VENDOR_VERSION_PATCH
37  *	as X, which precludes its use in printf statements *sigh*
38  *
39  *	Identifiers that are not macros, all evaluate to 0,
40  *	which is why this works.
41  */
42 #if !defined(LDAP_VENDOR_VERSION_PATCH) || LDAP_VENDOR_VERSION_PATCH == 0
43 #  undef LDAP_VENDOR_VERSION_PATCH
44 #  define LDAP_VENDOR_VERSION_PATCH 0
45 #endif
46 
47 /*
48  *      For compatibility with other LDAP libraries
49  */
50 #if !defined(LDAP_SCOPE_BASE) && defined(LDAP_SCOPE_BASEOBJECT)
51 #  define LDAP_SCOPE_BASE LDAP_SCOPE_BASEOBJECT
52 #endif
53 
54 #if !defined(LDAP_SCOPE_ONE) && defined(LDAP_SCOPE_ONELEVEL)
55 #  define LDAP_SCOPE_ONE LDAP_SCOPE_ONELEVEL
56 #endif
57 
58 #if !defined(LDAP_SCOPE_SUB) && defined(LDAP_SCOPE_SUBTREE)
59 #  define LDAP_SCOPE_SUB LDAP_SCOPE_SUBTREE
60 #endif
61 
62 #if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER)
63 #  define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
64 #endif
65 
66 #ifndef LDAP_CONST
67 #  define LDAP_CONST
68 #endif
69 
70 #if defined(HAVE_LDAP_URL_PARSE) && defined(HAVE_LDAP_IS_LDAP_URL) && defined(HAVE_LDAP_URL_DESC2STR)
71 #  define LDAP_CAN_PARSE_URLS
72 #endif
73 
74 #define MOD_PREFIX			"rlm_ldap"	//!< The name of the module.
75 
76 #define LDAP_MAX_ATTRMAP		128		//!< Maximum number of mappings between LDAP and
77 							//!< FreeRADIUS attributes.
78 #define LDAP_MAP_RESERVED		4		//!< Number of additional items to allocate in expanded
79 							//!< attribute name arrays. Currently for enable attribute,
80 							//!< group membership attribute, valuepair attribute,
81 							//!< and profile attribute.
82 
83 #define LDAP_MAX_CACHEABLE		64		//!< Maximum number of groups we retrieve from the server for
84 							//!< a given user. If more than this number are retrieve the
85 							//!< module returns invalid.
86 
87 #define LDAP_MAX_GROUP_NAME_LEN		128		//!< Maximum name of a group name.
88 #define LDAP_MAX_ATTR_STR_LEN		256		//!< Maximum length of an xlat expanded LDAP attribute.
89 #define LDAP_MAX_FILTER_STR_LEN		1024		//!< Maximum length of an xlat expanded filter.
90 #define LDAP_MAX_DN_STR_LEN		1024		//!< Maximum length of an xlat expanded DN.
91 
92 #define LDAP_VIRTUAL_DN_ATTR		"dn"		//!< 'Virtual' attribute which maps to the DN of the object.
93 
94 typedef struct ldap_acct_section {
95 	CONF_SECTION	*cs;				//!< Section configuration.
96 
97 	char const	*reference;			//!< Configuration reference string.
98 } ldap_acct_section_t;
99 
100 typedef struct ldap_sasl {
101 	char const	*mech;				//!< SASL mech(s) to try.
102 	char const	*proxy;				//!< Identity to proxy.
103 	char const	*realm;				//!< Kerberos realm.
104 } ldap_sasl;
105 
106 typedef struct ldap_sasl_dynamic {
107 	vp_tmpl_t	*mech;				//!< SASL mech(s) to try.
108 	vp_tmpl_t	*proxy;				//!< Identity to proxy.
109 	vp_tmpl_t	*realm;				//!< Kerberos realm.
110 } ldap_sasl_dynamic;
111 
112 typedef struct ldap_instance {
113 	CONF_SECTION	*cs;				//!< Main configuration section for this instance.
114 	fr_connection_pool_t *pool;			//!< Connection pool instance.
115 
116 	char const	*config_server;			//!< Server set in the config.
117 	char		*server;			//!< Initial server to bind to.
118 	uint16_t	port;				//!< Port to use when binding to the server.
119 
120 	char const	*admin_identity;		//!< Identity we bind as when we need to query the LDAP
121 							//!< directory.
122 	char const	*admin_password;		//!< Password used in administrative bind.
123 
124 	ldap_sasl	admin_sasl;			//!< SASL parameters used when binding as the admin.
125 
126 	const char	*sasl_secprops;			//!< SASL Security Properties to set.
127 
128 	char const	*dereference_str;		//!< When to dereference (never, searching, finding, always)
129 	int		dereference;			//!< libldap value specifying dereferencing behaviour.
130 
131 	bool		chase_referrals;		//!< If the LDAP server returns a referral to another server
132 							//!< or point in the tree, follow it, establishing new
133 							//!< connections and binding where necessary.
134 	bool		chase_referrals_unset;		//!< If true, use the OpenLDAP defaults for chase_referrals.
135 
136 	bool		rebind;				//!< Controls whether we set an ldad_rebind_proc function
137 							//!< and so determines if we can bind to other servers whilst
138 							//!< chasing referrals. If this is false, we will still chase
139 							//!< referrals on the same server, but won't bind to other
140 							//!< servers.
141 
142 	uint32_t	ldap_debug;			//!< Debug flag for the SDK.
143 
144 	char const	*name;				//!< Instance name.
145 
146 	bool		expect_password;		//!< True if the user_map included a mapping between an LDAP
147 							//!< attribute and one of our password reference attributes.
148 
149 	/*
150 	 *	RADIUS attribute to LDAP attribute maps
151 	 */
152 	vp_map_t	*user_map; 			//!< Attribute map applied to users and profiles.
153 
154 	/*
155 	 *	User object attributes and filters
156 	 */
157 	vp_tmpl_t	*userobj_filter;		//!< Filter to retrieve only user objects.
158 	vp_tmpl_t	*userobj_base_dn;		//!< DN to search for users under.
159 	char const	*userobj_scope_str;		//!< Scope (sub, one, base).
160 	char const	*userobj_sort_by;		//!< List of attributes to sort by.
161 	LDAPControl	*userobj_sort_ctrl;		//!< Server side sort control.
162 
163 	int		userobj_scope;			//!< Search scope.
164 
165 	char const	*user_dn;			//!< for multiple LDAP modules
166 	DICT_ATTR const *user_dn_da;			//!< cached user DN
167 
168 	char const	*userobj_membership_attr;	//!< Attribute that describes groups the user is a member of.
169 	char const	*userobj_access_attr;		//!< Attribute to check to see if the user should be locked out.
170 	bool		access_positive;		//!< If true the presence of the attribute will allow access,
171 							//!< else it will deny access.
172 
173 	char const	*valuepair_attr;		//!< Generic dynamic mapping attribute, contains a RADIUS
174 							//!< attribute and value.
175 
176 	ldap_sasl_dynamic user_sasl;			//!< SASL parameters used when binding as the user.
177 
178 	/*
179 	 *	Group object attributes and filters
180 	 */
181 	char const	*groupobj_filter;		//!< Filter to retrieve only group objects.
182 	vp_tmpl_t	*groupobj_base_dn;		//!< DN to search for users under.
183 	char const	*groupobj_scope_str;		//!< Scope (sub, one, base).
184 	int		groupobj_scope;			//!< Search scope.
185 
186 	char const	*groupobj_name_attr;		//!< The name of the group.
187 	char const	*groupobj_membership_filter;	//!< Filter to only retrieve groups which contain
188 							//!< the user as a member.
189 
190 	bool		cacheable_group_name;		//!< If true the server will determine complete set of group
191 							//!< memberships for the current user object, and perform any
192 							//!< resolution necessary to determine the names of those
193 							//!< groups, then right them to the control list (LDAP-Group).
194 
195 	bool		cacheable_group_dn;		//!< If true the server will determine complete set of group
196 							//!< memberships for the current user object, and perform any
197 							//!< resolution necessary to determine the DNs of those groups,
198 							//!< then right them to the control list (LDAP-GroupDN).
199 
200 	char const	*cache_attribute;		//!< Sets the attribute we use when creating and retrieving
201 							//!< cached group memberships.
202 
203 	DICT_ATTR const	*cache_da;			//!< The DA associated with this specific instance of the
204 							//!< rlm_ldap module.
205 
206 	DICT_ATTR const	*group_da;			//!< The DA associated with this specific instance of the
207 							//!< rlm_ldap module.
208 
209 	bool		allow_dangling_group_refs;	//!< Don't error if we fail to resolve a group DN referenced
210 							///< from a user object.
211 
212 
213 	/*
214 	 *	Dynamic clients
215 	 */
216 	char const	*clientobj_filter;		//!< Filter to retrieve only client objects.
217 	char const	*clientobj_base_dn;		//!< DN to search for clients under.
218 	char const	*clientobj_scope_str;		//!< Scope (sub, one, base).
219 	int		clientobj_scope;		//!< Search scope.
220 
221 	bool		do_clients;			//!< If true, attempt to load clients on instantiation.
222 
223 	/*
224 	 *	Profiles
225 	 */
226 	vp_tmpl_t	*default_profile;		//!< If this is set, we will search for a profile object
227 							//!< with this name, and map any attributes it contains.
228 							//!< No value should be set if profiles are not being used
229 							//!< as there is an associated performance penalty.
230 	char const	*profile_attr;			//!< Attribute that identifies profiles to apply. May appear
231 							//!< in userobj or groupobj.
232 	vp_tmpl_t	*profile_filter;		//!< Filter to retrieve only retrieve group objects.
233 
234 	/*
235 	 *	Accounting
236 	 */
237 	ldap_acct_section_t *postauth;			//!< Modify mappings for post-auth.
238 	ldap_acct_section_t *accounting;		//!< Modify mappings for accounting.
239 
240 	/*
241 	 *	TLS items.  We should really normalize these with the
242 	 *	TLS code in 3.0.
243 	 */
244 	int		tls_mode;
245 	bool		start_tls;			//!< Send the Start TLS message to the LDAP directory
246 							//!< to start encrypted communications using the standard
247 							//!< LDAP port.
248 
249 	char const	*tls_ca_file;			//!< Sets the full path to a CA certificate (used to validate
250 							//!< the certificate the server presents).
251 
252 	char const	*tls_ca_path;			//!< Sets the path to a directory containing CA certificates.
253 
254 	char const	*tls_certificate_file;		//!< Sets the path to the public certificate file we present
255 							//!< to the servers.
256 
257 	char const	*tls_private_key_file;		//!< Sets the path to the private key for our public
258 							//!< certificate.
259 
260 	char const	*tls_random_file;		//!< Path to the random file if /dev/random and /dev/urandom
261 							//!< are unavailable.
262 
263 	char const	*tls_require_cert_str;		//!< Sets requirements for validating the certificate the
264 							//!< server presents.
265 
266 	int		tls_require_cert;		//!< OpenLDAP constant representing the require cert string.
267 
268 	char const	*tls_min_version_str;		//!< Minimum TLS version
269 	int		tls_min_version;
270 
271 	/*
272 	 *	Options
273 	 */
274 	uint32_t  	net_timeout;			//!< How long we wait for new connections to the LDAP server
275 							//!< to be established.
276 	uint32_t	res_timeout;			//!< How long we wait for a result from the server.
277 	uint32_t	srv_timelimit;			//!< How long the server should spent on a single request
278 							//!< (also bounded by value on the server).
279 
280 #ifdef WITH_EDIR
281 	/*
282 	 *	eDir support
283 	 */
284 	bool		edir;				//!< If true attempt to retrieve the user's cleartext password
285 							//!< using the Universal Password feature of Novell eDirectory.
286 	bool		edir_autz;			//!< If true, and we have the Universal Password, bind with it
287 							//!< to perform additional authorisation checks.
288 #endif
289 	/*
290 	 *	For keep-alives.
291 	 */
292 #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
293 	uint32_t	keepalive_idle;			//!< Number of seconds a connections needs to remain idle
294 							//!< before TCP starts sending keepalive probes.
295 #endif
296 #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
297 	uint32_t	keepalive_probes;		//!< Number of missed timeouts before the connection is
298 							//!< dropped.
299 #endif
300 #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
301 	uint32_t	keepalive_interval;		//!< Interval between keepalive probes.
302 #endif
303 
304 	LDAP		*handle;			//!< Hack for OpenLDAP libldap global initialisation.
305 } rlm_ldap_t;
306 
307 /** Tracks the state of a libldap connection handle
308  *
309  */
310 typedef struct ldap_handle {
311 	LDAP		*handle;			//!< libldap handle.
312 	bool		rebound;			//!< Whether the connection has been rebound to something
313 							//!< other than the admin user.
314 	bool		referred;			//!< Whether the connection is now established a server
315 							//!< other than the configured one.
316 	rlm_ldap_t	*inst;				//!< rlm_ldap configuration.
317 } ldap_handle_t;
318 
319 /** Result of expanding the RHS of a set of maps
320  *
321  * Used to store the array of attributes we'll be querying for.
322  */
323 typedef struct rlm_ldap_map_exp {
324 	vp_map_t const *maps;				//!< Head of list of maps we expanded the RHS of.
325 	char const	*attrs[LDAP_MAX_ATTRMAP + LDAP_MAP_RESERVED + 1]; //!< Reserve some space for access attributes
326 							//!< and NULL termination.
327 	TALLOC_CTX	*ctx;				//!< Context to allocate new attributes in.
328 	int		count;				//!< Index on next free element.
329 } rlm_ldap_map_exp_t;
330 
331 /** Contains a collection of values
332  *
333  */
334 typedef struct rlm_ldap_result {
335 	struct berval	**values;			//!< libldap struct containing bv_val (char *)
336 							//!< and length bv_len.
337 	int		count;				//!< Number of values.
338 } rlm_ldap_result_t;
339 
340 /** Codes returned by rlm_ldap internal functions
341  *
342  */
343 typedef enum {
344 	LDAP_PROC_CONTINUE = 1,				//!< Operation is in progress.
345 	LDAP_PROC_SUCCESS = 0,				//!< Operation was successfull.
346 
347 	LDAP_PROC_ERROR	= -1,				//!< Unrecoverable library/server error.
348 
349 	LDAP_PROC_RETRY	= -2,				//!< Transitory error, caller should retry the operation
350 							//!< with a new connection.
351 
352 	LDAP_PROC_NOT_PERMITTED = -3,			//!< Operation was not permitted, either current user was
353 							//!< locked out in the case of binds, or has insufficient
354 							//!< access.
355 
356 	LDAP_PROC_REJECT = -4,				//!< Bind failed, user was rejected.
357 
358 	LDAP_PROC_BAD_DN = -5,				//!< Specified an invalid object in a bind or search DN.
359 
360 	LDAP_PROC_NO_RESULT = -6			//!< Got no results.
361 } ldap_rcode_t;
362 
363 /*
364  *	Some functions may be called with a NULL request structure, this
365  *	simplifies switching certain messages from the request log to
366  *	the main log.
367  */
368 #define LDAP_INFO(fmt, ...) INFO("rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
369 #define LDAP_WARN(fmt, ...) WARN("rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
370 
371 #define LDAP_DBGW(fmt, ...) radlog(L_DBG_WARN, "rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
372 #define LDAP_DBGW_REQ(fmt, ...) do { if (request) {RWDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_DBGW(fmt, ##__VA_ARGS__);}} while (0)
373 
374 #define LDAP_DBG(fmt, ...) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
375 #define LDAP_DBG_REQ(fmt, ...) do { if (request) {RDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
376 
377 #define LDAP_DBG2(fmt, ...) if (rad_debug_lvl >= L_DBG_LVL_2) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
378 #define LDAP_DBG_REQ2(fmt, ...) do { if (request) {RDEBUG2(fmt, ##__VA_ARGS__);} else if (rad_debug_lvl >= L_DBG_LVL_2) {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
379 
380 #define LDAP_DBG3(fmt, ...) if (rad_debug_lvl >= L_DBG_LVL_3) radlog(L_DBG, "rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
381 #define LDAP_DBG_REQ3(fmt, ...) do { if (request) {RDEBUG3(fmt, ##__VA_ARGS__);} else if (rad_debug_lvl >= L_DBG_LVL_3) {LDAP_DBG(fmt, ##__VA_ARGS__);}} while (0)
382 
383 #define LDAP_ERR(fmt, ...) ERROR("rlm_ldap (%s): " fmt, inst->name, ##__VA_ARGS__)
384 #define LDAP_ERR_REQ(fmt, ...) do { if (request) {REDEBUG(fmt, ##__VA_ARGS__);} else {LDAP_ERR(fmt, ##__VA_ARGS__);}} while (0)
385 
386 #define LDAP_EXT() if (extra) LDAP_ERR(extra)
387 #define LDAP_EXT_REQ() do { if (extra) { if (request) REDEBUG("%s", extra); else LDAP_ERR("%s", extra); }} while (0)
388 
389 extern FR_NAME_NUMBER const ldap_scope[];
390 extern FR_NAME_NUMBER const ldap_tls_require_cert[];
391 
392 /*
393  *	ldap.c - Wrappers arounds OpenLDAP functions.
394  */
395 size_t rlm_ldap_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg);
396 
397 bool rlm_ldap_is_dn(char const *in, size_t inlen);
398 
399 size_t rlm_ldap_normalise_dn(char *out, char const *in);
400 
401 ssize_t rlm_ldap_xlat_filter(REQUEST *request, char const **sub, size_t sublen, char *out, size_t outlen);
402 
403 ldap_rcode_t rlm_ldap_bind(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn,
404 			   char const *password, ldap_sasl *sasl, bool retry);
405 
406 char const *rlm_ldap_error_str(ldap_handle_t const *conn);
407 
408 ldap_rcode_t rlm_ldap_search(LDAPMessage **result, rlm_ldap_t const *inst, REQUEST *request,
409 			     ldap_handle_t **pconn,
410 			     char const *dn, int scope, char const *filter, char const * const *attrs,
411 			     LDAPControl **serverctrls, LDAPControl **clientctrls);
412 
413 ldap_rcode_t rlm_ldap_modify(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn,
414 			     char const *dn, LDAPMod *mods[]);
415 
416 char const *rlm_ldap_find_user(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn,
417 			       char const *attrs[], bool force, LDAPMessage **result, rlm_rcode_t *rcode);
418 
419 rlm_rcode_t rlm_ldap_check_access(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t const *conn,
420 				  LDAPMessage *entry);
421 
422 void rlm_ldap_check_reply(rlm_ldap_t const *inst, REQUEST *request);
423 
424 /*
425  *	ldap.c - Callbacks for the connection pool API.
426  */
427 ldap_rcode_t rlm_ldap_result(rlm_ldap_t const *inst, ldap_handle_t const *conn, int msgid, char const *dn,
428 			     LDAPMessage **result, char const **error, char **extra);
429 
430 char *rlm_ldap_berval_to_string(TALLOC_CTX *ctx, struct berval const *in);
431 
432 int rlm_ldap_global_init(rlm_ldap_t *inst) CC_HINT(nonnull);
433 
434 void *mod_conn_create(TALLOC_CTX *ctx, void *instance);
435 
436 ldap_handle_t *mod_conn_get(rlm_ldap_t const *inst, REQUEST *request);
437 
438 void mod_conn_release(rlm_ldap_t const *inst, ldap_handle_t *conn);
439 
440 /*
441  *	groups.c - Group membership functions.
442  */
443 rlm_rcode_t rlm_ldap_cacheable_userobj(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn,
444 				       LDAPMessage *entry, char const *attr);
445 
446 rlm_rcode_t rlm_ldap_cacheable_groupobj(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn);
447 
448 rlm_rcode_t rlm_ldap_check_groupobj_dynamic(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn,
449 					    VALUE_PAIR *check);
450 
451 rlm_rcode_t rlm_ldap_check_userobj_dynamic(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn,
452 					   char const *dn, VALUE_PAIR *check);
453 
454 rlm_rcode_t rlm_ldap_check_cached(rlm_ldap_t const *inst, REQUEST *request, VALUE_PAIR *check);
455 
456 /*
457  *	attrmap.c - Attribute mapping code.
458  */
459 int rlm_ldap_map_getvalue(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx);
460 
461 int rlm_ldap_map_verify(vp_map_t *map, void *instance);
462 
463 int rlm_ldap_map_expand(rlm_ldap_map_exp_t *expanded, REQUEST *request, vp_map_t const *maps);
464 
465 int rlm_ldap_map_do(rlm_ldap_t const *inst, REQUEST *request, LDAP *handle,
466 		    rlm_ldap_map_exp_t const *expanded, LDAPMessage *entry);
467 
468 /*
469  *	clients.c - Dynamic clients (bulk load).
470  */
471 int  rlm_ldap_client_load(rlm_ldap_t const *inst, CONF_SECTION *tmpl, CONF_SECTION *cs);
472 
473 /*
474  *	edir.c - Magic extensions for Novell
475  */
476 int nmasldap_get_password(LDAP *ld, char const *dn, char *password, size_t *len);
477 
478 char const *edir_errstr(int code);
479 
480 /*
481  *	sasl.s - SASL bind functions
482  */
483 ldap_rcode_t rlm_ldap_sasl_interactive(rlm_ldap_t const *inst, REQUEST *request,
484 				       ldap_handle_t *pconn, char const *dn,
485 				       char const *password, ldap_sasl *sasl,
486 				       char const **error, char **error_extra);
487 #endif
488