30 RCSID(
"$Id: 3d29cb1cb5d8830472e60b87b8c4980dc2032281 $")
32 #include <freeradius-devel/rad_assert.h>
39 #include <freeradius-devel/map_proc.h>
45 {
"sub", LDAP_SCOPE_SUB },
46 {
"one", LDAP_SCOPE_ONE },
47 {
"base", LDAP_SCOPE_BASE },
48 #ifdef LDAP_SCOPE_CHILDREN
49 {
"children", LDAP_SCOPE_CHILDREN },
54 #ifdef LDAP_OPT_X_TLS_NEVER
56 {
"never", LDAP_OPT_X_TLS_NEVER },
57 {
"demand", LDAP_OPT_X_TLS_DEMAND },
58 {
"allow", LDAP_OPT_X_TLS_ALLOW },
59 {
"try", LDAP_OPT_X_TLS_TRY },
60 {
"hard", LDAP_OPT_X_TLS_HARD },
67 {
"never", LDAP_DEREF_NEVER },
68 {
"searching", LDAP_DEREF_SEARCHING },
69 {
"finding", LDAP_DEREF_FINDING },
70 {
"always", LDAP_DEREF_ALWAYS },
191 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
195 #ifdef LDAP_OPT_NETWORK_TIMEOUT
206 #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
209 #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
212 #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
258 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
259 REQUEST *request,
char const *fmt)
265 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
266 REQUEST *request,
char const *fmt)
275 void const *mod_inst,
UNUSED void const *xlat_inst,
276 REQUEST *request,
char const *fmt)
282 LDAPURLDesc *ldap_url;
283 LDAPMessage *result = NULL;
284 LDAPMessage *entry = NULL;
286 struct berval **values;
296 if (!ldap_is_ldap_url(url)) {
297 REDEBUG(
"String passed does not look like an LDAP URL");
301 if (ldap_url_parse(url, &ldap_url)){
302 REDEBUG(
"Parsing LDAP URL failed");
309 if (!ldap_url->lud_attrs || !ldap_url->lud_attrs[0] ||
310 !*ldap_url->lud_attrs[0] ||
311 (strcmp(ldap_url->lud_attrs[0],
"*") == 0) ||
312 ldap_url->lud_attrs[1]) {
313 REDEBUG(
"Bad attributes list in LDAP URL. URL must specify exactly one attribute to retrieve");
319 if (!conn)
goto free_urldesc;
321 memcpy(&attrs, &ldap_url->lud_attrs,
sizeof(attrs));
323 status =
rlm_ldap_search(&result, inst, request, &conn, ldap_url->lud_dn, ldap_url->lud_scope,
324 ldap_url->lud_filter, attrs, NULL, NULL);
336 entry = ldap_first_entry(conn->
handle, result);
338 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
339 REDEBUG(
"Failed retrieving entry: %s", ldap_err2string(ldap_errno));
344 values = ldap_get_values_len(conn->
handle, entry, ldap_url->lud_attrs[0]);
346 RDEBUG(
"No \"%s\" attributes found in specified object", ldap_url->lud_attrs[0]);
350 if (values[0]->bv_len >= outlen)
goto free_values;
352 memcpy(*out, values[0]->bv_val, values[0]->bv_len + 1);
353 len = values[0]->bv_len;
356 ldap_value_free_len(values);
358 ldap_msgfree(result);
362 ldap_free_urldesc(ldap_url);
382 char const *url,
vp_map_t const *maps)
388 LDAPURLDesc *ldap_url;
390 LDAPMessage *result = NULL;
391 LDAPMessage *entry = NULL;
398 if (!ldap_is_ldap_url(url)) {
399 REDEBUG(
"Map query string does not look like a valid LDAP URI");
403 if (ldap_url_parse(url, &ldap_url)){
404 REDEBUG(
"Parsing LDAP URL failed");
417 if (!conn)
goto free_expanded;
419 status =
rlm_ldap_search(&result, inst, request, &conn, ldap_url->lud_dn, ldap_url->lud_scope,
420 ldap_url->lud_filter, expanded.
attrs, NULL, NULL);
437 for (entry = ldap_first_entry(conn->
handle, result);
439 entry = ldap_next_entry(conn->
handle, entry)) {
444 dn = ldap_get_dn(conn->
handle, entry);
445 RDEBUG2(
"Processing \"%s\"", dn);
449 for (map = maps, i = 0;
451 map = map->
next, i++) {
464 struct berval *values[2] = { &value, NULL };
466 if (!dn) dn = ldap_get_dn(conn->
handle, entry);
468 value.bv_len = strlen(dn);
482 RDEBUG3(
"Attribute \"%s\" not found in LDAP object", expanded.
attrs[i]);
489 ldap_value_free_len(attr.
values);
501 ldap_msgfree(result);
505 talloc_free(expanded.
ctx);
507 ldap_free_urldesc(ldap_url);
540 RDEBUG(
"Searching for user in group \"%s\"", check->vp_strvalue);
542 if (check->vp_length == 0) {
543 REDEBUG(
"Cannot do comparison (group name is empty)");
550 check_is_dn =
rlm_ldap_is_dn(check->vp_strvalue, check->vp_length);
554 MEM(norm = talloc_memdup(check, check->vp_strvalue, talloc_array_length(check->vp_strvalue)));
631 RDEBUG(
"User is not a member of \"%s\"", check->vp_strvalue);
658 #ifdef HAVE_LDAP_UNBIND_EXT_S
659 ldap_unbind_ext_s(inst->
handle, NULL, NULL);
661 ldap_unbind_s(inst->
handle);
665 #ifdef HAVE_LDAP_CREATE_SORT_CONTROL
693 DEBUG2(
"rlm_ldap (%s): Couldn't find configuration for %s, will return NOOP for calls "
694 "from this section", inst->
name, name);
701 LDAP_ERR(
"Failed parsing configuration for section %s", name);
725 char const *group_attribute;
733 snprintf(buffer,
sizeof(buffer),
"%s-LDAP-Group", inst->
name);
734 group_attribute = buffer;
736 group_attribute =
"LDAP-Group";
753 memset(&flags, 0,
sizeof(flags));
789 static bool version_done;
800 if (!options || !
cf_pair_find(options,
"chase_referrals")) {
810 #ifdef HAVE_LDAP_INITIALIZE
811 ldap_initialize(&inst->
handle,
"");
813 inst->
handle = ldap_init(
"", 0);
820 static LDAPAPIInfo info = { .ldapai_info_version = LDAP_API_INFO_VERSION };
825 ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
826 if (ldap_errno == LDAP_OPT_SUCCESS) {
834 if (strcasestr(info.ldapai_vendor_name, LDAP_VENDOR_NAME) == NULL) {
835 WARN(
"rlm_ldap: libldap vendor changed since the server was built");
836 WARN(
"rlm_ldap: linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
839 if (info.ldapai_vendor_version < LDAP_VENDOR_VERSION) {
840 WARN(
"rlm_ldap: libldap older than the version the server was built against");
841 WARN(
"rlm_ldap: linked: %i, built: %i",
842 info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
845 INFO(
"rlm_ldap: libldap vendor: %s, version: %i", info.ldapai_vendor_name,
846 info.ldapai_vendor_version);
848 ldap_memfree(info.ldapai_vendor_name);
849 ldap_memfree(info.ldapai_extensions);
851 DEBUG(
"rlm_ldap: Falling back to build time libldap version info. Query for LDAP_OPT_API_INFO "
852 "returned: %i", ldap_errno);
853 INFO(
"rlm_ldap: libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME,
873 cf_log_err_cs(conf,
"Configuration item 'group.name_attribute' must be set if cacheable "
874 "group names are enabled");
887 cf_log_err_cs(conf,
"Configuration item 'server' must have a value");
894 cf_log_err_cs(conf,
"Configuration item 'user.sasl.mech' not supported. "
895 "Linked libldap does not provide ldap_sasl_bind function");
900 cf_log_err_cs(conf,
"Configuration item 'sasl.mech' not supported. "
901 "Linked libldap does not provide ldap_sasl_interactive_bind function");
906 #ifndef HAVE_LDAP_CREATE_SORT_CONTROL
908 cf_log_err_cs(conf,
"Configuration item 'sort_by' not supported. "
909 "Linked libldap does not provide ldap_create_sort_control function");
914 #ifndef HAVE_LDAP_URL_PARSE
916 cf_log_err_cs(conf,
"Configuration item 'use_referral_credentials' not supported. "
917 "Linked libldap does not support URL parsing");
939 cf_log_err_cs(conf,
"Configuration item 'server' must have a value");
951 if (p == value)
break;
958 while (isspace((
int) *p)) p++;
959 if (p == q)
continue;
961 buff = talloc_array(inst,
char, (q - p) + 1);
962 strlcpy(buff, p, talloc_array_length(buff));
966 WARN(
"Listing multiple LDAP servers in the 'server' configuration item "
967 "is deprecated and will be removed in a future release. "
968 "Use multiple 'server' configuration items instead");
969 WARN(
"- server = '%s'", value);
971 WARN(
"+ server = '%s'", buff);
1011 #ifdef LDAP_CAN_PARSE_URLS
1017 if (ldap_is_ldap_url(value)) {
1018 LDAPURLDesc *ldap_url;
1019 bool set_port_maybe =
true;
1020 int default_port = LDAP_PORT;
1023 if (ldap_url_parse(value, &ldap_url)){
1024 cf_log_err_cs(conf,
"Parsing LDAP URL \"%s\" failed", value);
1026 ldap_free_urldesc(ldap_url);
1030 if (ldap_url->lud_dn && (ldap_url->lud_dn[0] !=
'\0')) {
1031 cf_log_err_cs(conf,
"Base DN cannot be specified via server URL");
1032 goto ldap_url_error;
1035 if (ldap_url->lud_attrs && ldap_url->lud_attrs[0]) {
1036 cf_log_err_cs(conf,
"Attribute list cannot be specified via server URL");
1037 goto ldap_url_error;
1043 if (ldap_url->lud_scope != LDAP_SCOPE_BASE) {
1044 cf_log_err_cs(conf,
"Scope cannot be specified via server URL");
1045 goto ldap_url_error;
1047 ldap_url->lud_scope = -1;
1054 if ((p = strchr(value,
']')) && (p[1] ==
':')) {
1055 set_port_maybe =
false;
1056 }
else if ((p = strchr(value,
':')) && (p = strchr(p + 1,
':'))) {
1057 set_port_maybe =
false;
1062 # ifdef HAVE_LDAP_INITIALIZE
1069 if (ldap_url->lud_scheme) {
1070 if (strcmp(ldap_url->lud_scheme,
"ldaps") == 0) {
1073 "with 'start_tls'");
1074 goto ldap_url_error;
1076 default_port = LDAPS_PORT;
1078 }
else if (strcmp(ldap_url->lud_scheme,
"ldapi") == 0) {
1079 set_port_maybe =
false;
1083 if (set_port_maybe) {
1087 ldap_url->lud_port = inst->
port;
1094 if (!ldap_url->lud_port) ldap_url->lud_port = default_port;
1097 url = ldap_url_desc2str(ldap_url);
1100 goto ldap_url_error;
1102 inst->
server = talloc_asprintf_append(inst->
server,
"%s ", url);
1109 if (ldap_url->lud_scheme &&
1110 ((strcmp(ldap_url->lud_scheme,
"ldaps") == 0) ||
1111 (strcmp(ldap_url->lud_scheme,
"ldapi") == 0) ||
1112 (strcmp(ldap_url->lud_scheme,
"cldap") == 0))) {
1113 cf_log_err_cs(conf,
"%s is not supported by linked libldap",
1114 ldap_url->lud_scheme);
1123 if (set_port_maybe) {
1124 ldap_url->lud_port = inst->
port;
1125 if (!ldap_url->lud_port) ldap_url->lud_port = default_port;
1128 inst->
server = talloc_asprintf_append(inst->
server,
"%s:%i ",
1129 ldap_url->lud_host ? ldap_url->lud_host :
"localhost",
1130 ldap_url->lud_port);
1137 ldap_free_urldesc(ldap_url);
1149 #ifdef HAVE_LDAP_INITIALIZE
1161 if (strchr(value,
'/')) {
1163 #ifdef LDAP_CAN_PARSE_URLS
1164 cf_log_err_cp(cp,
"Invalid server value, must be in format <server>[:<port>] or "
1165 "an ldap URI (ldap|cldap|ldaps|ldapi)://<server>:<port>");
1167 cf_log_err_cp(cp,
"Invalid server value, must be in format <server>[:<port>]");
1172 p = strrchr(value,
':');
1174 port = (int)strtol((p + 1), &q, 10);
1175 if ((p == value) || ((p + 1) == q) || (*q !=
'\0'))
goto bad_server_fmt;
1178 len = strlen(value);
1180 if (port == 0) port = LDAP_PORT;
1182 inst->
server = talloc_asprintf_append(inst->
server,
"ldap://%.*s:%i ", (
int) len, value, port);
1188 inst->
server = talloc_asprintf_append(inst->
server,
"%s ", value);
1196 #ifdef LDAP_OPT_X_TLS_NEVER
1201 inst->
tls_mode = LDAP_OPT_X_TLS_HARD;
1213 cf_log_err_cs(conf,
"Invalid 'dereference' value \"%s\", expected 'never', 'searching', "
1219 #if LDAP_SET_REBIND_PROC_ARGS != 3
1224 if (inst->
rebind ==
true) {
1225 cf_log_err_cs(conf,
"Cannot use 'rebind' configuration item as this version of libldap "
1226 "does not support the API that we need");
1237 cf_log_err_cs(conf,
"Invalid 'user.scope' value \"%s\", expected 'sub', 'one'"
1238 #ifdef LDAP_SCOPE_CHILDREN
1239 ", 'base' or 'children'"
1249 cf_log_err_cs(conf,
"Invalid 'group.scope' value \"%s\", expected 'sub', 'one'"
1250 #ifdef LDAP_SCOPE_CHILDREN
1251 ", 'base' or 'children'"
1261 cf_log_err_cs(conf,
"Invalid 'client.scope' value \"%s\", expected 'sub', 'one'"
1262 #ifdef LDAP_SCOPE_CHILDREN
1263 ", 'base' or 'children'"
1271 #ifdef HAVE_LDAP_CREATE_SORT_CONTROL
1282 ret = ldap_create_sort_keylist(&keys, p);
1283 if (ret != LDAP_SUCCESS) {
1284 cf_log_err_cs(conf,
"Invalid user.sort_by value \"%s\": %s",
1294 ldap_free_sort_keylist(keys);
1295 if (ret != LDAP_SUCCESS) {
1296 LDAP_ERR(
"Failed creating server sort control: %s", ldap_err2string(ret));
1303 #ifdef LDAP_OPT_X_TLS_NEVER
1309 cf_log_err_cs(conf,
"Invalid 'tls.require_cert' value \"%s\", expected 'never', "
1314 cf_log_err_cs(conf,
"Modifying 'tls.require_cert' is not supported by current "
1315 "version of libldap. Please upgrade or substitute current libldap and "
1316 "rebuild this module");
1336 if (!inst->
pool)
goto error;
1346 cf_log_err_cs(conf,
"Told to load clients but no client section found");
1352 cf_log_err_cs(cs,
"Told to load clients but no attribute section found");
1390 if (!request->username) {
1391 REDEBUG(
"Attribute \"User-Name\" is required for authentication");
1396 if (!request->password ||
1397 (request->password->da->attr != PW_USER_PASSWORD)) {
1398 RWDEBUG(
"You have set \"Auth-Type := LDAP\" somewhere");
1399 RWDEBUG(
"*********************************************");
1400 RWDEBUG(
"* THAT CONFIGURATION IS WRONG. DELETE IT. ");
1401 RWDEBUG(
"* YOU ARE PREVENTING THE SERVER FROM WORKING");
1402 RWDEBUG(
"*********************************************");
1404 REDEBUG(
"Attribute \"User-Password\" is required for authentication");
1409 if (request->password->vp_length == 0) {
1410 REDEBUG(
"Empty password supplied");
1422 memset(&sasl, 0,
sizeof(sasl));
1424 if (
tmpl_expand(&sasl.
mech, sasl_mech_buff,
sizeof(sasl_mech_buff), request,
1432 if (
tmpl_expand(&sasl.
proxy, sasl_proxy_buff,
sizeof(sasl_proxy_buff), request,
1441 if (
tmpl_expand(&sasl.
realm, sasl_realm_buff,
sizeof(sasl_realm_buff), request,
1450 RDEBUG(
"Login attempt by \"%s\"", request->username->vp_strvalue);
1462 status =
rlm_ldap_bind(inst, request, &conn, dn, request->password->vp_strvalue,
1467 RDEBUG(
"Bind as user \"%s\" was successful", dn);
1515 LDAPMessage *result = NULL, *entry = NULL;
1517 LDAP *handle = (*pconn)->handle;
1525 if (
tmpl_expand(&filter, filter_buff,
sizeof(filter_buff), request,
1527 REDEBUG(
"Failed creating profile filter");
1533 LDAP_SCOPE_BASE, filter, expanded->
attrs, NULL, NULL);
1540 RDEBUG(
"Profile object \"%s\" not found", dn);
1550 entry = ldap_first_entry(handle, result);
1552 ldap_get_option(handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
1553 REDEBUG(
"Failed retrieving entry: %s", ldap_err2string(ldap_errno));
1560 RDEBUG(
"Processing profile attributes");
1564 ldap_msgfree(result);
1577 struct berval **values;
1580 LDAPMessage *result, *entry;
1581 char const *dn = NULL;
1621 entry = ldap_first_entry(conn->
handle, result);
1623 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
1624 REDEBUG(
"Failed retrieving entry: %s", ldap_err2string(ldap_errno));
1670 size_t pass_size =
sizeof(password);
1688 vp->vp_length = pass_size;
1691 RDEBUG3(
"Added eDirectory password. control:%s += '%s'", vp->
da->
name, vp->vp_strvalue);
1693 RDEBUG2(
"Added eDirectory password");
1696 if (inst->edir_autz) {
1697 RDEBUG2(
"Binding as user for eDirectory authorization checks");
1702 status =
rlm_ldap_bind(inst, request, &conn, dn, vp->vp_strvalue, NULL,
true, NULL, NULL);
1706 RDEBUG(
"Bind as user '%s' was successful", dn);
1739 char const *profile;
1740 char profile_buff[1024];
1742 if (
tmpl_expand(&profile, profile_buff,
sizeof(profile_buff),
1744 REDEBUG(
"Failed creating default profile string");
1772 if (values != NULL) {
1773 for (i = 0; values[i] != NULL; i++) {
1781 ldap_value_free_len(values);
1787 ldap_value_free_len(values);
1792 RDEBUG(
"Processing user attributes");
1798 talloc_free(expanded.
ctx);
1799 if (result) ldap_msgfree(result);
1822 LDAPMod **modify = mod_p;
1825 int i, total = 0, last_pass = 0;
1855 if (
radius_xlat(p, (
sizeof(path) - (p - path)) - 1, request, section->
reference, NULL, NULL) < 0) {
1865 REDEBUG(
"Reference must resolve to a section");
1872 REDEBUG(
"Section must contain 'update' subsection");
1881 bool do_xlat =
false;
1884 REDEBUG(
"Modify map size exceeded");
1890 REDEBUG(
"Entry is not in \"ldap-attribute = value\" format");
1903 if (!value || (*value ==
'\0')) {
1904 RDEBUG(
"Empty value string, skipping attribute \"%s\"", attr);
1925 passed[last_pass] = NULL;
1926 }
else if (do_xlat) {
1929 if (
radius_axlat(&exp, request, value, NULL, NULL) <= 0) {
1930 RDEBUG(
"Skipping attribute \"%s\"", attr);
1937 expanded[last_exp++] = exp;
1938 passed[last_pass] = exp;
1943 memcpy(&(passed[last_pass]), &value,
sizeof(passed[last_pass]));
1946 passed[last_pass + 1] = NULL;
1948 mod_s[total].mod_values = &(passed[last_pass]);
1958 mod_s[total].mod_op = LDAP_MOD_ADD;
1962 mod_s[total].mod_op = LDAP_MOD_REPLACE;
1967 mod_s[total].mod_op = LDAP_MOD_DELETE;
1970 #ifdef LDAP_MOD_INCREMENT
1972 mod_s[total].mod_op = LDAP_MOD_INCREMENT;
1976 REDEBUG(
"Operator '%s' is not supported for LDAP modify operations",
1986 memcpy(&(mod_s[total].mod_type), &attr,
sizeof(mod_s[total].mod_type));
1988 mod_p[total] = &(mod_s[total]);
1997 mod_p[total] = NULL;
2008 status =
rlm_ldap_modify(inst, request, &conn, dn, modify, NULL, NULL);
2028 for (i = 0; i < last_exp; i++) {
2029 talloc_free(expanded[i]);
2067 .config = module_config,
static int parse_sub_section(rlm_ldap_t *inst, CONF_SECTION *parent, ldap_acct_section_t **config, rlm_components_t comp)
Parse an accounting sub section.
ssize_t ssize_t ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
static CONF_PARSER option_config[]
char const * cache_attribute
Sets the attribute we use when creating and retrieving cached group memberships.
#define PW_TYPE_FILE_INPUT
File matching value must exist, and must be readable.
ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request, vp_tmpl_t const *vpt, xlat_escape_t escape, void *escape_ctx)
Expand a vp_tmpl_t to a string writing the result to a buffer.
Tracks the state of a libldap connection handle.
ldap_rcode_t rlm_ldap_modify(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
Modify something in the LDAP directory.
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair)
Return the value (rhs) type.
Operation was successfull.
#define RINDENT()
Indent R* messages by one level.
int int map_to_request(REQUEST *request, vp_map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert vp_map_t to VALUE_PAIR (s) and add them to a REQUEST.
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
FR_NAME_NUMBER const ldap_scope[]
#define LDAP_VIRTUAL_DN_ATTR
'Virtual' attribute which maps to the DN of the object.
The module is OK, continue.
static int mod_instantiate(CONF_SECTION *conf, void *instance)
Instantiate the module.
char const * userobj_access_attr
Attribute to check to see if the user should be locked out.
static rlm_rcode_t mod_post_auth(void *instance, REQUEST *request) CC_HINT(nonnull)
Metadata exported by the module.
static CONF_PARSER sasl_mech_static[]
#define RDEBUG_ENABLED2
True if request debug level 1-2 messages are enabled.
fr_connection_pool_t * pool
Connection pool instance.
vp_tmpl_t * groupobj_base_dn
DN to search for users under.
fr_dict_attr_t const * group_da
The DA associated with this specific instance of the.
7 methods index for postauth section.
CONF_ITEM * cf_pair_to_item(CONF_PAIR const *cp)
Cast a CONF_PAIR to a CONF_ITEM.
static int mod_bootstrap(CONF_SECTION *conf, void *instance)
Bootstrap the module.
VALUE_PAIR * radius_pair_create(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor)
Create a VALUE_PAIR and add it to a list of VALUE_PAIR s.
static ssize_t ldap_unescape_xlat(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
int groupobj_scope
Search scope.
char const * rlm_ldap_find_user(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *attrs[], bool force, LDAPMessage **result, rlm_rcode_t *rcode)
Retrieve the DN of a user object.
bool start_tls
Send the Start TLS message to the LDAP directory to start encrypted communications using the standard...
bool use_referral_credentials
If true use credentials from the referral URL.
#define LDAP_VENDOR_VERSION_PATCH
char const * group_attribute
Sets the attribute we use when comparing group group memberships.
vp_tmpl_t * proxy
Identity to proxy.
#define CONF_PARSER_TERMINATOR
bool chase_referrals_unset
If true, use the OpenLDAP defaults for chase_referrals.
const FR_NAME_NUMBER fr_tokens_table[]
char * server
Initial server to bind to.
ldap_acct_section_t * accounting
Modify mappings for accounting.
void void void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt,...) CC_HINT(format(printf
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, PW_TYPE type, fr_dict_attr_flags_t flags)
Add an attribute to the dictionary.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Values of the encryption flags.
static ssize_t ldap_xlat(char **out, size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Expand an LDAP URL into a query, and return a string result from that query.
static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, REQUEST *request, char const *url, vp_map_t const *maps)
Perform a search and map the result of the search to server attributes.
int map_proc_register(void *mod_inst, char const *name, map_proc_func_t evaluate, xlat_escape_t escape, map_proc_instantiate_t instantiate, size_t inst_size)
Register a map processor.
#define PW_TYPE_SECRET
Only print value if debug level >= 3.
vp_tmpl_t * realm
Kerberos realm.
bool cacheable_group_name
If true the server will determine complete set of group memberships for the current user object...
The module considers the request invalid.
int userobj_scope
Search scope.
bool cacheable_group_dn
If true the server will determine complete set of group memberships for the current user object...
#define XLAT_DEFAULT_BUF_LEN
ldap_rcode_t
Codes returned by rlm_ldap internal functions.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_SECTION.
char const * profile_attr
Attribute that identifies profiles to apply.
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
#define LDAP_MAX_FILTER_STR_LEN
Maximum length of an xlat expanded filter.
#define PW_TYPE_SUBSECTION
size_t rlm_ldap_normalise_dn(char *out, char const *in)
Normalise escape sequences in a DN.
Defines a CONF_PAIR to C data type mapping.
void void void void void void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
char const * clientobj_scope_str
Scope (sub, one, base).
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
char const * cf_pair_value(CONF_PAIR const *pair)
struct vp_map * next
The next valuepair map.
rlm_rcode_t rlm_ldap_check_userobj_dynamic(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, VALUE_PAIR *check)
Query the LDAP directory to check if a user object is a member of a group.
static const CONF_PARSER acct_section_config[]
char const * reference
Configuration reference string.
Operation was not permitted, either current user was locked out in the case of binds, or has insufficient access.
int dereference
libldap value specifying dereferencing behaviour.
static CONF_PARSER group_config[]
char const * groupobj_scope_str
Scope (sub, one, base).
void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
Reparent an allocated char buffer to a VALUE_PAIR.
int map_afrom_cs(vp_map_t **out, CONF_SECTION *cs, pair_lists_t dst_list_def, pair_lists_t src_list_def, map_validate_t validate, void *ctx, unsigned int max) CC_HINT(nonnull(1
Reject the request (user is locked out).
char const * userobj_membership_attr
Attribute that describes groups the user is a member of.
char const * valuepair_attr
Generic dynamic mapping attribute, contains a RADIUS attribute and value.
int fr_str2int(FR_NAME_NUMBER const *table, char const *name, int def)
rlm_rcode_t rlm_ldap_cacheable_userobj(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, LDAPMessage *entry, char const *attr)
Convert group membership information into attributes.
fr_connection_pool_t * module_connection_pool_init(CONF_SECTION *module, void *opaque, fr_connection_create_t c, fr_connection_alive_t a, char const *prefix)
Initialise a module specific connection pool.
int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value)
Replace pair in a given section with a new pair, of the given value.
#define LDAP_MAX_DN_STR_LEN
Maximum length of an xlat expanded DN.
char const * groupobj_name_attr
The name of the group.
Result of expanding the RHS of a set of maps.
char const * cf_pair_attr(CONF_PAIR const *pair)
static int comp(void const *a, void const *b)
void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
Copy data into an "string" data type.
bool cf_item_is_section(CONF_ITEM const *item)
static void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
Create a new memcached handle.
#define LDAP_ERR(fmt,...)
static ssize_t ldap_escape_xlat(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
static CONF_PARSER profile_config[]
fr_dict_attr_t const * cache_da
The DA associated with this specific instance of the.
bool rebound
Whether the connection has been rebound to something other than the admin user.
void rlm_ldap_check_reply(rlm_ldap_t const *inst, REQUEST *request)
Verify we got a password from the search.
#define PW_TYPE_XLAT
string will be dynamically expanded.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_PAIR.
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Immediately reject the request.
Attributes in incoming or internally proxied request.
int count
Number of values.
bool rebind
Controls whether we set an ldad_rebind_proc function and so determines if we can bind to other server...
3 methods index for accounting section.
ldap_rcode_t rlm_ldap_bind(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, char const *password, ldap_sasl *sasl, bool retry, LDAPControl **serverctrls, LDAPControl **clientctrls)
Bind to the LDAP directory as a user.
const section_type_value_t section_type_value[]
Mappings between section names, typenames and control attributes.
char const * groupobj_membership_filter
Filter to only retrieve groups which contain the user as a member.
Stores an attribute, a value and various bits of other data.
uint16_t port
Port to use when binding to the server.
ldap_sasl_dynamic user_sasl
SASL parameters used when binding as the user.
Contains a collection of values.
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
0 methods index for authenticate section.
CONF_SECTION * cs
Main configuration section for this instance.
CONF_PAIR * cf_pair_find_next(CONF_SECTION const *, CONF_PAIR const *, char const *name)
Find a pair with a name matching attr, after specified pair.
bool cf_item_is_pair(CONF_ITEM const *item)
ldap_rcode_t rlm_ldap_search(LDAPMessage **result, rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Search for something in the LDAP directory.
#define REXDENT()
Exdent (unindent) R* messages by one level.
static const CONF_PARSER module_config[]
Configuration AVP similar to a VALUE_PAIR.
char const * proxy
Identity to proxy.
char const * name
Instance name.
#define FR_CONF_DEPRECATED(_n, _t, _p, _f)
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
int tls_require_cert
OpenLDAP constant representing the require cert string.
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
char const * fr_strerror(void)
Get the last library error.
static CONF_PARSER sasl_mech_dynamic[]
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
int count
Index on next free element.
vp_map_t * user_map
Attribute map applied to users and profiles.
static int mod_conn_get(void **handle, UNUSED rlm_cache_config_t const *config, void *driver_inst, UNUSED REQUEST *request)
Get a memcached handle.
static CONF_PARSER tls_config[]
rlm_ldap_t * inst
rlm_ldap configuration.
LDAP * handle
Hack for OpenLDAP libldap global initialisation.
char const * cf_section_name1(CONF_SECTION const *cs)
CONF_PAIR * cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value, FR_TOKEN op, FR_TOKEN lhs_type, FR_TOKEN rhs_type)
Allocate a CONF_PAIR.
#define PW_TYPE_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
rlm_rcode_t rlm_ldap_cacheable_groupobj(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn)
Convert group membership information into attributes.
Module succeeded without doing anything.
CONF_SECTION * cs
Section configuration.
char name[1]
Attribute name.
struct ldap_instance rlm_ldap_t
#define LDAP_MAX_ATTRMAP
Maximum number of mappings between LDAP and.
uint64_t magic
Used to validate module struct.
Module failed, don't reply.
int rlm_ldap_map_expand(rlm_ldap_map_exp_t *expanded, REQUEST *request, vp_map_t const *maps)
Expand values in an attribute map where needed.
int clientobj_scope
Search scope.
#define FR_CONF_OFFSET(_n, _t, _s, _f)
FR_NAME_NUMBER const ldap_tls_require_cert[]
int rlm_ldap_client_load(rlm_ldap_t const *inst, CONF_SECTION *tmpl, CONF_SECTION *map)
Load clients from LDAP on server start.
rlm_rcode_t rlm_ldap_check_cached(rlm_ldap_t const *inst, REQUEST *request, VALUE_PAIR *check)
Check group membership attributes to see if a user is a member.
struct berval ** values
libldap struct containing bv_val (char *) and length bv_len.
char const * edir_errstr(int code)
int paircompare_register_byname(char const *name, fr_dict_attr_t const *from, bool first_only, RAD_COMPARE_FUNC func, void *instance)
Register a function as compare function.
Specified an invalid object in a bind or search DN.
static void mod_conn_release(UNUSED rlm_cache_config_t const *config, void *driver_inst, UNUSED REQUEST *request, rlm_cache_handle_t *handle)
Release a memcached handle.
int rlm_ldap_map_getvalue(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx)
Callback for map_to_request.
enum rlm_components rlm_components_t
The different section components of the server.
static rlm_rcode_t mod_accounting(void *instance, REQUEST *request) CC_HINT(nonnull)
static rlm_rcode_t rlm_ldap_map_profile(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, rlm_ldap_map_exp_t const *expanded)
Search for and apply an LDAP profile.
static int rlm_ldap_groupcmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *thing, VALUE_PAIR *check, UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
Perform LDAP-Group comparison checking.
Attributes to send in the response.
int nmasldap_get_password(LDAP *ld, char const *dn, char *password, size_t *passlen)
Attempt to retrieve the universal password from Novell eDirectory.
rlm_rcode_t rlm_ldap_check_access(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t const *conn, LDAPMessage *entry)
Check for presence of access attribute in result.
size_t rlm_ldap_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Converts "bad" strings into ones which are safe for LDAP.
char const * tls_require_cert_str
Sets requirements for validating the certificate the server presents.
int rlm_ldap_map_do(const rlm_ldap_t *inst, REQUEST *request, LDAP *handle, rlm_ldap_map_exp_t const *expanded, LDAPMessage *entry)
Convert attribute map into valuepairs.
char const * attrs[LDAP_MAX_ATTRMAP+LDAP_MAP_RESERVED+1]
Reserve some space for access attributes.
CONF_ITEM * cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item)
Return the next item after a CONF_ITEM.
bool do_clients
If true, attempt to load clients on instantiation.
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
static CONF_PARSER client_config[]
size_t rlm_ldap_unescape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Converts escaped DNs and filter strings into normal.
TALLOC_CTX * ctx
Context to allocate new attributes in.
char const * mech
SASL mech(s) to try.
vp_tmpl_t * profile_filter
Filter to retrieve only retrieve group objects.
size_t strlcpy(char *dst, char const *src, size_t siz)
static CONF_PARSER user_config[]
LDAPControl * userobj_sort_ctrl
Server side sort control.
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
char * rlm_ldap_berval_to_string(TALLOC_CTX *ctx, struct berval const *in)
Convert a berval to a talloced string.
vp_tmpl_t * default_profile
If this is set, we will search for a profile object with this name, and map any attributes it contain...
static rlm_rcode_t user_modify(rlm_ldap_t *inst, REQUEST *request, ldap_acct_section_t *section)
Modify user's object in LDAP.
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
char const * userobj_scope_str
Scope (sub, one, base).
char const * realm
Kerberos realm.
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
String of printable characters.
#define FR_CONF_POINTER(_n, _t, _p)
ldap_sasl admin_sasl
SASL parameters used when binding as the admin.
#define PW_TYPE_TMPL
CONF_PAIR should be parsed as a template.
1 methods index for authorize section.
rlm_rcode_t rlm_ldap_check_groupobj_dynamic(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, VALUE_PAIR *check)
Query the LDAP directory to check if a group object includes a user object as a member.
static rlm_rcode_t CC_HINT(nonnull)
char const * section
Section name e.g. "Authorize".
ldap_acct_section_t * postauth
Modify mappings for post-auth.
int rlm_ldap_map_verify(vp_map_t *map, void *instance)
FR_TOKEN cf_pair_operator(CONF_PAIR const *pair)
LDAP authorization and authentication module headers.
fr_dict_t * fr_dict_internal
Internal server dictionary.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
char const * userobj_sort_by
List of attributes to sort by.
static int mod_detach(void *instance)
Detach from the LDAP server and cleanup internal state.
char const * dereference_str
When to dereference (never, searching, finding, always)
bool rlm_ldap_is_dn(char const *in, size_t inlen)
Check whether a string looks like a DN.
char const * config_server
Server set in the config.
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request) CC_HINT(nonnull)
char const * cf_section_name2(CONF_SECTION const *cs)
void fr_connection_pool_free(fr_connection_pool_t *pool)
Delete a connection pool.
LDAP * handle
libldap handle.
static FR_NAME_NUMBER const ldap_dereference[]
Bind failed, user was rejected.
vp_tmpl_t * mech
SASL mech(s) to try.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_t *dict, char const *attr)
Locate a fr_dict_attr_t by its name.
CONF_ITEM * cf_reference_item(CONF_SECTION const *parentcs, CONF_SECTION *outercs, char const *ptr)