31#define APR_WANT_STRFUNC
38#error mod_authnz_ldap requires APR-util to have LDAP support built in. To fix add --with-ldap to ./configure.
102#define GROUPATTR_MAX_ELTS 10
104module AP_MODULE_DECLARE_DATA authnz_ldap_module;
154 if ((*lang ==
',') || (*lang ==
';')) {
211#define FILTER_LENGTH MAX_STRING_LEN
236 filter =
sec->filter;
270#if APR_HAS_MICROSOFT_LDAPSDK
346 sec->have_ldap_url = 0;
351 sec->bind_authoritative = 1;
353 sec->group_attrib_is_dn = 1;
355 sec->maxNestingDepth = 10;
359 sec->remote_user_attribute =
NULL;
360 sec->compare_dn_on_server = 0;
382 const char **vals = req->
vals;
387 if (
sec->attributes && vals) {
390 while (
sec->attributes[
i]) {
401 sec->remote_user_attribute &&
415 const char *
result = user;
445 char *bindpw =
sec->bindpw;
480 const char *dn =
NULL;
496 if (!
sec->have_ldap_url) {
506 "auth_ldap authenticate: no password specified");
512 "auth_ldap authenticate: no user specified");
525 "auth_ldap authenticate: empty password specified");
531 const char *binddn =
sec->binddn;
532 const char *bindpw =
sec->bindpw;
533 if (
sec->initial_bind_as_user) {
544 "auth_ldap authenticate: no sec->host - weird...?");
549 "auth_ldap authenticate: using URL %s",
sec->url);
555 "auth_ldap authenticate: final authn filter is %s",
filtbuf);
568 if (!
sec->bind_authoritative) {
570 "auth_ldap authenticate: user %s authentication failed; "
571 "URI %s [%s][%s] (not authoritative)",
577 "auth_ldap authenticate: "
578 "user %s authentication failed; URI %s [%s][%s]",
587#ifdef LDAP_SECURITY_ERROR
612 if (
sec->user_is_dn) {
622 "auth_ldap authenticate: "
623 "REMOTE_USER was to be set with attribute '%s', "
624 "but this attribute was not requested for in the "
625 "LDAP query for the user. REMOTE_USER will fall "
626 "back to username or DN as appropriate.",
627 sec->remote_user_attribute);
631 "auth_ldap authenticate: accepting %s", user);
656 const char *dn =
NULL;
662 if (!
sec->have_ldap_url) {
674 "auth_ldap authorize: no sec->host - weird...?");
685 if (!strlen(
r->
user)) {
687 "ldap authorize: Userid is blank, AuthType=%s",
693 "ldap authorize: Creating LDAP req structure");
708 "auth_ldap authorise: User DN not found, %s",
ldc->reason);
718 if (req->
dn ==
NULL || strlen(req->
dn) == 0) {
720 "auth_ldap authorize: require user: user's DN has not "
721 "been defined; failing authorization");
728 "auth_ldap authorize: require user: Can't evaluate expression: %s",
741 "auth_ldap authorize: require user: authorization "
748 "auth_ldap authorize: require user: "
749 "authorization failed [%s][%s]",
763 "auth_ldap authorize: "
764 "require user: authorization successful");
770 "auth_ldap authorize: "
771 "require user: authorization failed [%s][%s]",
778 "auth_ldap authorize user: authorization denied for "
804 const char *dn =
NULL;
812 if (!
sec->have_ldap_url) {
824 "auth_ldap authorize: no sec->host - weird...?");
832 if (
sec->groupattr->nelts == 0) {
838 grp->name =
"member";
840 grp->name =
"uniqueMember";
850 if (
sec->subgroupclasses->nelts == 0) {
856 grp->name =
"groupOfNames";
858 grp->name =
"groupOfUniqueNames";
870 if (!strlen(
r->
user)) {
872 "ldap authorize: Userid is blank, AuthType=%s",
878 "ldap authorize: Creating LDAP req structure");
892 "auth_ldap authorise: User DN not found, %s",
ldc->reason);
903 if (
sec->group_attrib_is_dn) {
904 if (req->
dn ==
NULL || strlen(req->
dn) == 0) {
906 "auth_ldap authorize: require group: user's DN has "
907 "not been defined; failing authorization for user %s",
923 "auth_ldap authorize: require group: Can't evaluate expression: %s",
931 "auth_ldap authorize: require group: testing for group "
932 "membership in \"%s\"",
936 for (
i = 0;
i <
sec->groupattr->nelts;
i++) {
938 "auth_ldap authorize: require group: testing for %s: "
941 sec->group_attrib_is_dn ? req->
dn : req->
user,
t);
944 sec->group_attrib_is_dn ? req->
dn : req->
user);
947 "auth_ldap authorize: require group: "
948 "authorization successful (attribute %s) "
957 "auth_ldap authorize: require group \"%s\": "
958 "didn't match with attr %s [%s][%d - %s]",
964 for (
i = 0;
i <
sec->groupattr->nelts;
i++) {
975 "auth_ldap authorise: require group \"%s\": "
976 "failed [%s][%d - %s], checking sub-groups",
980 sec->group_attrib_is_dn ? req->
dn : req->
user,
982 sec->subgroupclasses,
983 0,
sec->maxNestingDepth);
986 "auth_ldap authorise: require group "
987 "(sub-group): authorisation successful "
988 "(attribute %s) [%s][%d - %s]",
996 "auth_ldap authorise: require group "
997 "(sub-group) \"%s\": didn't match with attr %s "
1005 "auth_ldap authorize group: authorization denied for "
1031 const char *dn =
NULL;
1037 if (!
sec->have_ldap_url) {
1049 "auth_ldap authorize: no sec->host - weird...?");
1059 if (!strlen(
r->
user)) {
1061 "ldap authorize: Userid is blank, AuthType=%s",
1067 "ldap authorize: Creating LDAP req structure");
1081 "auth_ldap authorise: User DN not found with filter %s: %s",
filtbuf,
ldc->reason);
1093 "auth_ldap authorize: require dn: Can't evaluate expression: %s",
1100 if (req->
dn ==
NULL || strlen(req->
dn) == 0) {
1102 "auth_ldap authorize: require dn: user's DN has not "
1103 "been defined; failing authorization");
1111 "auth_ldap authorize: "
1112 "require dn: authorization successful");
1118 "auth_ldap authorize: "
1119 "require dn \"%s\": LDAP error [%s][%s]",
1126 "auth_ldap authorize dn: authorization denied for "
1153 const char *dn =
NULL;
1159 if (!
sec->have_ldap_url) {
1171 "auth_ldap authorize: no sec->host - weird...?");
1181 if (!strlen(
r->
user)) {
1183 "ldap authorize: Userid is blank, AuthType=%s",
1189 "ldap authorize: Creating LDAP req structure");
1203 "auth_ldap authorise: User DN not found with filter %s: %s",
filtbuf,
ldc->reason);
1212 if (req->
dn ==
NULL || strlen(req->
dn) == 0) {
1214 "auth_ldap authorize: require ldap-attribute: user's DN "
1215 "has not been defined; failing authorization");
1222 "auth_ldap authorize: require ldap-attribute: Can't "
1223 "evaluate expression: %s",
err);
1234 "auth_ldap authorize: checking attribute %s has value %s",
1240 "auth_ldap authorize: "
1241 "require attribute: authorization successful");
1247 "auth_ldap authorize: require attribute: "
1248 "authorization failed [%s][%s]",
1255 "auth_ldap authorize attribute: authorization denied for "
1281 const char *dn =
NULL;
1287 if (!
sec->have_ldap_url) {
1299 "auth_ldap authorize: no sec->host - weird...?");
1309 if (!strlen(
r->
user)) {
1311 "ldap authorize: Userid is blank, AuthType=%s",
1317 "ldap authorize: Creating LDAP req structure");
1331 "auth_ldap authorise: User DN not found with filter %s: %s",
filtbuf,
ldc->reason);
1340 if (req->
dn ==
NULL || strlen(req->
dn) == 0) {
1342 "auth_ldap authorize: require ldap-filter: user's DN "
1343 "has not been defined; failing authorization");
1350 "auth_ldap authorize: require ldap-filter: Can't "
1351 "evaluate require expression: %s",
err);
1359 "auth_ldap authorize: checking filter %s",
t);
1371 "auth_ldap authorize: checking dn match %s", dn);
1372 if (
sec->compare_as_user) {
1379 sec->compare_dn_on_server);
1385 "auth_ldap authorize: require ldap-filter: "
1386 "authorization successful");
1392 "auth_ldap authorize: require ldap-filter: "
1393 "%s authorization failed [%s][%s]",
1399 "auth_ldap authorize: require ldap-filter: "
1400 "authorization failed [%s][%s]",
1407 "auth_ldap authorize filter: authorization denied for "
1417 const char *expr_err =
NULL;
1425 "Cannot parse expression in require line: ",
1463 if (
urld->lud_attrs &&
urld->lud_attrs[0]) {
1465 while (
urld->lud_attrs[
i]) {
1470 while (
urld->lud_attrs[
i]) {
1474 sec->attribute =
sec->attributes[0];
1477 sec->attribute =
"uid";
1483 if (
urld->lud_filter) {
1484 if (
urld->lud_filter[0] ==
'(') {
1490 strlen(
urld->lud_filter)-2);
1497 sec->filter =
"objectclass=*";
1511 return "Invalid LDAP connection mode setting: must be one of NONE, "
1512 "SSL, or TLS/STARTTLS";
1528 sec->have_ldap_url = 1;
1531 "auth_ldap url parse: `%s', Host: %s, Port: %d, DN: %s, "
1532 "attrib: %s, scope: %s, filter: %s, connection mode: %s",
1537 urld->lud_attrs?
urld->lud_attrs[0] :
"(null)",
1555 else if (
strcmp(
arg,
"searching") == 0) {
1562 sec->deref = always;
1565 return "Unrecognized value for AuthLDAPDereferenceAliases directive";
1576 for (
i = 0;
sec->sgAttributes[
i];
i++) {
1580 return "Too many AuthLDAPSubGroupAttribute values";
1594 return "Too many AuthLDAPSubGroupClass values";
1620 return "Too many AuthLDAPGroupAttribute directives";
1643 return apr_pstrcat(
cmd->pool,
"AuthLDAPInitialBindPattern: cannot compile regular "
1644 "expression '", exp,
"'",
NULL);
1647 sec->bind_regex = regexp;
1648 sec->bind_subst = subst;
1663 "Unable to parse exec arguments from ",
1670 "Invalid AuthLDAPBindPassword exec location:",
1674 (
const char*)
argv[0], (
const char *
const *)
argv);
1678 "Unable to get bind password from exec of ",
1684 sec->bindpw = (
char *)
arg;
1687 if (!(*
sec->bindpw)) {
1688 return "Empty passwords are invalid for AuthLDAPBindPassword";
1697 "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
1698 "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
1700 "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
1701 "to specify redundant servers.\n"
1702 "<li>Port is optional, and specifies the port to connect to.\n"
1703 "<li>basedn specifies the base DN to start searches from\n"
1704 "<li>Attrib specifies what attribute to search for in the directory. If not "
1705 "provided, it defaults to <b>uid</b>.\n"
1706 "<li>Scope is the scope of the search, and can be either <b>sub</b> or "
1707 "<b>one</b>. If not provided, the default is <b>sub</b>.\n"
1708 "<li>Filter is a filter to use in the search. If not provided, "
1709 "defaults to <b>(objectClass=*)</b>.\n"
1711 "Searches are performed using the attribute and the filter combined. "
1712 "For example, assume that the\n"
1713 "LDAP URL is <b>ldap://ldap.airius.com/ou=People, o=Airius?uid?sub?(posixid=*)</b>. "
1715 "be done using the filter <b>(&((posixid=*))(uid=<i>username</i>))</b>, "
1716 "where <i>username</i>\n"
1717 "is the user name passed by the HTTP client. The search will be a subtree "
1718 "search on the branch <b>ou=People, o=Airius</b>."),
1722 "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."),
1725 "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
1729 "Set to 'on' to return failures when user-specific bind fails - defaults to on."),
1733 "Set to 'on' to set the REMOTE_USER environment variable to be the full "
1734 "DN of the remote user. By default, this is set to off, meaning that "
1735 "the REMOTE_USER variable will contain whatever value the remote user sent."),
1739 "Override the user supplied username and place the "
1740 "contents of this attribute in the REMOTE_USER "
1741 "environment variable."),
1745 "Set to 'on' to force auth_ldap to do DN compares (for the \"require dn\" "
1746 "directive) using the server, and set it 'off' to do the compares locally "
1747 "(at the expense of possible false matches). See the documentation for "
1748 "a complete description of this option."),
1751 "Attribute labels used to define sub-group (or nested group) membership in groups - "
1752 "defaults to member and uniqueMember"),
1755 "LDAP objectClass values used to identify sub-group instances - "
1756 "defaults to groupOfNames and groupOfUniqueNames"),
1759 "Maximum subgroup nesting depth to be evaluated - defaults to 10 (top-level group = 0)"),
1762 "A list of attribute labels used to identify the user members of groups - defaults to "
1763 "member and uniquemember"),
1767 "If set to 'on', auth_ldap uses the DN that is retrieved from the server for "
1768 "subsequent group comparisons. If set to 'off', auth_ldap uses the string "
1769 "provided by the client directly. Defaults to 'on'."),
1772 "Determines how aliases are handled during a search. Can be one of the "
1773 "values \"never\", \"searching\", \"finding\", or \"always\". "
1774 "Defaults to always."),
1777 "Character set conversion configuration file. If omitted, character set "
1778 "conversion is disabled."),
1782 "The prefix to add to environment variables set during "
1783 "successful authorization, default '" AUTHZ_PREFIX "'"),
1787 "Set to 'on' to perform the initial DN lookup with the basic auth credentials "
1788 "instead of anonymous or hard-coded credentials"),
1791 "The regex and substitution to determine a username that can bind based on an HTTP basic auth username"),
1795 "Set to 'on' to perform authorization-based searches with the users credentials, when this module "
1796 "has also performed authentication. Does not affect nested groups lookup."),
1799 "Set to 'on' to perform authorization-based compares with the users credentials, when this module "
1800 "has also performed authentication. Does not affect nested groups lookups."),
1809 &authnz_ldap_module);
1829 if (ap_find_linked_module(
"util_ldap.c") ==
NULL) {
1831 "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
1832 "must be loaded in order for mod_authnz_ldap to function properly");
1844 "Invalid charset conversion config path %s",
1846 &authnz_ldap_module));
1852 "could not open charset conversion config file %s.",
1879 "could not find the UTF-8 charset in the file %s.",
apr_size_t char apr_size_t * outbytes
APR general purpose library routines.
apr_size_t const unsigned char unsigned int unsigned int d
APR Standard Headers Support.
APR I18N translation library.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
int ap_cfg_closefile(ap_configfile_t *cfp)
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
apr_status_t ap_pcfg_openfile(ap_configfile_t **ret_cfg, apr_pool_t *p, const char *name)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
#define AP_INIT_ITERATE(directive, func, mconfig, where, help)
char * ap_server_root_relative(apr_pool_t *p, const char *fname)
const char * ap_set_string_slot(cmd_parms *cmd, void *struct_ptr, const char *arg)
#define ap_set_module_config(v, m, val)
#define AP_INIT_TAKE12(directive, func, mconfig, where, help)
const char * ap_set_flag_slot(cmd_parms *cmd, void *struct_ptr, int arg)
void ap_hook_optional_fn_retrieve(ap_HOOK_optional_fn_retrieve_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
apr_status_t ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp)
#define AP_INIT_TAKE2(directive, func, mconfig, where, help)
apr_status_t ap_register_auth_provider(apr_pool_t *pool, const char *provider_group, const char *provider_name, const char *provider_version, const void *provider, int type)
#define AP_AUTH_INTERNAL_PER_CONF
apr_dbd_transaction_t int mode
#define APR_RETRIEVE_OPTIONAL_FN(name)
#define APR_OPTIONAL_FN_TYPE(name)
struct apr_xlate_t apr_xlate_t
const char apr_size_t char * outbuf
#define AP_EXPR_FLAG_STRING_RESULT
#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn)
const char * ap_expr_str_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
#define HTTP_INTERNAL_SERVER_ERROR
#define STANDARD20_MODULE_STUFF
char * ap_get_exec_line(apr_pool_t *p, const char *cmd, const char *const *argv)
char * ap_getword(apr_pool_t *p, const char **line, char stop)
char * ap_pregsub(apr_pool_t *p, const char *input, const char *source, apr_size_t nmatch, ap_regmatch_t pmatch[])
void ap_str_tolower(char *s)
ap_regex_t * ap_pregcomp(apr_pool_t *p, const char *pattern, int cflags)
char * ap_getword_conf(apr_pool_t *p, const char **line)
apr_array_header_t ** result
int strcasecmp(const char *a, const char *b)
int strncasecmp(const char *a, const char *b, size_t n)
#define APR_HASH_KEY_STRING
#define apr_pcalloc(p, size)
const char const char * password
apr_int32_t apr_int32_t apr_int32_t err
Authentication and Authorization Extension for Apache.
#define AUTHN_PROVIDER_VERSION
#define AUTHN_PROVIDER_GROUP
#define AUTHZ_PROVIDER_VERSION
#define AUTHZ_PROVIDER_GROUP
static apr_status_t authnz_ldap_cleanup_connection_close(void *param)
static apr_xlate_t * get_conv_set(request_rec *r)
static authz_status ldapgroup_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static apr_OFN_uldap_connection_close_t * util_ldap_connection_close
static char * default_attributes[3]
static const authz_provider authz_ldapdn_provider
static void ImportULDAPOptFn(void)
static const authz_provider authz_ldapattribute_provider
static const char * ldap_determine_binddn(request_rec *r, const char *user)
static util_ldap_connection_t * get_connection_for_authz(request_rec *r, enum auth_ldap_optype type)
static apr_hash_t * charset_conversions
static const char * mod_auth_ldap_set_subgroup_maxdepth(cmd_parms *cmd, void *config, const char *max_depth)
static const char * mod_auth_ldap_parse_url(cmd_parms *cmd, void *config, const char *url, const char *mode)
static int set_request_vars(request_rec *r, enum auth_ldap_phase phase)
static char * derive_codepage_from_lang(apr_pool_t *p, char *language)
static int authnz_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static const char * mod_auth_ldap_add_group_attribute(cmd_parms *cmd, void *config, const char *arg)
static authz_status ldapattribute_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
@ LDAP_COMPARE_AND_SEARCH
static const authz_provider authz_ldapuser_provider
static authn_status authn_ldap_check_password(request_rec *r, const char *user, const char *password)
static const char * authn_ldap_xlate_password(request_rec *r, const char *sent_password)
static apr_OFN_uldap_ssl_supported_t * util_ldap_ssl_supported
static void authn_ldap_build_filter(char *filtbuf, request_rec *r, const char *sent_user, const char *sent_filter, authn_ldap_config_t *sec)
static const authz_provider authz_ldapfilter_provider
static const char * set_bind_pattern(cmd_parms *cmd, void *_cfg, const char *exp, const char *subst)
static const char * mod_auth_ldap_set_deref(cmd_parms *cmd, void *config, const char *arg)
static const char * set_bind_password(cmd_parms *cmd, void *_cfg, const char *arg)
static void register_hooks(apr_pool_t *p)
static authz_status ldapfilter_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static const char * set_charset_config(cmd_parms *cmd, void *config, const char *arg)
static const char * ldap_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
#define GROUPATTR_MAX_ELTS
static apr_OFN_uldap_cache_getuserdn_t * util_ldap_cache_getuserdn
static apr_OFN_uldap_cache_comparedn_t * util_ldap_cache_comparedn
static const command_rec authnz_ldap_cmds[]
static const char * mod_auth_ldap_add_subgroup_class(cmd_parms *cmd, void *config, const char *arg)
static apr_OFN_uldap_connection_find_t * util_ldap_connection_find
static const char * mod_auth_ldap_add_subgroup_attribute(cmd_parms *cmd, void *config, const char *arg)
static const authz_provider authz_ldapgroup_provider
static authz_status ldapdn_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static apr_OFN_uldap_cache_checkuserid_t * util_ldap_cache_checkuserid
static void * create_authnz_ldap_dir_config(apr_pool_t *p, char *d)
static authz_status ldapuser_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static apr_OFN_uldap_cache_compare_t * util_ldap_cache_compare
static apr_OFN_uldap_cache_check_subgroups_t * util_ldap_cache_check_subgroups
static const authn_provider authn_ldap_provider
apr_array_header_t * groupattr
apr_array_header_t * subgroupclasses
char * remote_user_attribute
A structure that represents the current request.
struct ap_conf_vector_t * request_config
apr_table_t * subprocess_env
struct ap_conf_vector_t * per_dir_config
A structure to keep track of authorization requirements.
A structure to store information for each virtual server.
static int uldap_cache_check_subgroups(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *dn, const char *attrib, const char *value, char **subgroupAttrs, apr_array_header_t *subgroupclasses, int cur_subgroup_depth, int max_subgroup_depth)
static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *dn, const char *reqdn, int compare_dn_on_server)
static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *dn, const char *attrib, const char *value)
static void uldap_connection_close(util_ldap_connection_t *ldc)
static int uldap_ssl_supported(request_rec *r)
static util_ldap_connection_t * uldap_connection_find(request_rec *r, const char *host, int port, const char *binddn, const char *bindpw, deref_options deref, int secure)
static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *basedn, int scope, char **attrs, const char *filter, const char *bindpw, const char **binddn, const char ***retvals)
static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *basedn, int scope, char **attrs, const char *filter, const char **binddn, const char ***retvals)