/*
* Scopes
*/
-const FR_NAME_NUMBER ldap_scope[] = {
+FR_NAME_NUMBER const ldap_scope[] = {
{ "sub", LDAP_SCOPE_SUB },
{ "one", LDAP_SCOPE_ONE },
{ "base", LDAP_SCOPE_BASE },
+#ifdef LDAP_SCOPE_CHILDREN
{ "children", LDAP_SCOPE_CHILDREN },
-
+#endif
{ NULL , -1 }
};
#ifdef LDAP_OPT_X_TLS_NEVER
-const FR_NAME_NUMBER ldap_tls_require_cert[] = {
+FR_NAME_NUMBER const ldap_tls_require_cert[] = {
{ "never", LDAP_OPT_X_TLS_NEVER },
{ "demand", LDAP_OPT_X_TLS_DEMAND },
{ "allow", LDAP_OPT_X_TLS_ALLOW },
};
#endif
+FR_NAME_NUMBER const ldap_dereference[] = {
+ { "never", LDAP_DEREF_NEVER },
+ { "searching", LDAP_DEREF_SEARCHING },
+ { "finding", LDAP_DEREF_FINDING },
+ { "always", LDAP_DEREF_ALWAYS },
+
+ { NULL , -1 }
+};
+
/*
* TLS Configuration
*/
/*
* Deprecated attributes
*/
- {"cacertfile", PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, offsetof(ldap_instance_t, tls_ca_file), NULL, NULL},
- {"ca_file", PW_TYPE_FILE_INPUT, offsetof(ldap_instance_t, tls_ca_file), NULL, NULL},
+ { "cacertfile", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, ldap_instance_t, tls_ca_file), NULL },
+ { "ca_file", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, ldap_instance_t, tls_ca_file), NULL },
- {"cacertdir", PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, offsetof(ldap_instance_t, tls_ca_path), NULL, NULL},
- {"ca_path", PW_TYPE_FILE_INPUT, offsetof(ldap_instance_t, tls_ca_path), NULL, NULL},
+ { "cacertdir", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, ldap_instance_t, tls_ca_path), NULL },
+ { "ca_path", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, ldap_instance_t, tls_ca_path), NULL },
- {"certfile", PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, offsetof(ldap_instance_t, tls_certificate_file), NULL, NULL},
- {"certificate_file", PW_TYPE_FILE_INPUT, offsetof(ldap_instance_t, tls_certificate_file), NULL, NULL},
+ { "certfile", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, ldap_instance_t, tls_certificate_file), NULL },
+ { "certificate_file", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, ldap_instance_t, tls_certificate_file), NULL },
- {"keyfile", PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, offsetof(ldap_instance_t, tls_private_key_file), NULL, NULL}, // OK if it changes on HUP
- {"private_key_file", PW_TYPE_FILE_INPUT, offsetof(ldap_instance_t, tls_private_key_file), NULL, NULL}, // OK if it changes on HUP
+ { "keyfile", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, ldap_instance_t, tls_private_key_file), NULL }, // OK if it changes on HUP
+ { "private_key_file", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, ldap_instance_t, tls_private_key_file), NULL }, // OK if it changes on HUP
- {"randfile", PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, offsetof(ldap_instance_t, tls_random_file), NULL, NULL},
- {"random_file", PW_TYPE_FILE_INPUT, offsetof(ldap_instance_t, tls_random_file), NULL, NULL},
+ { "randfile", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT | PW_TYPE_DEPRECATED, ldap_instance_t, tls_random_file), NULL },
+ { "random_file", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, ldap_instance_t, tls_random_file), NULL },
/*
* LDAP Specific TLS attributes
*/
- {"start_tls", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t, start_tls), NULL, "no"},
- {"require_cert", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, tls_require_cert_str), NULL, NULL},
+ { "start_tls", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, start_tls), "no" },
+ { "require_cert", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, tls_require_cert_str), NULL },
{ NULL, -1, 0, NULL, NULL }
};
static CONF_PARSER profile_config[] = {
- {"filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, profile_filter), NULL, "(&)"}, //!< Correct filter for
+ { "filter", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, profile_filter), "(&)" }, //!< Correct filter for
//!< when the DN is
//!< known.
- {"attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, profile_attr), NULL, NULL},
- {"default", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, default_profile), NULL, NULL},
+ { "attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, profile_attr), NULL },
+ { "default", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, default_profile), NULL },
{ NULL, -1, 0, NULL, NULL }
};
* User configuration
*/
static CONF_PARSER user_config[] = {
- {"filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, userobj_filter), NULL, "(uid=%u)"},
- {"scope", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, userobj_scope_str), NULL, "sub"},
- {"base_dn", PW_TYPE_STRING_PTR | PW_TYPE_REQUIRED, offsetof(ldap_instance_t,userobj_base_dn), NULL, NULL},
+ { "filter", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, userobj_filter), "(uid=%u)" },
+ { "scope", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, userobj_scope_str), "sub" },
+ { "base_dn", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, userobj_base_dn), "" },
- {"access_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, userobj_access_attr), NULL, NULL},
- {"access_positive", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t, access_positive), NULL, "yes"},
+ { "access_attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, userobj_access_attr), NULL },
+ { "access_positive", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, access_positive), "yes" },
{ NULL, -1, 0, NULL, NULL }
};
* Group configuration
*/
static CONF_PARSER group_config[] = {
- {"filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, groupobj_filter), NULL, NULL},
- {"scope", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, groupobj_scope_str), NULL, "sub"},
- {"base_dn", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, groupobj_base_dn), NULL, NULL},
+ { "filter", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, groupobj_filter), NULL },
+ { "scope", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, groupobj_scope_str), "sub" },
+ { "base_dn", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, groupobj_base_dn), "" },
- {"name_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, groupobj_name_attr), NULL, "cn"},
- {"membership_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, userobj_membership_attr), NULL, NULL},
- {"membership_filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, groupobj_membership_filter), NULL, NULL},
- {"cacheable_name", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t, cacheable_group_name), NULL, "no"},
- {"cacheable_dn", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t, cacheable_group_dn), NULL, "no"},
+ { "name_attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, groupobj_name_attr), "cn" },
+ { "membership_attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, userobj_membership_attr), NULL },
+ { "membership_filter", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, groupobj_membership_filter), NULL },
+ { "cacheable_name", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, cacheable_group_name), "no" },
+ { "cacheable_dn", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, cacheable_group_dn), "no" },
+ { "cache_attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, cache_attribute), NULL },
{ NULL, -1, 0, NULL, NULL }
};
* Client configuration
*/
static CONF_PARSER client_attribute[] = {
- {"identifier", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_identifier), NULL, "host"},
- {"shortname", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_shortname), NULL, "cn"},
- {"nas_type", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_type), NULL, NULL},
- {"secret", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_secret), NULL, NULL},
- {"virtual_server", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_server), NULL, NULL},
- {"require_message_authenticator", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_require_ma),
- NULL, NULL},
+ { "identifier", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_identifier), "host" },
+ { "shortname", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_shortname), "cn" },
+ { "nas_type", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_type), NULL },
+ { "secret", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_secret), NULL },
+ { "virtual_server", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_server), NULL },
+ { "require_message_authenticator", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_require_ma), NULL },
{ NULL, -1, 0, NULL, NULL }
};
static CONF_PARSER client_config[] = {
- {"filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_filter), NULL, NULL},
- {"scope", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_scope_str), NULL, "sub"},
- {"base_dn", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, clientobj_base_dn), NULL, NULL},
- {"attribute", PW_TYPE_SUBSECTION, 0, NULL, (void const *) client_attribute},
+ { "filter", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_filter), NULL },
+ { "scope", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_scope_str), "sub" },
+ { "base_dn", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, clientobj_base_dn), "" },
+ { "attribute", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) client_attribute },
{ NULL, -1, 0, NULL, NULL }
};
* Reference for accounting updates
*/
static const CONF_PARSER acct_section_config[] = {
- {"reference", PW_TYPE_STRING_PTR, offsetof(ldap_acct_section_t, reference), NULL, "."},
+ { "reference", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_acct_section_t, reference), "." },
{NULL, -1, 0, NULL, NULL}
};
/*
* Debugging flags to the server
*/
- {"ldap_debug", PW_TYPE_INTEGER, offsetof(ldap_instance_t,ldap_debug), NULL, "0x0000"},
+ { "ldap_debug", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, ldap_debug), "0x0000" },
+
+ { "dereference", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, dereference_str), NULL },
- {"chase_referrals", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t,chase_referrals), NULL, NULL},
+ { "chase_referrals", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, chase_referrals), NULL },
- {"rebind", PW_TYPE_BOOLEAN,offsetof(ldap_instance_t,rebind), NULL, NULL},
+ { "rebind", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, rebind), NULL },
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
/* timeout on network activity */
- {"net_timeout", PW_TYPE_INTEGER, offsetof(ldap_instance_t,net_timeout), NULL, "10"},
+ { "net_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, net_timeout), "10" },
+#endif
/* timeout for search results */
- {"res_timeout", PW_TYPE_INTEGER, offsetof(ldap_instance_t,res_timeout), NULL, "20"},
+ { "res_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, res_timeout), "20" },
/* allow server unlimited time for search (server-side limit) */
- {"srv_timelimit", PW_TYPE_INTEGER, offsetof(ldap_instance_t,srv_timelimit), NULL, "20"},
+ { "srv_timelimit", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, srv_timelimit), "20" },
#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
- {"idle", PW_TYPE_INTEGER, offsetof(ldap_instance_t,keepalive_idle), NULL, "60"},
+ { "idle", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, keepalive_idle), "60" },
#endif
#ifdef LDAP_OPT_X_KEEPALIVE_PROBES
- {"probes", PW_TYPE_INTEGER, offsetof(ldap_instance_t,keepalive_probes), NULL, "3"},
+ { "probes", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, keepalive_probes), "3" },
#endif
#ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
- {"interval", PW_TYPE_INTEGER, offsetof(ldap_instance_t,keepalive_interval), NULL, "30"},
+ { "interval", FR_CONF_OFFSET(PW_TYPE_INTEGER, ldap_instance_t, keepalive_interval), "30" },
#endif
{ NULL, -1, 0, NULL, NULL }
static const CONF_PARSER module_config[] = {
- {"server", PW_TYPE_STRING_PTR | PW_TYPE_REQUIRED, offsetof(ldap_instance_t,server), NULL, "localhost"},
- {"port", PW_TYPE_INTEGER, offsetof(ldap_instance_t,port), NULL, "389"},
+ { "server", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_REQUIRED, ldap_instance_t, server), "localhost" },
+ { "port", FR_CONF_OFFSET(PW_TYPE_SHORT, ldap_instance_t, port), "389" },
- {"password", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t,password), NULL, ""},
- {"identity", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t,admin_dn), NULL, ""},
+ { "password", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_SECRET, ldap_instance_t, password), "" },
+ { "identity", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, admin_dn), "" },
- {"valuepair_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance_t, valuepair_attr), NULL, NULL},
+ { "valuepair_attribute", FR_CONF_OFFSET(PW_TYPE_STRING, ldap_instance_t, valuepair_attr), NULL },
#ifdef WITH_EDIR
/* support for eDirectory Universal Password */
- {"edir", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t,edir), NULL, NULL}, /* NULL defaults to "no" */
+ { "edir", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, edir), NULL }, /* NULL defaults to "no" */
/*
- * Attempt to bind with the Cleartext password we got from eDirectory
+ * Attempt to bind with the cleartext password we got from eDirectory
* Universal password for additional authorization checks.
*/
- {"edir_autz", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t,edir_autz), NULL, NULL}, /* NULL defaults to "no" */
+ { "edir_autz", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, edir_autz), NULL }, /* NULL defaults to "no" */
#endif
- {"read_clients", PW_TYPE_BOOLEAN, offsetof(ldap_instance_t,do_clients), NULL, NULL}, /* NULL defaults to "no" */
+ { "read_clients", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, do_clients), NULL }, /* NULL defaults to "no" */
- { "user", PW_TYPE_SUBSECTION, 0, NULL, (void const *) user_config },
+ { "user", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) user_config },
- { "group", PW_TYPE_SUBSECTION, 0, NULL, (void const *) group_config },
+ { "group", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) group_config },
- { "client", PW_TYPE_SUBSECTION, 0, NULL, (void const *) client_config },
+ { "client", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) client_config },
- { "profile", PW_TYPE_SUBSECTION, 0, NULL, (void const *) profile_config },
+ { "profile", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) profile_config },
- { "options", PW_TYPE_SUBSECTION, 0, NULL, (void const *) option_config },
+ { "options", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) option_config },
- { "tls", PW_TYPE_SUBSECTION, 0, NULL, (void const *) tls_config },
+ { "tls", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) tls_config },
{NULL, -1, 0, NULL, NULL}
};
if (ldap_url->lud_host &&
((strncmp(inst->server, ldap_url->lud_host, strlen(inst->server)) != 0) ||
- (ldap_url->lud_port != inst->port))) {
+ ((uint32_t) ldap_url->lud_port != inst->port))) {
RDEBUG("Requested server/port is \"%s:%i\"", ldap_url->lud_host, inst->port);
goto free_urldesc;
ldap_instance_t *inst = instance;
rlm_rcode_t rcode;
- int found = false;
- int check_is_dn;
+ bool found = false;
+ bool check_is_dn;
ldap_handle_t *conn = NULL;
char const *user_dn;
- if (!inst->groupobj_base_dn) {
- REDEBUG("Directive 'group.base_dn' must be set'");
-
- return 1;
- }
+ rad_assert(inst->groupobj_base_dn);
RDEBUG("Searching for user in group \"%s\"", check->vp_strvalue);
* @return 0 on success, else < 0 on failure.
*/
static int parse_sub_section(ldap_instance_t *inst, CONF_SECTION *parent, ldap_acct_section_t **config,
- rlm_components_t comp)
+ rlm_components_t comp)
{
CONF_SECTION *cs;
*/
static int mod_instantiate(CONF_SECTION *conf, void *instance)
{
+ static bool version_done;
+
+ CONF_SECTION *options;
ldap_instance_t *inst = instance;
inst->cs = conf;
- inst->chase_referrals = 2; /* use OpenLDAP defaults */
- inst->rebind = 2;
+ options = cf_section_sub_find(conf, "options");
+ if (!options || !cf_pair_find(options, "chase_referrals")) {
+ inst->chase_referrals_unset = true; /* use OpenLDAP defaults */
+ }
inst->xlat_name = cf_section_name2(conf);
if (!inst->xlat_name) {
}
/*
+ * Get version info from the LDAP API.
+ */
+ if (!version_done) {
+ int ldap_errno;
+ LDAPAPIInfo info;
+
+ version_done = true;
+
+ ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
+ if (ldap_errno == LDAP_OPT_SUCCESS) {
+ if (strcmp(info.ldapai_vendor_name, LDAP_VENDOR_NAME) != 0) {
+ WARN("rlm_ldap: libldap vendor changed since the server was built");
+ WARN("rlm_ldap: linked: %s built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
+ }
+
+ if (info.ldapai_vendor_version != LDAP_VENDOR_VERSION) {
+ WARN("rlm_ldap: libldap version changed since the server was built");
+ WARN("rlm_ldap: linked: %i built: %i",
+ info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
+ }
+
+ INFO("rlm_ldap: libldap vendor: %s version: %i", info.ldapai_vendor_name,
+ info.ldapai_vendor_version);
+ ldap_memfree(info.ldapai_vendor_name);
+ ldap_memfree(info.ldapai_extensions);
+ } else {
+ WARN("rlm_ldap: Falling back to build time libldap version info. Query for LDAP_OPT_API_INFO "
+ "returned: %i", ldap_errno);
+ INFO("rlm_ldap: libldap vendor: %s version: %i", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
+ }
+ }
+
+ /*
* If the configuration parameters can't be parsed, then fail.
*/
if ((parse_sub_section(inst, conf, &inst->accounting, RLM_COMPONENT_ACCT) < 0) ||
}
}
- if (inst->cacheable_group_name || inst->cacheable_group_dn) {
- if (!inst->groupobj_base_dn) {
- LDAP_ERR("Directive 'group.base_dn' must be set if cacheable group names are enabled");
-
- goto error;
- }
- }
-
/*
* Check for URLs. If they're used and the library doesn't support them, then complain.
*/
#endif
}
+#ifdef LDAP_OPT_X_TLS_NEVER
/*
* Workaround for servers which support LDAPS but not START TLS
*/
} else {
inst->tls_mode = 0;
}
+#endif
+
+ /*
+ * Convert dereference strings to enumerated constants
+ */
+ if (inst->dereference_str) {
+ inst->dereference = fr_str2int(ldap_dereference, inst->dereference_str, -1);
+ if (inst->dereference < 0) {
+ LDAP_ERR("Invalid 'dereference' value \"%s\", expected 'never', 'searching', "
+ "'finding' or 'always'", inst->dereference_str);
+ goto error;
+ }
+ }
#if LDAP_SET_REBIND_PROC_ARGS != 3
/*
*/
inst->userobj_scope = fr_str2int(ldap_scope, inst->userobj_scope_str, -1);
if (inst->userobj_scope < 0) {
- LDAP_ERR("Invalid 'user.scope' value \"%s\", expected 'sub', 'one', 'base' or 'children'",
- inst->userobj_scope_str);
+ LDAP_ERR("Invalid 'user.scope' value \"%s\", expected 'sub', 'one'"
+#ifdef LDAP_SCOPE_CHILDREN
+ ", 'base' or 'children'"
+#else
+ " or 'base'"
+#endif
+ , inst->userobj_scope_str);
goto error;
}
inst->groupobj_scope = fr_str2int(ldap_scope, inst->groupobj_scope_str, -1);
if (inst->groupobj_scope < 0) {
- LDAP_ERR("Invalid 'group.scope' value \"%s\", expected 'sub', 'one', 'base' or 'children'",
- inst->groupobj_scope_str);
+ LDAP_ERR("Invalid 'group.scope' value \"%s\", expected 'sub', 'one'"
+#ifdef LDAP_SCOPE_CHILDREN
+ ", 'base' or 'children'"
+#else
+ " or 'base'"
+#endif
+ , inst->groupobj_scope_str);
goto error;
}
inst->clientobj_scope = fr_str2int(ldap_scope, inst->clientobj_scope_str, -1);
if (inst->clientobj_scope < 0) {
- LDAP_ERR("Invalid 'client.scope' value \"%s\", expected 'sub', 'one', 'base' or 'children'",
- inst->clientobj_scope_str);
+ LDAP_ERR("Invalid 'client.scope' value \"%s\", expected 'sub', 'one'"
+#ifdef LDAP_SCOPE_CHILDREN
+ ", 'base' or 'children'"
+#else
+ " or 'base'"
+#endif
+ , inst->clientobj_scope_str);
goto error;
}
}
#else
LDAP_ERR("Modifying 'tls.require_cert' is not supported by current version of libldap. "
- "Please upgrade libldap and rebuild this module");
+ "Please upgrade or substitute current libldap and rebuild this module");
goto error;
#endif
* Group comparison checks.
*/
if (cf_section_name2(conf)) {
- ATTR_FLAGS flags;
+ static ATTR_FLAGS flags;
char buffer[256];
- snprintf(buffer, sizeof(buffer), "%s-Ldap-Group",
- inst->xlat_name);
- memset(&flags, 0, sizeof(flags));
+ snprintf(buffer, sizeof(buffer), "%s-Ldap-Group", inst->xlat_name);
+ if (dict_addattr(buffer, -1, 0, PW_TYPE_STRING, flags) < 0) {
+ LDAP_ERR("Error creating group attribute: %s", fr_strerror());
- dict_addattr(buffer, -1, 0, PW_TYPE_STRING, flags);
+ return -1;
+ }
inst->group_da = dict_attrbyname(buffer);
if (!inst->group_da) {
LDAP_ERR("Failed creating attribute %s", buffer);
xlat_register(inst->xlat_name, ldap_xlat, rlm_ldap_escape_func, inst);
/*
+ * Setup the cache attribute
+ */
+ if (inst->cache_attribute) {
+ static ATTR_FLAGS flags;
+
+ if (dict_addattr(inst->cache_attribute, -1, 0, PW_TYPE_STRING, flags) < 0) {
+ LDAP_ERR("Error creating cache attribute: %s", fr_strerror());
+
+ return -1;
+ }
+ inst->cache_da = dict_attrbyname(inst->cache_attribute);
+ } else {
+ inst->cache_da = inst->group_da; /* Default to the group_da */
+ }
+
+ /*
* Initialize the socket pool.
*/
- inst->pool = fr_connection_pool_init(inst->cs, inst, mod_conn_create, NULL, mod_conn_delete, NULL);
+ inst->pool = fr_connection_pool_init(inst->cs, inst, mod_conn_create, NULL, NULL, NULL);
if (!inst->pool) {
return -1;
}
return -1;
}
-/** Check the user's password against ldap directory
- *
- * @param instance rlm_ldap configuration.
- * @param request Current request.
- * @return one of the RLM_MODULE_* values.
- */
-static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request)
+static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
{
rlm_rcode_t rcode;
ldap_rcode_t status;
if (!request->password ||
(request->password->da->attr != PW_USER_PASSWORD)) {
- RWDEBUG("You have set \"Auth-Type := LDAP\" somewhere.");
+ RWDEBUG("You have set \"Auth-Type := LDAP\" somewhere");
RWDEBUG("*********************************************");
RWDEBUG("* THAT CONFIGURATION IS WRONG. DELETE IT. ");
- RWDEBUG("* YOU ARE PREVENTING THE SERVER FROM WORKING.");
+ RWDEBUG("* YOU ARE PREVENTING THE SERVER FROM WORKING");
RWDEBUG("*********************************************");
- REDEBUG("Attribute \"User-Password\" is required for authentication.");
+ REDEBUG("Attribute \"User-Password\" is required for authentication");
return RLM_MODULE_INVALID;
}
return rcode;
}
-/** Check if user is authorized for remote access
- *
- */
-static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
+static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request)
{
rlm_rcode_t rcode = RLM_MODULE_OK;
ldap_rcode_t status;
rlm_ldap_map_xlat_t expanded; /* faster than mallocing every time */
if (!request->username) {
- RDEBUG2("Attribute \"User-Name\" is required for authorization.");
+ RDEBUG2("Attribute \"User-Name\" is required for authorization");
return RLM_MODULE_NOOP;
}
*/
res = nmasldap_get_password(conn->handle, dn, password, &pass_size);
if (res != 0) {
- RWDEBUG("Failed to retrieve eDirectory password");
- rcode = RLM_MODULE_NOOP;
+ REDEBUG("Failed to retrieve eDirectory password: (%i) %s", res, edir_errstr(res));
+ rcode = RLM_MODULE_FAIL;
goto finish;
}
pairstrcpy(vp, password);
vp->length = pass_size;
- RDEBUG2("Added eDirectory password in check items as %s = %s", vp->da->name, vp->vp_strvalue);
+ if (RDEBUG_ENABLED3) {
+ RDEBUG3("Added eDirectory password. control:%s += '%s'", vp->da->name, vp->vp_strvalue);
+ } else {
+ RDEBUG2("Added eDirectory password");
+ }
if (inst->edir_autz) {
RDEBUG2("Binding as user for eDirectory authorization checks");
switch (status) {
case LDAP_PROC_SUCCESS:
rcode = RLM_MODULE_OK;
- RDEBUG("Bind as user \"%s\" was successful", dn);
-
+ RDEBUG("Bind as user '%s' was successful", dn);
break;
+
case LDAP_PROC_NOT_PERMITTED:
rcode = RLM_MODULE_USERLOCK;
-
goto finish;
+
case LDAP_PROC_REJECT:
rcode = RLM_MODULE_REJECT;
-
goto finish;
+
case LDAP_PROC_BAD_DN:
rcode = RLM_MODULE_INVALID;
-
goto finish;
+
case LDAP_PROC_NO_RESULT:
rcode = RLM_MODULE_NOTFOUND;
-
goto finish;
+
default:
rcode = RLM_MODULE_FAIL;
-
goto finish;
};
}
/*
* Apply ONE user profile, or a default user profile.
*/
- vp = pairfind(request->config_items, PW_USER_PROFILE, 0, TAG_ANY);
- if (vp || inst->default_profile) {
- char const *profile = vp ? vp->vp_strvalue : inst->default_profile;
+ if (inst->default_profile) {
+ char profile[1024];
+
+ if (radius_xlat(profile, sizeof(profile), request, inst->default_profile, NULL, NULL) < 0) {
+ REDEBUG("Failed creating default profile string");
+
+ rcode = RLM_MODULE_INVALID;
+ goto finish;
+ }
rlm_ldap_map_profile(inst, request, &conn, profile, &expanded);
}
}
}
- if (inst->user_map) {
+ if (inst->user_map || inst->valuepair_attr) {
+ RDEBUG("Processing user attributes");
rlm_ldap_map_do(inst, request, conn->handle, &expanded, entry);
rlm_ldap_check_reply(inst, request);
}
static rlm_rcode_t user_modify(ldap_instance_t *inst, REQUEST *request, ldap_acct_section_t *section)
{
rlm_rcode_t rcode = RLM_MODULE_OK;
+ ldap_rcode_t status;
ldap_handle_t *conn = NULL;
* Iterate over all the pairs, building our mods array
*/
for (ci = cf_item_find_next(cs, NULL); ci != NULL; ci = cf_item_find_next(cs, ci)) {
- int do_xlat = false;
+ bool do_xlat = false;
- if (total == LDAP_MAX_ATTRMAP) {
- REDEBUG("Modify map size exceeded");
+ if (total == LDAP_MAX_ATTRMAP) {
+ REDEBUG("Modify map size exceeded");
- goto error;
- }
+ goto error;
+ }
if (!cf_item_is_pair(ci)) {
REDEBUG("Entry is not in \"ldap-attribute = value\" format");
continue;
}
- switch (cf_pair_value_type(cp))
- {
- case T_BARE_WORD:
- case T_SINGLE_QUOTED_STRING:
+ switch (cf_pair_value_type(cp)) {
+ case T_BARE_WORD:
+ case T_SINGLE_QUOTED_STRING:
break;
- case T_BACK_QUOTED_STRING:
- case T_DOUBLE_QUOTED_STRING:
- do_xlat = true;
+
+ case T_BACK_QUOTED_STRING:
+ case T_DOUBLE_QUOTED_STRING:
+ do_xlat = true;
break;
- default:
- rad_assert(0);
- goto error;
+
+ default:
+ rad_assert(0);
+ goto error;
}
if (op == T_OP_CMP_FALSE) {
} else if (do_xlat) {
char *exp = NULL;
- if (radius_xlat(exp, 0, request, value, NULL, NULL) <= 0) {
+ if (radius_axlat(&exp, request, value, NULL, NULL) <= 0) {
RDEBUG("Skipping attribute \"%s\"", attr);
talloc_free(exp);
last_pass += 2;
- switch (op)
- {
+ switch (op) {
/*
* T_OP_EQ is *NOT* supported, it is impossible to
* support because of the lack of transactions in LDAP
#endif
default:
REDEBUG("Operator '%s' is not supported for LDAP modify operations",
- fr_int2str(fr_tokens, op, "<INVALID>"));
+ fr_int2str(fr_tokens, op, "<INVALID>"));
goto error;
}
* Now we know the value is ok, copy the pointers into
* the ldapmod struct.
*/
- memcpy(&(mod_s[total].mod_type), &(attr), sizeof(mod_s[total].mod_type));
+ memcpy(&(mod_s[total].mod_type), &attr, sizeof(mod_s[total].mod_type));
mod_p[total] = &(mod_s[total]);
total++;
goto error;
}
- rcode = rlm_ldap_modify(inst, request, &conn, dn, modify);
+ status = rlm_ldap_modify(inst, request, &conn, dn, modify);
+ switch (status) {
+ case LDAP_PROC_SUCCESS:
+ break;
+
+ case LDAP_PROC_REJECT:
+ case LDAP_PROC_BAD_DN:
+ rcode = RLM_MODULE_INVALID;
+ break;
+
+ default:
+ rcode = RLM_MODULE_FAIL;
+ break;
+ };
release:
error:
return rcode;
}
-static rlm_rcode_t mod_accounting(void *instance, REQUEST * request) {
+static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST * request) {
ldap_instance_t *inst = instance;
if (inst->accounting) {
return RLM_MODULE_NOOP;
}
-static rlm_rcode_t mod_post_auth(void *instance, REQUEST * request)
+static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST * request)
{
ldap_instance_t *inst = instance;