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