Add support for dereferencing (following LDAP aliases)
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 13 Jun 2014 07:54:30 +0000 (08:54 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 13 Jun 2014 07:54:30 +0000 (08:54 +0100)
raddb/mods-available/ldap
src/modules/rlm_ldap/ldap.c
src/modules/rlm_ldap/ldap.h
src/modules/rlm_ldap/rlm_ldap.c

index af3f155..1f0ee03 100644 (file)
@@ -26,7 +26,7 @@ ldap {
        #
        #  Generic valuepair attribute
        #
-       
+
        #  If set, this will attribute will be retrieved in addition to any
        #  mapped attributes.
        #
@@ -45,7 +45,7 @@ ldap {
        #
        #  Mapping of LDAP directory attributes to RADIUS dictionary attributes.
        #
-       
+
        #  WARNING: Although this format is almost identical to the unlang
        #  update section format, it does *NOT* mean that you can use other
        #  unlang constructs in module configuration files.
@@ -104,7 +104,7 @@ ldap {
        #            control:Auth-Type := ldap
        #        }
        #    }
-       
+
        #
        #  User object identification.
        #
@@ -328,11 +328,19 @@ ldap {
        #  These options set timeouts, keep-alives, etc. for the connections.
        #
        options {
+               #  Control under which situations aliases are followed.
+               #  May be one of 'never', 'searching', 'finding' or 'always'
+               #  default: libldap's default which is usually 'never'.
+               #
+               #  LDAP_OPT_DEREF is set to this value.
+#              dereference = 'always'
+
                #
-               #  The following two configuration items are for Active Directory
-               #  compatibility.  If you set these to "no", then searches
-               #  will likely return "operations error", instead of a
-               #  useful result.
+               #  The following two configuration items control whether the
+               #  server follows references returned by LDAP directory.
+               #  They are  mostly for Active Directory compatibility.
+               #  If you set these to "no", then searches will likely return
+               #  "operations error", instead of a useful result.
                #
                chase_referrals = yes
                rebind = yes
index 47c1f80..70d2813 100644 (file)
@@ -1159,6 +1159,13 @@ void *mod_conn_create(void *instance)
        }
 
        /*
+        *      Leave "dereference" unset to use the OpenLDAP default.
+        */
+       if (inst->dereference_str) {
+               do_ldap_option(LDAP_OPT_DEREF, "dereference", &(inst->dereference));
+       }
+
+       /*
         *      Leave "chase_referrals" unset to use the OpenLDAP default.
         */
        if (!inst->chase_referrals_unset) {
index da28d65..0dac3f5 100644 (file)
@@ -72,6 +72,9 @@ typedef struct ldap_instance {
                                                        //!< directory.
        char const      *password;                      //!< Password used in administrative bind.
 
+       char const      *dereference_str;               //!< When to dereference (never, searching, finding, always)
+       int             dereference;                    //!< libldap value specifying dereferencing behaviour.
+
        bool            chase_referrals;                //!< If the LDAP server returns a referral to another server
                                                        //!< or point in the tree, follow it, establishing new
                                                        //!< connections and binding where necessary.
index 8fbe04a..ed833c2 100644 (file)
@@ -60,6 +60,15 @@ FR_NAME_NUMBER const ldap_tls_require_cert[] = {
 };
 #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
  */
@@ -177,6 +186,8 @@ static CONF_PARSER option_config[] = {
         */
        { "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", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, chase_referrals), NULL },
 
        { "rebind", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ldap_instance_t, rebind), NULL },
@@ -583,6 +594,16 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
        }
 #endif
 
+       /*
+        *      Convert dereference strings to enumerated constants
+        */
+       inst->dereference = fr_str2int(ldap_scope, 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
        /*
         *      The 2-argument rebind doesn't take an instance variable.  Our rebind function needs the instance