30 RCSID(
"$Id: fc789e2174ba69fff74e64324902c39ebeeafd2e $")
34 #include <freeradius-devel/util/debug.h>
35 #include <freeradius-devel/util/table.h>
36 #include <freeradius-devel/util/uri.h>
37 #include <freeradius-devel/util/value.h>
39 #include <freeradius-devel/ldap/conf.h>
40 #include <freeradius-devel/ldap/base.h>
42 #include <freeradius-devel/server/map_proc.h>
43 #include <freeradius-devel/server/module_rlm.h>
44 #include <freeradius-devel/server/rcode.h>
46 #include <freeradius-devel/unlang/xlat_func.h>
47 #include <freeradius-devel/unlang/action.h>
152 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
180 #define USER_CALL_ENV_COMMON(_struct) \
181 { FR_CALL_ENV_OFFSET("base_dn", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_CONCAT, _struct, user_base), .pair.dflt = "", .pair.dflt_quote = T_SINGLE_QUOTED_STRING }, \
182 { FR_CALL_ENV_OFFSET("filter", FR_TYPE_STRING, CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_CONCAT, _struct, user_filter), .pair.dflt = "(&)", .pair.dflt_quote = T_SINGLE_QUOTED_STRING }
193 .pair.dflt =
"&User-Password", .pair.dflt_quote =
T_BARE_WORD },
291 .expect_password_offset = -1
388 #define LDAP_URI_SAFE_FOR (fr_value_box_safe_for_t)fr_ldap_uri_escape_func
429 if (!fr_sbuff_init_talloc(vb, &sbuff, &sbuff_ctx, in_vb->vb_length * 3, in_vb->vb_length * 3)) {
430 REDEBUG(
"Failed to allocate buffer for escaped string");
472 if (!fr_sbuff_init_talloc(vb, &sbuff, &sbuff_ctx, in_vb->vb_length, in_vb->vb_length)) {
473 REDEBUG(
"Failed to allocate buffer for unescaped string");
506 if (!fr_sbuff_init_talloc(vb, &sbuff, &sbuff_ctx, vb->vb_length * 3, vb->vb_length * 3)) {
536 if (!query->
treq)
return;
539 request = treq->request;
560 struct berval **values;
570 for (attr = query->search.attrs; *attr; attr++) {
571 values = ldap_get_values_len(ldap_conn->
handle,
msg, *attr);
573 RDEBUG2(
"No \"%s\" attributes found in specified object", *attr);
577 count = ldap_count_values_len(values);
578 for (i = 0; i <
count; i++) {
582 RPERROR(
"Failed creating value from LDAP response");
587 ldap_value_free_len(values);
603 if (!query->
treq)
return;
605 RDEBUG2(
"Forcefully cancelling pending LDAP query");
642 static inline CC_HINT(always_inline)
647 LDAPURLDesc tmp_desc = {
648 .lud_scheme = url_parsed->lud_scheme,
649 .lud_host = url_parsed->lud_host,
650 .lud_port = url_parsed->lud_port,
653 host = ldap_url_desc2str(&tmp_desc);
654 if (
unlikely(host == NULL))
REDEBUG(
"Invalid LDAP URL - %pV", url_in); \
669 char *host_url, *host = NULL;
674 LDAPURLDesc *ldap_url;
680 RPERROR(
"Failed to escape LDAP URI");
687 uri = fr_value_box_list_head(&uri_components->vb_group);
691 REDEBUG(
"Failed concattenating input");
695 if (!ldap_is_ldap_url(uri->vb_strvalue)) {
696 REDEBUG(
"String passed does not look like an LDAP URL");
700 ldap_url_ret = ldap_url_parse(uri->vb_strvalue, &ldap_url);
701 if (ldap_url_ret != LDAP_URL_SUCCESS){
704 ldap_free_urldesc(ldap_url);
711 if (!ldap_url->lud_attrs || !ldap_url->lud_attrs[0] || !*ldap_url->lud_attrs[0] ||
712 (strcmp(ldap_url->lud_attrs[0],
"*") == 0) || ldap_url->lud_attrs[1]) {
713 REDEBUG(
"Bad attributes list in LDAP URL. URL must specify exactly one attribute to retrieve");
718 ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter,
719 (
char const *
const*)ldap_url->lud_attrs, NULL, NULL);
722 if (ldap_url->lud_exts) {
728 RPERROR(
"Parsing URL extensions failed");
735 if (!serverctrls[i])
break;
744 if (!ldap_url->lud_host) {
745 host_url = handle_config->
server;
748 if (
unlikely(host_url == NULL))
goto query_error;
753 if (host) ldap_memfree(host);
755 REDEBUG(
"Unable to get LDAP query for xlat");
765 REDEBUG(
"Unable to enqueue LDAP query for xlat");
771 REDEBUG(
"Unable to set timeout for LDAP query");
808 #define REPEAT_LDAP_MEMBEROF_XLAT_RESULTS \
809 if (unlang_function_repeat_set(request, ldap_memberof_xlat_results) < 0) do { \
810 rcode = RLM_MODULE_FAIL; \
825 switch (xlat_ctx->
status) {
830 if (
inst->group.obj_membership_filter) {
840 if (xlat_ctx->
found) {
845 if (
inst->group.userobj_membership_attr) {
873 vb->vb_bool = xlat_ctx->
found;
898 RDEBUG2(
"Searching for user in group \"%pV\"", group_vb);
900 if (group_vb->vb_length == 0) {
901 REDEBUG(
"Cannot do comparison (group name is empty)");
910 MEM(norm = talloc_array(group_vb,
char, talloc_array_length(group_vb->vb_strvalue)));
924 if ((group_is_dn &&
inst->group.cacheable_dn) || (!group_is_dn &&
inst->group.cacheable_name)) {
930 RDEBUG2(
"User is not a member of \"%pV\"", group_vb);
953 .attrs = {
inst->group.userobj_membership_attr, NULL },
954 .group_is_dn = group_is_dn,
959 inst->handle_config.admin_password, request, &
inst->handle_config);
962 REDEBUG(
"Unable to get LDAP trunk for group membership check");
1002 ldap_free_urldesc(to_free->
url);
1003 to_free->
url = NULL;
1022 char *host_url, *host = NULL;
1045 RPERROR(
"Failed to escape LDAP DN");
1050 RPERROR(
"Failed to escape LDAP URI");
1058 uri = fr_value_box_list_head(&uri_components->vb_group);
1061 REDEBUG(
"Failed concattenating input");
1072 host_url = handle_config->
server;
1075 scope =
inst->profile_scope;
1077 ldap_url_ret = ldap_url_parse(uri->vb_strvalue, &xlat_ctx->
url);
1078 if (ldap_url_ret != LDAP_URL_SUCCESS){
1088 if (!xlat_ctx->
url->lud_dn) {
1089 REDEBUG(
"LDAP URI must specify a profile DN");
1093 dn = xlat_ctx->
url->lud_dn;
1098 filter = xlat_ctx->
url->lud_filter ? xlat_ctx->
url->lud_filter : env_data->
profile_filter.vb_strvalue;
1103 scope = xlat_ctx->
url->lud_scope == LDAP_SCOPE_DEFAULT ?
inst->profile_scope : xlat_ctx->
url->lud_scope;
1108 if (!xlat_ctx->
url->lud_host) {
1109 host_url = handle_config->
server;
1112 if (
unlikely(host_url == NULL))
goto error;
1120 inst->valuepair_attr) < 0)
goto error;
1123 if (host) ldap_memfree(host);
1125 REDEBUG(
"Unable to get LDAP query for xlat");
1171 switch (query->
ret) {
1193 RDEBUG2(
"Processing \"%s\"", dn);
1197 for (map = map_list_head(map_ctx->
maps), i = 0;
1199 map = map_list_next(map_ctx->
maps, map), i++) {
1211 struct berval
value;
1212 struct berval *values[2] = { &
value, NULL };
1216 value.bv_len = strlen(dn);
1230 RDEBUG3(
"Attribute \"%s\" not found in LDAP object", expanded->
attrs[i]);
1237 ldap_value_free_len(attr.
values);
1258 ldap_free_urldesc(map_ctx->
ldap_url);
1281 fr_value_box_list_t *url, map_list_t
const *maps)
1286 LDAPURLDesc *ldap_url;
1292 char *host_url, *host = NULL;
1301 url_head = fr_value_box_list_head(url);
1303 REDEBUG(
"LDAP URL cannot be (null)");
1309 REDEBUG(
"Failed concatenating input");
1313 if (!ldap_is_ldap_url(url_head->vb_strvalue)) {
1314 REDEBUG(
"Map query string does not look like a valid LDAP URI");
1320 map_ctx->
maps = maps;
1322 ldap_url_ret = ldap_url_parse(url_head->vb_strvalue, &map_ctx->
ldap_url);
1323 if (ldap_url_ret != LDAP_URL_SUCCESS){
1339 if (!ldap_url->lud_host) {
1340 host_url =
inst->handle_config.server;
1343 if (
unlikely(host_url == NULL))
goto fail;
1347 inst->handle_config.admin_password, request, &
inst->handle_config);
1348 if (host) ldap_memfree(host);
1349 if (!ttrunk)
goto fail;
1355 ldap_url->lud_scope, ldap_url->lud_filter, map_ctx->
expanded.
attrs,
1370 inst->handle_config.admin_password, request, &
inst->handle_config);
1399 RDEBUG(
"Configuration item 'sasl.mech' is not supported. "
1400 "The linked version of libldap does not provide ldap_sasl_bind( function");
1413 if (!auth_ctx->
dn) {
1418 RDEBUG2(
"Login attempt as \"%s\"", auth_ctx->
dn);
1431 RWDEBUG(
"You have set \"Auth-Type := LDAP\" somewhere");
1433 RWDEBUG(
"*********************************************");
1434 RWDEBUG(
"* THAT CONFIGURATION IS WRONG. DELETE IT. ");
1435 RWDEBUG(
"* YOU ARE PREVENTING THE SERVER FROM WORKING");
1436 RWDEBUG(
"*********************************************");
1446 RDEBUG(
"Login attempt with password \"%pV\"", &call_env->
password);
1448 RDEBUG2(
"Login attempt with password");
1456 .call_env = call_env
1483 #define REPEAT_MOD_AUTHORIZE_RESUME \
1484 if (unlang_function_repeat_set(request, mod_authorize_resume) < 0) do { \
1485 rcode = RLM_MODULE_FAIL; \
1514 switch (*p_result) {
1527 switch (autz_ctx->
status) {
1535 if (!autz_ctx->
entry) {
1536 ldap_get_option(handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
1537 REDEBUG(
"Failed retrieving entry: %s", ldap_err2string(ldap_errno));
1545 if (
inst->user.obj_access_attr) {
1552 if (
inst->group.skip_on_suspend)
goto post_group;
1564 if ((
inst->group.cacheable_dn ||
inst->group.cacheable_name) && (
inst->group.userobj_membership_attr)) {
1576 if (
inst->group.cacheable_dn ||
inst->group.cacheable_name) {
1604 autz_ctx->
status = LDAP_AUTZ_EDIR_BIND;
1610 case LDAP_AUTZ_EDIR_BIND:
1611 if (
inst->edir &&
inst->edir_autz) {
1618 REDEBUG(
"Failed to find &control.Password.Cleartext");
1623 RDEBUG2(
"Binding as %s for eDirectory authorization checks", autz_ctx->
dn);
1629 autz_ctx->
status = LDAP_AUTZ_POST_EDIR;
1634 case LDAP_AUTZ_POST_EDIR:
1653 if (!map_list_empty(call_env->
user_map) ||
inst->valuepair_attr) {
1654 RDEBUG2(
"Processing user attributes");
1700 if (
inst->profile_attr) {
1706 RDEBUG2(
"Processing %i profile(s) found in attribute \"%s\"",
count,
inst->profile_attr);
1708 for (
struct berval **bv_p = autz_ctx->
profile_values; *bv_p; bv_p++) {
1713 RDEBUG2(
"No profile(s) found in attribute \"%s\"",
inst->profile_attr);
1719 if (
inst->profile_attr_suspend) {
1725 RDEBUG2(
"Processing %i suspension profile(s) found in attribute \"%s\"",
count,
inst->profile_attr_suspend);
1727 for (
struct berval **bv_p = autz_ctx->
profile_values; *bv_p; bv_p++) {
1728 RDEBUG3(
"Will evaluate suspenension profile with DN \"%pV\"",
1733 RDEBUG2(
"No suspension profile(s) found in attribute \"%s\"",
inst->profile_attr_suspend);
1827 inst->handle_config.admin_password, request, &
inst->handle_config);
1828 if (!autz_ctx->
ttrunk)
goto fail;
1830 #define CHECK_EXPANDED_SPACE(_expanded) fr_assert((size_t)_expanded->count < (NUM_ELEMENTS(_expanded->attrs) - 1));
1835 if (
inst->user.obj_access_attr) {
1840 if (
inst->group.userobj_membership_attr && (
inst->group.cacheable_dn ||
inst->group.cacheable_name)) {
1842 expanded->
attrs[expanded->
count++] =
inst->group.userobj_membership_attr;
1845 if (
inst->profile_attr) {
1850 if (
inst->profile_attr_suspend) {
1901 switch (query->
ret) {
1907 RDEBUG2(
"User object \"%s\" not modified", usermod_ctx->
dn);
1927 LDAPMod **modify = usermod_ctx->
mod_p;
1935 if (!usermod_ctx->
dn) {
1945 usermod_ctx->
dn, modify, NULL, NULL);
1966 int total = 0, last_pass = 0;
1988 if (section->
reference[0] !=
'.') *p++ =
'.';
1990 if (
xlat_eval(p, (
sizeof(path) - (p - path)) - 1, request, section->
reference, NULL, NULL) < 0)
goto error;
1993 if (!ci)
goto error;
1996 REDEBUG(
"Reference must resolve to a section");
2003 REDEBUG(
"Section must contain 'update' subsection");
2011 .call_env = call_env
2018 bool do_xlat =
false;
2021 REDEBUG(
"Modify map size exceeded");
2027 REDEBUG(
"Entry is not in \"ldap-attribute = value\" format");
2041 RDEBUG2(
"Empty value string, skipping attribute \"%s\"", attr);
2062 usermod_ctx->
passed[last_pass] = NULL;
2063 }
else if (do_xlat) {
2067 RDEBUG2(
"Skipping attribute \"%s\"", attr);
2073 usermod_ctx->
passed[last_pass] = exp;
2078 memcpy(&(usermod_ctx->
passed[last_pass]), &
value,
sizeof(usermod_ctx->
passed[last_pass]));
2081 usermod_ctx->
passed[last_pass + 1] = NULL;
2082 usermod_ctx->
mod_s[total].mod_values = &(usermod_ctx->
passed[last_pass]);
2091 usermod_ctx->
mod_s[total].mod_op = LDAP_MOD_ADD;
2095 usermod_ctx->
mod_s[total].mod_op = LDAP_MOD_REPLACE;
2100 usermod_ctx->
mod_s[total].mod_op = LDAP_MOD_DELETE;
2104 usermod_ctx->
mod_s[total].mod_op = LDAP_MOD_INCREMENT;
2108 REDEBUG(
"Operator '%s' is not supported for LDAP modify operations",
2118 memcpy(&(usermod_ctx->
mod_s[total].mod_type), &attr,
sizeof(usermod_ctx->
mod_s[total].mod_type));
2120 usermod_ctx->
mod_p[total] = &(usermod_ctx->
mod_s[total]);
2129 usermod_ctx->
mod_p[total] = NULL;
2132 inst->handle_config.admin_identity,
2133 inst->handle_config.admin_password,
2134 request, &
inst->handle_config);
2135 if (!usermod_ctx->
ttrunk) {
2136 REDEBUG(
"Unable to get LDAP trunk for update");
2150 TALLOC_FREE(usermod_ctx);
2182 if (
inst->user.obj_sort_ctrl) ldap_control_free(
inst->user.obj_sort_ctrl);
2210 DEBUG2(
"rlm_ldap (%s) - Couldn't find configuration for %s, will return NOOP for calls "
2220 PERROR(
"rlm_ldap (%s) - Failed parsing configuration for section %s", mctx->
inst->
name,
name);
2253 inst->handle_config.admin_password, NULL, &
inst->handle_config);
2255 ERROR(
"Unable to launch LDAP trunk");
2275 void **trunks_to_free;
2280 for (i = talloc_array_length(trunks_to_free) - 1; i >= 0; i--)
talloc_free(trunks_to_free[i]);
2301 char const *group_attribute;
2306 if (
inst->group.attribute) {
2307 group_attribute =
inst->group.attribute;
2310 group_attribute =
buffer;
2312 group_attribute =
"LDAP-Group";
2320 if (!
inst->group.da) {
2323 memset(&flags, 0,
sizeof(flags));
2326 PERROR(
"Error creating group attribute");
2336 if (
inst->group.cache_attribute) {
2339 memset(&flags, 0,
sizeof(flags));
2342 PERROR(
"Error creating cache attribute");
2348 inst->group.cache_da =
inst->group.da;
2354 inst->bind_trunk_conf.target_req_per_conn = 1;
2355 inst->bind_trunk_conf.max_req_per_conn = 1;
2360 inst->bind_trunk_conf.req_pool_headers = 2;
2389 bool expect_password =
false;
2395 map_t const *map = NULL;
2411 MEM(maps = talloc(parsed, map_list_t));
2412 map_list_init(maps);
2424 while ((map = map_list_next(maps, map))) {
2427 expect_password =
true;
2443 .name =
"expect_password",
2453 vb->vb_bool = expect_password;
2461 UNUSED char const *section_name1,
UNUSED char const *section_name2,
2465 char const *filters[] = {
inst->group.obj_filter,
inst->group.obj_membership_filter };
2470 *(
void **)
out = parsed;
2492 if (!options || !
cf_pair_find(options,
"chase_referrals")) {
2493 inst->handle_config.chase_referrals_unset =
true;
2509 if (
inst->group.cacheable_name &&
inst->group.obj_membership_filter) {
2510 if (!
inst->group.obj_name_attr) {
2511 cf_log_err(
conf,
"Configuration item 'group.name_attribute' must be set if cacheable "
2512 "group names are enabled");
2524 if (!
inst->handle_config.server_str) {
2525 cf_log_err(
conf,
"Configuration item 'server' must have a value");
2531 if (
inst->handle_config.admin_sasl.mech) {
2532 cf_log_err(
conf,
"Configuration item 'sasl.mech' not supported. "
2533 "Linked libldap does not provide ldap_sasl_interactive_bind function");
2542 inst->handle_config.server = talloc_strdup(
inst,
"");
2547 for (i = 0; i < talloc_array_length(
inst->handle_config.server_str); i++) {
2548 char const *
value =
inst->handle_config.server_str[i];
2555 for (j = 0; j < talloc_array_length(
value) - 1; j++) {
2560 cf_log_err(
conf,
"Invalid character '%c' found in 'server' configuration item",
2574 if (ldap_is_ldap_url(
value)) {
2588 if (
inst->handle_config.server) {
2589 inst->handle_config.server[talloc_array_length(
inst->handle_config.server) - 2] =
'\0';
2590 DEBUG4(
"rlm_ldap (%s) - LDAP server string: %s", mctx->
inst->
name,
inst->handle_config.server);
2596 if (
inst->handle_config.port == LDAPS_PORT ||
inst->handle_config.tls_mode) {
2597 inst->handle_config.tls_mode = LDAP_OPT_X_TLS_HARD;
2599 inst->handle_config.tls_mode = 0;
2605 if (
inst->handle_config.dereference_str) {
2607 inst->handle_config.dereference_str, -1);
2608 if (
inst->handle_config.dereference < 0) {
2609 cf_log_err(
conf,
"Invalid 'dereference' value \"%s\", expected 'never', 'searching', "
2610 "'finding' or 'always'",
inst->handle_config.dereference_str);
2618 if (
inst->user.obj_sort_by) {
2622 ret = ldap_create_sort_keylist(&keys,
UNCONST(
char *,
inst->user.obj_sort_by));
2623 if (ret != LDAP_SUCCESS) {
2625 inst->user.obj_sort_by, ldap_err2string(ret));
2634 ldap_free_sort_keylist(keys);
2635 if (ret != LDAP_SUCCESS) {
2636 ERROR(
"Failed creating server sort control: %s", ldap_err2string(ret));
2641 if (
inst->handle_config.tls_require_cert_str) {
2646 inst->handle_config.tls_require_cert_str, -1);
2647 if (
inst->handle_config.tls_require_cert < 0) {
2648 cf_log_err(
conf,
"Invalid 'tls.require_cert' value \"%s\", expected 'never', "
2649 "'demand', 'allow', 'try' or 'hard'",
inst->handle_config.tls_require_cert_str);
2654 if (
inst->handle_config.tls_min_version_str) {
2655 if (strcmp(
inst->handle_config.tls_min_version_str,
"1.2") == 0) {
2656 inst->handle_config.tls_min_version = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2;
2658 }
else if (strcmp(
inst->handle_config.tls_min_version_str,
"1.1") == 0) {
2659 inst->handle_config.tls_min_version = LDAP_OPT_X_TLS_PROTOCOL_TLS1_1;
2661 }
else if (strcmp(
inst->handle_config.tls_min_version_str,
"1.0") == 0) {
2662 inst->handle_config.tls_min_version = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
2665 cf_log_err(
conf,
"Invalid 'tls.tls_min_version' value \"%s\"",
inst->handle_config.tls_min_version_str);
2719 .thread_inst_type =
"fr_ldap_thread_t",
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
static int const char char buffer[256]
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define USES_APPLE_DEPRECATED_API
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
void call_env_parsed_free(call_env_parsed_head_t *parsed, call_env_parsed_t *ptr)
Remove a call_env_parsed_t from the list of parsed call envs.
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
void call_env_parsed_set_value(call_env_parsed_t *parsed, fr_value_box_t const *vb)
Assign a value box to a call_env_parsed_t.
#define CALL_ENV_TERMINATOR
#define FR_CALL_ENV_PARSE_OFFSET(_name, _cast_type, _flags, _struct, _field, _parse_field)
Specify a call_env_parser_t which writes out runtime results and the result of the parsing phase to t...
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
void const * uctx
User context for callback functions.
#define FR_CALL_ENV_SUBSECTION_FUNC(_name, _ident2, _flags, _func)
Specify a call_env_parser_t which parses a subsection using a callback function.
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl must contain an attribute reference.
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
@ CALL_ENV_FLAG_PARSE_MISSING
If this subsection is missing, still parse it.
@ CALL_ENV_FLAG_NULLABLE
Tmpl expansions are allowed to produce no output.
@ CALL_ENV_PARSE_TYPE_VALUE_BOX
Output of the parsing phase is a single value box (static data).
@ CALL_ENV_PARSE_TYPE_VOID
Output of the parsing phase is undefined (a custom structure).
#define FR_CALL_ENV_SUBSECTION(_name, _ident2, _flags, _subcs)
Specify a call_env_parser_t which defines a nested subsection.
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
CONF_ITEM * cf_reference_item(CONF_SECTION const *parent_cs, CONF_SECTION const *outer_cs, char const *ptr)
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define cf_section_rules_push(_cs, _rule)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct,...
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
@ CONF_FLAG_XLAT
string will be dynamically expanded.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
Configuration AVP similar to a fr_pair_t.
A section grouping multiple CONF_PAIR.
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
CONF_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
fr_token_t cf_pair_operator(CONF_PAIR const *pair)
Return the operator of a pair.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
#define cf_log_err(_cf, _fmt,...)
#define cf_item_next(_ci, _prev)
@ MOD_POST_AUTH
7 methods index for postauth section.
@ MOD_ACCOUNTING
3 methods index for accounting section.
enum rlm_components rlm_components_t
The different section components of the server.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
Specifies an attribute which must be present for the module to function.
Values of the encryption flags.
Specifies a dictionary which must be loaded/loadable for the module to function.
char const *_CONST name
Instance name.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
dl_module_inst_t const * inst
#define fr_event_timer_in(...)
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
#define GLOBAL_LIB_TERMINATOR
Structure to define how to initialise libraries with global configuration.
static xlat_action_t ldap_uri_escape_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Escape LDAP string.
static xlat_action_t ldap_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Expand an LDAP URL into a query, and return a string result from that query.
static xlat_action_t ldap_profile_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Expand an LDAP URL into a query, applying the results using the user update map.
static xlat_action_t ldap_memberof_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Check for a user being in a LDAP group.
static xlat_action_t ldap_uri_unescape_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Unescape LDAP string.
unlang_action_t rlm_ldap_cacheable_userobj(rlm_rcode_t *p_result, request_t *request, ldap_autz_ctx_t *autz_ctx, char const *attr)
Convert group membership information into attributes.
unlang_action_t rlm_ldap_check_cached(rlm_rcode_t *p_result, rlm_ldap_t const *inst, request_t *request, fr_value_box_t const *check)
Check group membership attributes to see if a user is a member.
unlang_action_t rlm_ldap_cacheable_groupobj(rlm_rcode_t *p_result, request_t *request, ldap_autz_ctx_t *autz_ctx)
Convert group membership information into attributes.
unlang_action_t rlm_ldap_check_groupobj_dynamic(rlm_rcode_t *p_result, request_t *request, ldap_memberof_xlat_ctx_t *xlat_ctx)
Initiate an LDAP search to determine group membership, querying group objects.
unlang_action_t rlm_ldap_check_userobj_dynamic(rlm_rcode_t *p_result, request_t *request, ldap_memberof_xlat_ctx_t *xlat_ctx)
Query the LDAP directory to check if a user object is a member of a group.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
int fr_ldap_map_verify(map_t *map, void *instance)
size_t fr_ldap_uri_unescape_func(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg))
Converts escaped DNs and filter strings into normal.
size_t fr_ldap_util_normalise_dn(char *out, char const *in)
Normalise escape sequences in a DN.
int fr_ldap_map_getvalue(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, void *uctx)
Callback for map_to_request.
size_t fr_ldap_uri_escape_func(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg))
Converts "bad" strings into ones which are safe for LDAP.
int fr_ldap_filter_to_tmpl(TALLOC_CTX *ctx, tmpl_rules_t const *t_rules, char const **sub, size_t sublen, tmpl_t **out))
Combine filters and tokenize to a tmpl.
struct berval ** values
libldap struct containing bv_val (char *) and length bv_len.
fr_ldap_control_t serverctrls[LDAP_MAX_CONTROLS]
Server controls specific to this query.
fr_trunk_request_t * treq
Trunk request this query is associated with.
fr_time_delta_t res_timeout
How long we wait for results.
char const * admin_password
Password used in administrative bind.
fr_ldap_config_t * config
Module instance config.
int count
Index on next free element.
fr_event_timer_t const * ev
Event for timing out the query.
bool fr_ldap_util_is_dn(char const *in, size_t inlen)
Check whether a string looks like a DN.
char * server
Initial server to bind to.
static int8_t fr_ldap_bind_auth_cmp(void const *one, void const *two)
Compare two ldap bind auth structures on msgid.
LDAP * handle
libldap handle.
fr_ldap_thread_trunk_t * fr_thread_ldap_trunk_get(fr_ldap_thread_t *thread, char const *uri, char const *bind_dn, char const *bind_password, request_t *request, fr_ldap_config_t const *config)
Find a thread specific LDAP connection for a specific URI / bind DN.
char const * admin_identity
Identity we bind as when we need to query the LDAP directory.
fr_ldap_result_code_t ret
Result code.
bool freeit
Whether the control should be freed after we've finished using it.
fr_rb_tree_t * trunks
Tree of LDAP trunks used by this thread.
fr_trunk_conf_t * trunk_conf
Module trunk config.
char const * fr_ldap_url_err_to_str(int ldap_url_err)
Translate the error code emitted from ldap_url_parse and friends into something accessible with fr_st...
int fr_ldap_server_url_check(fr_ldap_config_t *handle_config, char const *server, CONF_SECTION const *cs)
Check an LDAP server entry in URL format is valid.
int count
Number of values.
#define LDAP_MAX_ATTRMAP
Maximum number of mappings between LDAP and.
int fr_ldap_box_escape(fr_value_box_t *vb, UNUSED void *uctx)
static int8_t fr_ldap_trunk_cmp(void const *one, void const *two)
Compare two ldap trunk structures on connection URI / DN.
int fr_ldap_server_config_check(fr_ldap_config_t *handle_config, char const *server, CONF_SECTION *cs)
Check an LDAP server config in server:port format is valid.
char * fr_ldap_berval_to_string(TALLOC_CTX *ctx, struct berval const *in)
Convert a berval to a talloced string.
fr_ldap_connection_t * ldap_conn
LDAP connection this query is running on.
fr_ldap_thread_trunk_t * fr_thread_ldap_bind_trunk_get(fr_ldap_thread_t *thread)
Find the thread specific trunk to use for LDAP bind auths.
fr_trunk_conf_t * bind_trunk_conf
Trunk config for bind auth trunk.
fr_ldap_result_code_t
LDAP query result codes.
@ LDAP_RESULT_TIMEOUT
The query timed out.
@ LDAP_RESULT_SUCCESS
Successfully got LDAP results.
@ LDAP_RESULT_NO_RESULT
No results returned.
@ LDAP_RESULT_BAD_DN
The requested DN does not exist.
int fr_ldap_map_expand(TALLOC_CTX *ctx, fr_ldap_map_exp_t *expanded, request_t *request, map_list_t const *maps, char const *generic_attr)
Expand values in an attribute map where needed.
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
#define LDAP_VIRTUAL_DN_ATTR
'Virtual' attribute which maps to the DN of the object.
int fr_ldap_parse_url_extensions(LDAPControl **sss, size_t sss_len, char *extensions[])
Parse a subset (just server side sort for now) of LDAP URL extensions.
LDAPMessage * result
Head of LDAP results list.
fr_event_list_t * el
Thread event list for callbacks / timeouts.
LDAPControl * control
LDAP control.
int fr_ldap_map_do(request_t *request, char const *valuepair_attr, fr_ldap_map_exp_t const *expanded, LDAPMessage *entry)
Convert attribute map into valuepairs.
unlang_action_t fr_ldap_edir_get_password(request_t *request, char const *dn, fr_ldap_thread_trunk_t *ttrunk, fr_dict_attr_t const *password_da)
Initiate retrieval of the universal password from Novell eDirectory.
char const * attrs[LDAP_MAX_ATTRMAP+LDAP_MAP_RESERVED+1]
Reserve some space for access attributes.
fr_trunk_t * trunk
Connection trunk.
fr_ldap_thread_trunk_t * bind_trunk
LDAP trunk used for bind auths.
unlang_action_t fr_ldap_bind_auth_async(request_t *request, fr_ldap_thread_t *thread, char const *bind_dn, char const *password)
Initiate an async LDAP bind for authentication.
TALLOC_CTX * ctx
Context to allocate new attributes in.
fr_rb_tree_t * binds
Tree of outstanding bind auths.
LDAPURLDesc * ldap_url
parsed URL for current query if the source of the query was a URL.
Holds arguments for async bind auth requests.
Connection configuration.
Tracks the state of a libldap connection handle.
Result of expanding the RHS of a set of maps.
Contains a collection of values.
Holds arguments for the async SASL bind operation.
Thread specific structure to manage LDAP trunk connections.
Thread LDAP trunk structure.
#define FR_LDAP_COMMON_CONF(_conf)
LDAP * ldap_global_handle
Hack for OpenLDAP libldap global initialisation.
LDAP * fr_ldap_handle_thread_local(void)
Get a thread local dummy LDAP handle.
global_lib_autoinst_t fr_libldap_global_config
unlang_action_t fr_ldap_trunk_modify(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async modification LDAP query on a trunk connection.
fr_table_num_sorted_t const fr_ldap_tls_require_cert[]
fr_table_num_sorted_t const fr_ldap_dereference[]
fr_ldap_query_t * fr_ldap_search_alloc(TALLOC_CTX *ctx, char const *base_dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Allocate a new search object.
unlang_action_t fr_ldap_trunk_search(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *base_dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async search LDAP query on a trunk connection.
fr_table_num_sorted_t const fr_ldap_scope[]
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert map_t to fr_pair_t (s) and add them to a request_t.
Stores all information relating to an event list.
int map_proc_register(void *mod_inst, char const *name, map_proc_func_t evaluate, map_proc_instantiate_t instantiate, size_t inst_size, fr_value_box_safe_for_t literals_safe_for)
Register a map processor.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
ssize_t xlat_eval(char *out, size_t outlen, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx)
void * env_data
Per call environment data.
void * thread
Thread specific instance data.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
void * thread
Thread instance data.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
Specifies a module method identifier.
module_thread_instance_t * module_rlm_thread_by_data(void const *data)
char const * section_type_value[MOD_COUNT]
module_t common
Common fields presented by all modules.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
static const conf_parser_t config[]
unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret, rlm_ldap_t const *inst, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *dn, int scope, char const *filter, fr_ldap_map_exp_t const *expanded)
Search for and apply an LDAP profile.
#define RDEBUG_ENABLED2()
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
int fr_rb_flatten_inorder(TALLOC_CTX *ctx, void **out[], fr_rb_tree_t *tree)
static int8_t comp(void const *a, void const *b)
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_RCODE(_rcode)
#define RETURN_MODULE_INVALID
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
static const call_env_method_t xlat_memberof_method_env
static int mod_detach(module_detach_ctx_t const *mctx)
Detach from the LDAP server and cleanup internal state.
static int mod_load(void)
static xlat_action_t ldap_profile_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Return whether evaluating the profile was successful.
map_list_t * profile_map
List of maps to apply to the profile.
#define REPEAT_LDAP_MEMBEROF_XLAT_RESULTS
LDAPMod mod_s[LDAP_MAX_ATTRMAP]
static unlang_action_t ldap_memberof_xlat_results(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Run the state machine for the LDAP membership xlat.
static conf_parser_t profile_config[]
fr_dict_attr_t const * attr_nt_password
static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, void *mod_inst, UNUSED void *proc_inst, request_t *request, fr_value_box_list_t *url, map_list_t const *maps)
Perform a search and map the result of the search to server attributes.
static void user_modify_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
Cancel an in progress user modification.
static void ldap_memberof_xlat_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
Cancel an in-progress query for the LDAP group membership xlat.
static xlat_arg_parser_t const ldap_safe_xlat_arg[]
ldap_auth_call_env_t * call_env
static const call_env_method_t authenticate_method_env
static xlat_arg_parser_t const ldap_uri_escape_xlat_arg[]
fr_ldap_result_code_t ret
fr_dict_attr_t const * attr_ldap_userdn
global_lib_autoinst_t const * rlm_ldap_lib[]
static const call_env_method_t authorize_method_env
static unlang_action_t mod_map_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Process the results of an LDAP map query.
static int ldap_update_section_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, char const *section_name1, char const *section_name2, void const *data, call_env_parser_t const *rule)
static xlat_arg_parser_t const ldap_uri_unescape_xlat_arg[]
static const call_env_method_t xlat_profile_method_env
#define CHECK_EXPANDED_SPACE(_expanded)
static int parse_sub_section(module_inst_ctx_t const *mctx, CONF_SECTION *parent, ldap_acct_section_t **config, rlm_components_t comp)
Parse an accounting sub section.
static unlang_action_t user_modify_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Take the retrieved user DN and launch the async modification.
fr_dict_attr_t const * attr_crypt_password
fr_value_box_t user_filter
static fr_dict_t const * dict_freeradius
static int ldap_group_filter_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED char const *section_name1, UNUSED char const *section_name2, void const *data, UNUSED call_env_parser_t const *rule)
static void ldap_query_timeout(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Callback when LDAP query times out.
static int map_ctx_free(ldap_map_ctx_t *map_ctx)
Ensure map context is properly cleared up.
static unlang_action_t mod_authenticate_start(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Perform async lookup of user DN if required for authentication.
LDAPMod * mod_p[LDAP_MAX_ATTRMAP+1]
static conf_parser_t user_config[]
static int ldap_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void *proc_inst, tmpl_t const *src, UNUSED map_list_t const *maps)
static fr_dict_attr_t const * attr_expr_bool_enum
static xlat_action_t ldap_memberof_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Process the results of evaluating LDAP group membership.
static fr_table_num_sorted_t const ldap_uri_scheme_table[]
static xlat_arg_parser_t const ldap_xlat_arg[]
static unlang_action_t mod_authorize_start(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Start LDAP authorization with async lookup of user DN.
static unlang_action_t ldap_memberof_xlat_user_find(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
User object lookup as part of group membership xlat.
static int ldap_uri_part_escape(fr_value_box_t *vb, UNUSED void *uctx)
Escape function for a part of an LDAP URI.
fr_dict_attr_t const * attr_password
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Bootstrap the module.
#define REPEAT_MOD_AUTHORIZE_RESUME
static const conf_parser_t acct_section_config[]
fr_value_box_t user_sasl_proxy
fr_ldap_thread_trunk_t * ttrunk
fr_value_box_t user_sasl_authname
fr_dict_attr_t const * attr_password_with_header
static conf_parser_t group_config[]
static void mod_unload(void)
fr_dict_attr_autoload_t rlm_ldap_dict_attr[]
ssize_t expect_password_offset
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int ldap_xlat_profile_ctx_free(ldap_xlat_profile_ctx_t *to_free)
fr_dict_attr_t const * attr_cleartext_password
tmpl_t const * password_tmpl
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static xlat_action_t ldap_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
Callback when resuming after async ldap query is completed.
fr_value_box_t user_sasl_mech
static unlang_action_t mod_authenticate_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Initiate async LDAP bind to authenticate user.
static unlang_action_t user_modify_start(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Perform async lookup of user DN if required for user modification.
fr_dict_autoload_t rlm_ldap_dict[]
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Initialise thread specific data structure.
static int autz_ctx_free(ldap_autz_ctx_t *autz_ctx)
Ensure authorization context is properly cleared up.
fr_ldap_map_exp_t expanded
static void ldap_xlat_signal(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
Callback for signalling async ldap query.
static xlat_arg_parser_t const ldap_memberof_xlat_arg[]
char * passed[LDAP_MAX_ATTRMAP *2]
fr_value_box_t user_filter
static char * host_uri_canonify(request_t *request, LDAPURLDesc *url_parsed, fr_value_box_t *url_in)
Produce canonical LDAP host URI for finding trunks.
fr_ldap_thread_t * thread
static size_t ldap_uri_scheme_table_len
#define LDAP_URI_SAFE_FOR
This is the common function that actually ends up doing all the URI escaping.
static fr_uri_part_t const ldap_dn_parts[]
static unlang_action_t user_modify_final(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Handle results of user modification.
static unlang_action_t user_modify(rlm_rcode_t *p_result, rlm_ldap_t const *inst, request_t *request, ldap_acct_section_t *section, ldap_usermod_call_env_t *call_env)
Modify user's object in LDAP.
static const conf_parser_t module_config[]
static const call_env_method_t usermod_method_env
#define USER_CALL_ENV_COMMON(_struct)
ldap_usermod_call_env_t * call_env
static unlang_action_t mod_authorize_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Resume function called after each potential yield in LDAP authorization.
static void mod_authorize_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
Clear up when cancelling a mod_authorize call.
fr_value_box_t profile_filter
Filter to use when searching for users.
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
Clean up thread specific data structure.
static int mod_instantiate(module_inst_ctx_t const *mctx)
Instantiate the module.
fr_ldap_map_exp_t expanded
static const call_env_parser_t sasl_call_env[]
fr_value_box_t user_sasl_realm
static fr_uri_part_t const ldap_uri_parts[]
static unlang_action_t mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Holds state of in progress async authentication.
Holds state of in progress LDAP map.
Parameters to allow ldap_update_section_parse to be reused.
Holds state of in progress ldap user modifications.
Call environment used in the profile xlat.
LDAP authorization and authentication module headers.
fr_ldap_map_exp_t expanded
ldap_group_xlat_status_t status
ldap_autz_call_env_t * call_env
struct berval ** profile_values
@ LDAP_ACCESS_SUSPENDED
User account has been suspended.
@ LDAP_ACCESS_ALLOWED
User is allowed to login.
@ LDAP_ACCESS_DISALLOWED
User it not allow to login (disabled)
fr_ldap_thread_trunk_t * ttrunk
fr_value_box_t profile_filter
Filter to use when searching for profiles.
fr_value_box_t user_filter
Filter to use when searching for users.
@ LDAP_AUTZ_DEFAULT_PROFILE
@ LDAP_AUTZ_POST_DEFAULT_PROFILE
ldap_autz_status_t status
fr_value_box_t user_base
Base DN in which to search for users.
ldap_access_state_t access_state
What state a user's account is in.
fr_value_box_t user_base
Base DN in which to search for users.
ldap_xlat_memberof_call_env_t * env_data
unlang_action_t rlm_ldap_find_user_async(TALLOC_CTX *ctx, rlm_ldap_t const *inst, request_t *request, fr_value_box_t *base, fr_value_box_t *filter_box, fr_ldap_thread_trunk_t *ttrunk, char const *attrs[], fr_ldap_query_t **query_out)
Initiate asynchronous retrieval of the DN of a user object.
map_list_t * user_map
Attribute map applied to users and profiles.
void rlm_ldap_check_reply(request_t *request, rlm_ldap_t const *inst, char const *inst_name, bool expect_password, fr_ldap_thread_trunk_t const *ttrunk)
Verify we got a password from the search.
fr_value_box_t const * expect_password
True if the user_map included a mapping between an LDAP attribute and one of our password reference a...
fr_ldap_thread_trunk_t * ttrunk
static char const * rlm_find_user_dn_cached(request_t *request)
char const * reference
Configuration reference string.
CONF_SECTION * cs
Section configuration.
fr_value_box_t user_filter
Filter to use when searching for users.
fr_value_box_t default_profile
If this is set, we will search for a profile object with this name, and map any attributes it contain...
dl_module_inst_t const * dlinst
ldap_access_state_t rlm_ldap_check_access(rlm_ldap_t const *inst, request_t *request, LDAPMessage *entry)
Check for presence of access attribute in result.
Call environment used in LDAP authorization.
Holds state of in progress async authorization.
Holds state of in progress group membership check xlat.
Call environment used in group membership xlat.
static int instantiate(module_inst_ctx_t const *mctx)
unlang_action_t fr_ldap_sasl_bind_auth_async(request_t *request, fr_ldap_thread_t *thread, char const *mechs, char const *identity, char const *password, char const *proxy, char const *realm)
Initiate an async SASL LDAP bind for authentication.
int fr_sbuff_trim_talloc(fr_sbuff_t *sbuff, size_t len)
Trim a talloced sbuff to the minimum length required to represent the contained string.
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define fr_sbuff_buff(_sbuff_or_marker)
Talloc sbuff extension structure.
#define MODULE_NAME_TERMINATOR
static tmpl_attr_t const * tmpl_attr_tail(tmpl_t const *vpt)
Return the last attribute reference.
Optional arguments passed to vp_tmpl functions.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
An element in a list of nested attribute references.
fr_dict_attr_t const *_CONST da
Resolved dictionary attribute.
Stores an attribute, a value and various bits of other data.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
@ TMPL_ESCAPE_PRE_CONCAT
Pre-concatenation escaping is useful for DSLs where elements of the expansion are static,...
fr_table_num_ordered_t const fr_tokens_table[]
conf_parser_t const fr_trunk_config[]
Config parser definitions to populate a fr_trunk_conf_t.
void fr_trunk_request_signal_cancel(fr_trunk_request_t *treq)
Cancel a trunk request.
fr_trunk_enqueue_t fr_trunk_request_enqueue(fr_trunk_request_t **treq_out, fr_trunk_t *trunk, request_t *request, void *preq, void *rctx)
Enqueue a request that needs data written to the trunk.
@ FR_TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
@ FR_TRUNK_ENQUEUE_OK
Operation was successful.
static fr_event_list_t * el
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
bool required
Argument must be present, and non-empty.
xlat_action_t xlat_transparent(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_YIELD
An xlat function pushed a resume frame onto the stack.
@ XLAT_ACTION_PUSH_UNLANG
An xlat function pushed an unlang frame onto the unlang stack.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
ssize_t xlat_aeval(TALLOC_CTX *ctx, char **out, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx))
Definition for a single argument consumend by an xlat function.
int fr_uri_escape_list(fr_value_box_list_t *uri, fr_uri_part_t const *uri_parts, void *uctx)
Parse a list of value boxes representing a URI.
int fr_uri_has_scheme(fr_value_box_list_t *uri, fr_table_num_sorted_t const *schemes, size_t schemes_len, int def)
Searches for a matching scheme in the table of schemes, using a list of value boxes representing the ...
#define XLAT_URI_PART_TERMINATOR
char const * name
Name of this part of the URI.
Definition for a single part of a URI.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.
int fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
int fr_value_box_bstrdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a talloced buffer containing a nul terminated string to a box, but don't copy it.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_strvalue_len(_val, _len)
#define fr_value_box_is_safe_for(_box, _safe_for)
#define FR_MAX_STRING_LEN
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
void * rctx
Resume context.
module_ctx_t const * mctx
Synthesised module calling ctx.
void * env_data
Expanded call env data.
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.
int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the argument of an xlat.
void xlat_func_unregister(char const *name)
Unregister an xlat function.
xlat_t * xlat_func_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function for a module.
#define xlat_func_safe_for_set(_xlat, _escaped)
Set the escaped values for output boxes.