]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
v4: Add additional LDAP tests (#4276)
authorNick Porter <nick@portercomputing.co.uk>
Thu, 21 Oct 2021 14:07:20 +0000 (15:07 +0100)
committerGitHub <noreply@github.com>
Thu, 21 Oct 2021 14:07:20 +0000 (10:07 -0400)
* Add extra entry to test LDAP directory for escaped char matching

* Add tests of %{ldap: } xlat

* Tidy ldap map test - and allow for ldap search results not being fixed order

* Add extra ldap xlat tests

* ldap_debug option is only parsed in the global section

* Add meaningful libldap debugging to tests

* Add secondary LDAP server to CI tests

Allows for referral tests and xlats calling a different server to the
module configured one.

* Add subordinate dc to base.ldif for referral test

* Add tests for referral and requesting an alternate LDAP server

* Add extra LDAP entries for multiple hop referrals

* Test multiple hop LDAP referrals

* Tidy ldap auth test

* Tidy LDAP accounting test

* Tidy LDAP group tests

* "by anonymous auth" needs to be before any "to *" otherwise auth doesn't work

* Add LDAP bind authentication to tests

* LDAP map now returns correct codes

* Add SSL connection to test LDAP server

* Add test SSL LDAP server port to CI config

* Add a second ldap test module instance using SSL

* Add third instance of ldap module using StartTLS

* Add test using SSL connection to LDAP server

* Add test using StartTLS connection to LDAP server

17 files changed:
.github/workflows/ci.yml
raddb/mods-available/ldap
scripts/ci/ldap/slapd2.conf [new file with mode: 0644]
scripts/ci/ldap2-setup.sh [new file with mode: 0755]
src/tests/modules/ldap/acct.unlang
src/tests/modules/ldap/auth.unlang
src/tests/modules/ldap/auth_ssl.attrs [new file with mode: 0644]
src/tests/modules/ldap/auth_ssl.unlang [new file with mode: 0644]
src/tests/modules/ldap/auth_starttls.attrs [new file with mode: 0644]
src/tests/modules/ldap/auth_starttls.unlang [new file with mode: 0644]
src/tests/modules/ldap/groups_rfc2307bis.unlang
src/tests/modules/ldap/map.unlang
src/tests/modules/ldap/module.conf
src/tests/modules/ldap/xlat.attrs
src/tests/modules/ldap/xlat.unlang
src/tests/salt-test-server/salt/ldap/base.ldif
src/tests/salt-test-server/salt/ldap/base2.ldif [new file with mode: 0644]

index 22c386f0cf4393188b308967df0c18af954ad702..50c9d8df49049ad9c698e5d024aef6f6989fff5f 100644 (file)
@@ -288,6 +288,7 @@ jobs:
             mysql-setup.sh \
             openresty-setup.sh \
             ldap-setup.sh \
+            ldap2-setup.sh \
             redis-setup.sh; do
 
             script="./scripts/ci/$i"
@@ -302,6 +303,7 @@ jobs:
         SQL_POSTGRESQL_TEST_SERVER: 127.0.0.1
         LDAP_TEST_SERVER: 127.0.0.1
         LDAP_TEST_SERVER_PORT: 3890
+        LDAP_TEST_SERVER_SSL_PORT: 6360
         REST_TEST_SERVER: 127.0.0.1
         REST_TEST_SERVER_PORT: 8080
         REST_TEST_SERVER_SSL_PORT: 8443
index b6ccd15f59df8d53517e18b5f46e2a09f17114b2..a6003c7d004703f34912793a07c0cb35d48d8d33 100644 (file)
@@ -160,10 +160,44 @@ ldap {
 
                #
                #  ldap_debug:: Debug flags for libldap (see OpenLDAP documentation).
+               #  Set this to enable debugging output from different code areas within libldap.
                #
-               #  .Please see the option 'ldap_debug'
+               #  NOTE: These debugging options can produce significant amounts of logging output.
                #
-#              ldap_debug = 0x0000
+               #  [options="header,autowidth"]
+               #  |===
+               #  | Option             | Value
+               #  | LDAP_DEBUG_TRACE   | 0x0001
+               #  | LDAP_DEBUG_PACKETS | 0x0002
+               #  | LDAP_DEBUG_ARGS    | 0x0004
+               #  | LDAP_DEBUG_CONNS   | 0x0008
+               #  | LDAP_DEBUG_BER     | 0x0010
+               #  | LDAP_DEBUG_FILTER  | 0x0020
+               #  | LDAP_DEBUG_CONFIG  | 0x0040
+               #  | LDAP_DEBUG_ACL     | 0x0080
+               #  | LDAP_DEBUG_STATS   | 0x0100
+               #  | LDAP_DEBUG_STATS2  | 0x0200
+               #  | LDAP_DEBUG_SHELL   | 0x0400
+               #  | LDAP_DEBUG_PARSE   | 0x0800
+               #  | LDAP_DEBUG_SYNC    | 0x4000
+               #  | LDAP_DEBUG_NONE    | 0x8000
+               #  | LDAP_DEBUG_ANY     | (-1)
+               #  |===
+               #
+               #  e.g:
+               #
+               #  If you want to see the LDAP logs only for `trace` and `parse`,
+               #  facilities you should use:
+               #
+               #    (LDAP_DEBUG_TRACE + LDAP_DEBUG_PARSE) = 0x0801
+               #
+               #  Setting the `ldap_debug` configuration item as follows:
+               #
+               #     ldap_debug = 0x0801
+               #
+               #  Default: 0x0000 (no debugging messages)
+               #
+               ldap_debug = 0x0000
        }
 
        #
@@ -658,47 +692,6 @@ ldap {
                #  NOTE: `LDAP_OPT_X_KEEPALIVE_INTERVAL` is set to this value.
                #
                interval = 3
-
-               #
-               #  ldap_debug:: Debug flags for libldap (see OpenLDAP documentation).
-               #  Set this to enable debugging output from different code areas within libldap.
-               #
-               #  NOTE: These debugging options can produce significant amounts of logging output.
-               #
-               #  [options="header,autowidth"]
-               #  |===
-               #  | Option             | Value
-               #  | LDAP_DEBUG_TRACE   | 0x0001
-               #  | LDAP_DEBUG_PACKETS | 0x0002
-               #  | LDAP_DEBUG_ARGS    | 0x0004
-               #  | LDAP_DEBUG_CONNS   | 0x0008
-               #  | LDAP_DEBUG_BER     | 0x0010
-               #  | LDAP_DEBUG_FILTER  | 0x0020
-               #  | LDAP_DEBUG_CONFIG  | 0x0040
-               #  | LDAP_DEBUG_ACL     | 0x0080
-               #  | LDAP_DEBUG_STATS   | 0x0100
-               #  | LDAP_DEBUG_STATS2  | 0x0200
-               #  | LDAP_DEBUG_SHELL   | 0x0400
-               #  | LDAP_DEBUG_PARSE   | 0x0800
-               #  | LDAP_DEBUG_SYNC    | 0x4000
-               #  | LDAP_DEBUG_NONE    | 0x8000
-               #  | LDAP_DEBUG_ANY     | (-1)
-               #  |===
-               #
-               #  e.g:
-               #
-               #  If you want to see the LDAP logs only for `trace` and `parse`,
-               #  facilities you should use:
-               #
-               #    (LDAP_DEBUG_TRACE + LDAP_DEBUG_PARSE) = 0x0801
-               #
-               #  Setting the `ldap_debug` configuration item as follows:
-               #
-               #     ldap_debug = 0x0801
-               #
-               #  Default: 0x0000 (no debugging messages)
-               #
-               ldap_debug = 0x0000
        }
 
        #
diff --git a/scripts/ci/ldap/slapd2.conf b/scripts/ci/ldap/slapd2.conf
new file mode 100644 (file)
index 0000000..a943de9
--- /dev/null
@@ -0,0 +1,61 @@
+#
+###### SAMPLE 1 - SIMPLE DIRECTORY ############
+#
+# NOTES: inetorgperson picks up attributes and objectclasses
+#        from all three schemas
+#
+# NB: RH Linux schemas in /etc/openldap
+#
+include         /tmp/ldap2/schema/core.schema
+include         /tmp/ldap2/schema/cosine.schema
+include         /tmp/ldap2/schema/inetorgperson.schema
+include         /tmp/ldap2/schema/nis.schema
+include         doc/schemas/ldap/openldap/freeradius.schema
+include         doc/schemas/ldap/openldap/freeradius-clients.schema
+pidfile /tmp/slapd2.pid
+
+# enable a lot of logging - we might need it
+# but generates huge logs
+loglevel        -1
+
+# MODULELOAD definitions
+# not required (comment out) before version 2.3
+moduleload back_mdb.la
+
+database config
+rootdn "cn=admin,cn=config"
+rootpw secret
+
+#
+# Certificates for SSL/TLS connections
+# Note - these will not match the host name so clients need to use 
+#        the "allow" option when checking certificates
+#
+TLSCACertificateFile /tmp/ldap2/certs/cacert.pem
+TLSCertificateFile /tmp/ldap2/certs/servercert.pem
+TLSCertificateKeyFile /tmp/ldap2/certs/serverkey.pem
+
+#######################################################################
+# mdb database definitions
+#
+# replace example and com below with a suitable domain
+#
+# If you don't have a domain you can leave it since example.com
+# is reserved for experimentation or change them to my and inc
+#
+#######################################################################
+
+database mdb
+suffix "dc=nodomain"
+
+# root or superuser
+rootdn "cn=admin,dc=nodomain"
+rootpw secret
+# The database directory MUST exist prior to running slapd AND
+# change path as necessary
+directory       /tmp/ldap2/db/
+
+# other database parameters
+# read more in slapd.conf reference section
+checkpoint 128 15
+
diff --git a/scripts/ci/ldap2-setup.sh b/scripts/ci/ldap2-setup.sh
new file mode 100755 (executable)
index 0000000..265891d
--- /dev/null
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Allow setup script to work with homebrew too
+export PATH="/usr/local/opt/openldap/libexec:$PATH"
+
+# Clean out any existing DB
+rm -rf /tmp/ldap2/db
+# Create directory we can write DB files to
+mkdir -p /tmp/ldap2/db/
+
+# Change db location to /tmp as we can't write to /var
+sed -i -e 's/\/var\/lib\/ldap/\/tmp\/ldap2\/db/' src/tests/salt-test-server/salt/ldap/base2.ldif
+
+# Create a directory we can link schema files into
+if [ -d /tmp/ldap2/schema ]; then
+    echo "Schema dir already linked"
+# Debian
+elif [ -d /etc/ldap/schema ]; then
+    ln -fs /etc/ldap/schema /tmp/ldap2/schema
+# Redhat
+elif [ -d /etc/openldap/schema ]; then
+    ln -fs /etc/openldap/schema /tmp/ldap2/schema
+# macOS (homebrew)
+elif [ -d /usr/local/etc/openldap/schema ]; then
+    ln -fs /usr/local/etc/openldap/schema /tmp/ldap2/schema
+else
+    echo "Can't locate OpenLDAP schema dir"
+    exit 1
+fi
+
+# Clean out any old certificates
+rm -rf /tmp/ldap2/certs
+# Create certificate directory
+mkdir -p /tmp/ldap2/certs
+
+# Copy certificates - whilst not stricltly LDAP certs they work fine for these tests
+cp src/tests/certs/rsa/ca.pem /tmp/ldap2/certs/cacert.pem
+cp src/tests/certs/rsa/server.pem /tmp/ldap2/certs/servercert.pem
+# OpenLDAP wants an un-encrypted key
+openssl rsa -in src/tests/certs/rsa/server.key -out /tmp/ldap2/certs/serverkey.pem -passin pass:whatever
+
+# Start slapd
+slapd -h "ldap://127.0.0.1:3891/ ldaps://127.0.0.1:6360" -f scripts/ci/ldap/slapd2.conf &
+
+# Wait for LDAP to start
+sleep 1
+
+# Add test data
+count=0
+while [ $count -lt 10 ] ; do
+    if ldapadd -x -H ldap://127.0.0.1:3891/ -D "cn=admin,cn=config" -w secret -f src/tests/salt-test-server/salt/ldap/base2.ldif ; then
+        break 2
+    else
+        count=$((count+1))
+        sleep 1
+    fi
+done
+
+if [ $? -ne 0 ]; then
+        echo "Error configuring server"
+        exit 1
+fi
+
index 8e9cc465191ba40d2f355022a0f4a18ca4164455..004a2f31dce39d60aefe1d8ed512f8e0fe6fb131 100644 (file)
@@ -4,10 +4,7 @@
 #
 ldap.accounting {
 }
-if (ok) {
-        test_pass
-}
-else {
+if (!ok) {
         test_fail
 }
 
@@ -18,6 +15,5 @@ update {
 if (&Tmp-String-0 != "User john is online") {
         test_fail
 }
-else {
-        test_pass
-}
+
+test_pass
index 7c1bc865902176990458c0c222bfca3efe079390..04d2fc904f82e44ff463a638ad3cf62fe4fc9e2a 100644 (file)
@@ -6,58 +6,40 @@ ldap
 if (&control.NAS-IP-Address != 1.2.3.4) {
         test_fail
 }
-else {
-        test_pass
-}
 
 if (&control.Reply-Message != "Hello world") {
         test_fail
 }
-else {
-        test_pass
-}
 
 # Cmp operator means Framed-IP-Address is ignored
 if (&control.Framed-IP-Address) {
         test_fail
 }
-else {
-        test_pass
-}
 
 # IP netmask defined in profile1 should overwrite radprofile value.
 if (&reply.Framed-IP-Netmask != 255.255.0.0) {
         test_fail
 }
-else {
-        test_pass
-}
 
 if (&reply.Acct-Interim-Interval != 1800) {
         test_fail
 }
-else {
-        test_pass
-}
 
 if (&reply.Idle-Timeout != 3600) {
         test_fail
 }
-else {
-        test_pass
-}
 
 if (&reply.Session-Timeout != 7200) {
         test_fail
 }
-else {
-        test_pass
-}
 
 if ("%(pairs:reply.)" == "") {
         test_fail
 }
 
+# Attempt a bind authentication
+ldap.authenticate
+
 ldap.post-auth
 
 update {
@@ -67,6 +49,5 @@ update {
 if (&Tmp-String-0 != "User %{User-Name} authenticated") {
        test_fail
 }
-else {
-       test_pass
-}
+
+test_pass
diff --git a/src/tests/modules/ldap/auth_ssl.attrs b/src/tests/modules/ldap/auth_ssl.attrs
new file mode 100644 (file)
index 0000000..7faadab
--- /dev/null
@@ -0,0 +1,14 @@
+#
+#  Input packet
+#
+Packet-Type = Access-Request
+User-Name = "fred"
+User-Password = "password"
+NAS-IP-Address = 1.2.3.5
+
+#
+#  Expected answer
+#
+Packet-Type == Access-Accept
+Idle-Timeout == 3600
+Session-Timeout == 7200
diff --git a/src/tests/modules/ldap/auth_ssl.unlang b/src/tests/modules/ldap/auth_ssl.unlang
new file mode 100644 (file)
index 0000000..e0c322b
--- /dev/null
@@ -0,0 +1,40 @@
+#
+#  Run the "ldapssl" module - an instance of ldap using an ssl conneciton
+#
+ldapssl
+
+if (&control.NAS-IP-Address != 1.2.3.4) {
+        test_fail
+}
+
+# Cmp operator means Framed-IP-Address is ignored
+if (&control.Framed-IP-Address) {
+        test_fail
+}
+
+if (&reply.Idle-Timeout != 3600) {
+        test_fail
+}
+
+if (&reply.Session-Timeout != 7200) {
+        test_fail
+}
+
+if ("%(pairs:reply.)" == "") {
+        test_fail
+}
+
+# Attempt a bind authentication
+ldapssl.authenticate
+
+ldapssl.post-auth
+
+update {
+        &Tmp-String-0 := "%{ldapssl:ldaps:///uid=fred,ou=people,dc=subdept,dc=example,dc=com?description}"
+}
+
+if (&Tmp-String-0 != "User %{User-Name} authenticated") {
+       test_fail
+}
+
+test_pass
diff --git a/src/tests/modules/ldap/auth_starttls.attrs b/src/tests/modules/ldap/auth_starttls.attrs
new file mode 100644 (file)
index 0000000..7faadab
--- /dev/null
@@ -0,0 +1,14 @@
+#
+#  Input packet
+#
+Packet-Type = Access-Request
+User-Name = "fred"
+User-Password = "password"
+NAS-IP-Address = 1.2.3.5
+
+#
+#  Expected answer
+#
+Packet-Type == Access-Accept
+Idle-Timeout == 3600
+Session-Timeout == 7200
diff --git a/src/tests/modules/ldap/auth_starttls.unlang b/src/tests/modules/ldap/auth_starttls.unlang
new file mode 100644 (file)
index 0000000..6f838e8
--- /dev/null
@@ -0,0 +1,41 @@
+#
+#  Run the "ldapssl" module - an instance of ldap using an ssl conneciton
+#
+
+ldaptls
+
+if (&control.NAS-IP-Address != 1.2.3.4) {
+        test_fail
+}
+
+# Cmp operator means Framed-IP-Address is ignored
+if (&control.Framed-IP-Address) {
+        test_fail
+}
+
+if (&reply.Idle-Timeout != 3600) {
+        test_fail
+}
+
+if (&reply.Session-Timeout != 7200) {
+        test_fail
+}
+
+if ("%(pairs:reply.)" == "") {
+        test_fail
+}
+
+# Attempt a bind authentication
+ldaptls.authenticate
+
+ldaptls.post-auth
+
+update {
+        &Tmp-String-0 := "%{ldaptls:ldap:///uid=fred,ou=people,dc=subdept,dc=example,dc=com?description}"
+}
+
+if (&Tmp-String-0 != "User %{User-Name} authenticated") {
+       test_fail
+}
+
+test_pass
index 9a6ea42b5bb9e092c0c8b59c93b89f3f5700969b..80060de829eec8fbe4a55209a40ec9c3c9aeb97e 100644 (file)
@@ -6,36 +6,26 @@ ldap
 #
 #  Resolve using group name attribute
 #
-if (&LDAP-Group == 'foo') {
-        test_pass
-}
-else {
+if (&LDAP-Group != 'foo') {
         test_fail
 }
 
 #
 #  Resolve using group DN
 #
-if (&LDAP-Group == 'cn=foo,ou=groups,dc=example,dc=com') {
-        test_pass
-}
-else {
+if (&LDAP-Group != 'cn=foo,ou=groups,dc=example,dc=com') {
         test_fail
 }
 
 #
 #  Check we have these values cached
 #
-if (&control.LDAP-Cached-Membership[*] == 'foo') {
-       test_pass
-}
-else {
+if (&control.LDAP-Cached-Membership[*] != 'foo') {
        test_fail
 }
 
-if (&control.LDAP-Cached-Membership[*] == 'cn=foo,ou=groups,dc=example,dc=com') {
-       test_pass
-}
-else {
+if (&control.LDAP-Cached-Membership[*] != 'cn=foo,ou=groups,dc=example,dc=com') {
        test_fail
 }
+
+test_pass
index ac788fcefadb18cacd9aa94c1396137cb3cf478b..2dda4f20a808ed4a124e9066ffedcb2002cb7ae9 100644 (file)
@@ -3,30 +3,19 @@ map ldap "ldap:///ou=profiles,dc=example,dc=com??sub?(objectClass=radiusprofile)
        &Tmp-String-1 += 'entryDN'
 }
 
-if (updated) {
-       test_pass
-} else {
+if (!updated) {
        test_fail
 }
 
-if (&request.Tmp-String-0 == '255.255.255.0') {
-       test_pass
-}
-else {
+if (&request.Tmp-String-0 != '255.255.255.0') {
        test_fail
 }
 
-if (&request.Tmp-String-1[0] == 'cn=radprofile,ou=profiles,dc=example,dc=com') {
-       test_pass
-}
-else {
+if (&request.Tmp-String-1[*] != 'cn=radprofile,ou=profiles,dc=example,dc=com') {
        test_fail
 }
 
-if (&request.Tmp-String-1[1] == 'cn=profile1,ou=profiles,dc=example,dc=com') {
-       test_pass
-}
-else {
+if (&request.Tmp-String-1[*] != 'cn=profile1,ou=profiles,dc=example,dc=com') {
        test_fail
 }
 
@@ -35,11 +24,8 @@ map ldap "ldap:///ou=profiles,dc=example,dc=com??sub?(objectClass=notARealObject
        &Tmp-String-1 += 'entryDN'
 }
 
-#
-#  Uncomment when map return codes work properly
-#
-#if (notfound) {
-#      test_pass
-#} else {
-#      test_fail
-#}
+if (!notfound) {
+       test_fail
+}
+
+test_pass
index a4151e79d7882049b2820ee5cdb9e7d9397d9f33..b7b4f2be01c051a0659c9499742ccfcd0cacdbb1 100644 (file)
@@ -53,6 +53,17 @@ ldap {
 #              realm = 'example.org'
        }
 
+       global {
+               #  ldap_debug: debug flag for LDAP SDK
+               #  (see OpenLDAP documentation).  Set this to enable
+               #  huge amounts of LDAP debugging on the screen.
+               #  You should only use this if you are an LDAP expert.
+               #
+               #       default: 0x0000 (no debugging messages)
+               #       Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
+               ldap_debug = 0x0801
+       }
+
        #
        #  Generic valuepair attribute
        #
@@ -349,6 +360,7 @@ ldap {
                #
                chase_referrals = yes
                rebind = yes
+               referral_depth = 2
 
                #  Seconds to wait for LDAP query to finish. default: 20
                timeout = 10
@@ -368,14 +380,6 @@ ldap {
                #  LDAP_OPT_X_KEEPALIVE_INTERVAL
                interval = 3
 
-               #  ldap_debug: debug flag for LDAP SDK
-               #  (see OpenLDAP documentation).  Set this to enable
-               #  huge amounts of LDAP debugging on the screen.
-               #  You should only use this if you are an LDAP expert.
-               #
-               #       default: 0x0000 (no debugging messages)
-               #       Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
-               ldap_debug = 0x0028
        }
 
        #
@@ -479,3 +483,238 @@ ldap {
                #  or increase lifetime/idle_timeout.
        }
 }
+
+#
+#  Second LDAP connection using SSL
+#
+ldap ldapssl {
+       server = "ldaps://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_SSL_PORT}/"
+
+       identity = 'cn=admin,dc=example,dc=com'
+       password = secret
+
+       base_dn = 'dc=subdept,dc=example,dc=com'
+
+       sasl {
+       }
+
+       global {
+               ldap_debug = 0x0801
+       }
+
+       valuepair_attribute = 'radiusAttribute'
+
+       update {
+               &control.Password.With-Header   += 'userPassword'
+               &reply.Idle-Timeout             := 'radiusIdleTimeout'
+               &reply.Framed-IP-Netmask        := 'radiusFramedIPNetmask'
+
+               &control                        += 'radiusControlAttribute'
+               &request                        += 'radiusRequestAttribute'
+               &reply                          += 'radiusReplyAttribute'
+       }
+
+       user {
+               base_dn = "ou=people,${..base_dn}"
+
+               filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+
+               sasl {
+               }
+       }
+
+       group {
+               base_dn = "ou=groups,${..base_dn}"
+               filter = '(objectClass=groupOfNames)'
+               scope = 'sub'
+               name_attribute = cn
+               membership_filter = "(|(member=%{control.Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
+               membership_attribute = 'memberOf'
+               cacheable_name = no
+               cacheable_dn = no
+               cache_attribute = 'LDAP-Cached-Membership'
+       }
+
+       profile {
+               filter = '(objectclass=radiusprofile)'
+               default = 'cn=radprofile,ou=profiles,dc=example,dc=com'
+               attribute = 'radiusProfileDn'
+       }
+
+       accounting {
+               reference = "%{tolower:type.%{Acct-Status-Type}}"
+               type {
+                       start {
+                               update {
+                                       description := "User %{User-Name} is online"
+                               }
+                       }
+                       interim-update {
+                               update {
+                                       description := "Last seen at %S"
+                               }
+                       }
+                       stop {
+                               update {
+                                       description := "Offline at %S"
+                               }
+                       }
+               }
+       }
+
+       post-auth {
+               update {
+                       description := "User %{User-Name} authenticated"
+               }
+       }
+
+       options {
+#              dereference = 'always'
+
+               chase_referrals = yes
+               rebind = yes
+               referral_depth = 2
+
+               timeout = 10
+               timelimit = 3
+               idle = 60
+               probes = 3
+               interval = 3
+
+       }
+
+       tls {
+               require_cert    = 'allow'
+               ca_file = 'src/tests/certs/rsa/ca.pem'
+       }
+
+       pool {
+               start = 1
+               min = 1
+               max = 4
+               spare = 0
+               uses = 0
+               lifetime = 0
+               idle_timeout = 60
+               retry_delay = 1
+       }
+}
+
+#
+#  Third LDAP connection using StartTLS
+#
+ldap ldaptls {
+       server = "$ENV{LDAP_TEST_SERVER}"
+
+       port = 3891
+
+       identity = 'cn=admin,dc=example,dc=com'
+       password = secret
+
+       base_dn = 'dc=subdept,dc=example,dc=com'
+
+       sasl {
+       }
+
+       global {
+               ldap_debug = 0x0801
+       }
+
+       valuepair_attribute = 'radiusAttribute'
+
+       update {
+               &control.Password.With-Header   += 'userPassword'
+               &reply.Idle-Timeout             := 'radiusIdleTimeout'
+               &reply.Framed-IP-Netmask        := 'radiusFramedIPNetmask'
+
+               &control                        += 'radiusControlAttribute'
+               &request                        += 'radiusRequestAttribute'
+               &reply                          += 'radiusReplyAttribute'
+       }
+
+       user {
+               base_dn = "ou=people,${..base_dn}"
+
+               filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+
+               sasl {
+               }
+       }
+
+       group {
+               base_dn = "ou=groups,${..base_dn}"
+               filter = '(objectClass=groupOfNames)'
+               scope = 'sub'
+               name_attribute = cn
+               membership_filter = "(|(member=%{control.Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
+               membership_attribute = 'memberOf'
+               cacheable_name = no
+               cacheable_dn = no
+               cache_attribute = 'LDAP-Cached-Membership'
+       }
+
+       profile {
+               filter = '(objectclass=radiusprofile)'
+               default = 'cn=radprofile,ou=profiles,dc=example,dc=com'
+               attribute = 'radiusProfileDn'
+       }
+
+       accounting {
+               reference = "%{tolower:type.%{Acct-Status-Type}}"
+               type {
+                       start {
+                               update {
+                                       description := "User %{User-Name} is online"
+                               }
+                       }
+                       interim-update {
+                               update {
+                                       description := "Last seen at %S"
+                               }
+                       }
+                       stop {
+                               update {
+                                       description := "Offline at %S"
+                               }
+                       }
+               }
+       }
+
+       post-auth {
+               update {
+                       description := "User %{User-Name} authenticated"
+               }
+       }
+
+       options {
+#              dereference = 'always'
+
+               chase_referrals = yes
+               rebind = yes
+               referral_depth = 2
+
+               timeout = 10
+               timelimit = 3
+               idle = 60
+               probes = 3
+               interval = 3
+
+       }
+
+       tls {
+               start_tls       = yes
+               require_cert    = 'allow'
+               ca_file = 'src/tests/certs/rsa/ca.pem'
+       }
+
+       pool {
+               start = 1
+               min = 1
+               max = 4
+               spare = 3
+               uses = 0
+               lifetime = 0
+               idle_timeout = 60
+               retry_delay = 1
+       }
+}
index d08077d093f430dcc19d3d7bb5c728d8988b0c52..c12b9e965d1bd4799fede6e4b10ac5e2c6d38618 100644 (file)
@@ -5,6 +5,7 @@ Packet-Type = Access-Request
 User-Name = "john"
 User-Password = "password"
 NAS-IP-Address = 1.2.3.5
+Tmp-String-9 = "(manager)"
 
 #
 #  Expected answer
index e72fbf97e22ef7ff0e599a40a9d387c976765196..7a9eac1cef241e1443f04a97d9c748bb74531d91 100644 (file)
@@ -59,4 +59,92 @@ if (&Tmp-String-5 != ',+"\<>;*=()') {
         test_fail
 }
 
+update request {
+        &Tmp-String-6 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=people,dc=example,dc=com?displayName?sub?(uid=john)}"
+}
+
+if (&Tmp-String-6 != "John Doe") {
+        test_fail
+}
+
+# Return multiple values - could be in any sequence
+update request {
+        &Tmp-String-7 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=clients,dc=example,dc=com?radiusClientIdentifier?sub?(objectClass=radiusClient)}"
+}
+
+if ((&Tmp-String-7 != "1.1.1.12.2.2.2") && (&Tmp-String-7 != "2.2.2.21.1.1.1")) {
+        test_fail
+}
+
+# Use tainted string in filter - with special characters
+update request {
+        &Tmp-String-8 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=people,dc=example,dc=com?cn?sub?(displayName=*%{Tmp-String-9}*)}"
+}
+
+if (&Tmp-String-8 != "Bob Smith") {
+        test_fail
+}
+
+# A query which should return no results
+update request {
+        &Tmp-String-0 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=people,dc=example,dc=com?displayName?sub?(uid=notknown)}"
+}
+
+if (&Tmp-String-0 != "") {
+        test_fail
+}
+
+# Request an invalid DN
+update request {
+        &Tmp-String-0 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=notthere?displayName?sub?(uid=john)}"
+}
+
+if (&Tmp-String-0 != "") {
+        test_fail
+}
+
+if (&Module-Failure-Message != "LDAP server returned an error: lib error: No such object (32)") {
+        test_fail
+}
+
+# Query within a dn which will prompt a referral
+update request {
+        &Tmp-String-0 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/dc=subdept,dc=example,dc=com?displayName?sub?(uid=fred)}"
+}
+
+if (&Tmp-String-0 != "Fred Jones") {
+        test_fail
+}
+
+# Reference an alternative LDAP server in the xlat
+update request {
+        &Tmp-String-1 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:%{expr:$ENV{LDAP_TEST_SERVER_PORT} + 1}/dc=subdept,dc=example,dc=com?displayName?sub?(uid=fred)}"
+}
+
+if (&Tmp-String-1 != "Fred Jones") {
+        test_fail
+}
+
+# This query will follow 2 referrals, the second will present an alternate search base
+update request {
+        &Tmp-String-2 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=offsite,dc=subdept,dc=example,dc=com?displayName?sub?(uid=john)}"
+}
+
+if (&Tmp-String-2 != "John Doe") {
+        test_fail
+}
+
+# This query will follow 3 referrals - more than our max referral depth
+update request {
+        &Tmp-String-3 := "%{ldap:ldap://$ENV{LDAP_TEST_SERVER}:$ENV{LDAP_TEST_SERVER_PORT}/ou=bounce1,dc=subdept,dc=example,dc=com?displayName?sub?(uid=fred)}"
+}
+
+if (&Tmp-String-3 != "") {
+        test_fail
+}
+
+if (&Module-Failure-Message != "Maximum LDAP referral depth (2) exceeded") {
+        test_fail
+}
+
 test_pass
index 20fc51ca9e375a2de493a53915bca9b8d747c265..6195e92aa3e37d727a8bcef09a16c847db93e017 100644 (file)
@@ -10,8 +10,8 @@ olcRootPW: {SSHA}SgCZuAcGQA5HlgKi+g5xwVyI2NhXRFYh
 olcDbIndex: objectClass eq
 olcLastMod: TRUE
 olcDbCheckpoint: 512 30
-olcAccess: to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn="cn=admin,cn=config" manage
 olcAccess: to attrs=userPassword by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
+olcAccess: to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn="cn=admin,cn=config" manage
 olcAccess: to attrs=shadowLastChange by self write by * read
 olcAccess: to dn.base="" by * read
 olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read
@@ -79,6 +79,22 @@ radiusAttribute: reply.Session-Timeout := 7200
 radiusAttribute: control.NAS-IP-Address := 1.2.3.4
 radiusProfileDN: cn=profile1,ou=profiles,dc=example,dc=com
 
+dn: uid=bob,ou=people,dc=example,dc=com
+objectClass: inetOrgPerson
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: radiusprofile
+uid: bob
+sn: Smith
+givenName: Bob
+cn: Bob Smith
+displayName: Bob Smith (manager)
+userPassword: testing
+uidNumber: 101
+gidNumber: 101
+homeDirectory: /home/bob
+radiusIdleTimeout: 7200
+
 dn: ou=clients,dc=example,dc=com
 objectClass: organizationalUnit
 ou: clients
@@ -100,3 +116,16 @@ radiusClientShortname: client2
 radiusClientType: cisco
 radiusClientRequireMa: TRUE
 radiusClientComment: Another test client
+
+dn: dc=subdept,dc=example,dc=com
+objectClass: referral
+objectClass: extensibleObject
+dc: subdept
+ref: ldap://127.0.0.1:3892/
+ref: ldap://127.0.0.1:3891/dc=subdept,dc=example,dc=com
+
+dn: ou=bounce2,dc=example,dc=com
+objectClass: referral
+objectClass: extensibleObject
+ou: bounce2
+ref: ldap://127.0.0.1:3891/dc=subdept,dc=example,dc=com??sub
diff --git a/src/tests/salt-test-server/salt/ldap/base2.ldif b/src/tests/salt-test-server/salt/ldap/base2.ldif
new file mode 100644 (file)
index 0000000..4ae6b07
--- /dev/null
@@ -0,0 +1,81 @@
+# Database settings
+dn: olcDatabase=mdb,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcMdbConfig
+olcDatabase: {1}mdb
+olcSuffix: dc=example,dc=com
+olcDbDirectory: /tmp/ldap2/db
+olcRootDN: cn=admin,dc=example,dc=com
+olcRootPW: {SSHA}SgCZuAcGQA5HlgKi+g5xwVyI2NhXRFYh
+olcDbIndex: objectClass eq
+olcLastMod: TRUE
+olcDbCheckpoint: 512 30
+olcAccess: to attrs=userPassword by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
+olcAccess: to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn="cn=admin,cn=config" manage
+olcAccess: to attrs=shadowLastChange by self write by * read
+olcAccess: to dn.base="" by * read
+olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read
+
+# Create top-level object in domain
+dn: dc=example,dc=com
+objectClass: top
+objectClass: dcObject
+objectclass: organization
+o: Example Organization
+dc: Example
+description: LDAP Example Two
+
+dn: dc=subdept,dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Sub org
+dc: subdept
+
+dn: ou=people,dc=subdept,dc=example,dc=com
+objectClass: organizationalUnit
+ou: people
+
+dn: ou=groups,dc=subdept,dc=example,dc=com
+objectClass: organizationalUnit
+ou: groups
+
+dn: ou=profiles,dc=subdept,dc=example,dc=com
+objectClass: organizationalUnit
+ou: profiles
+
+dn: cn=radprofile,ou=profiles,dc=subdept,dc=example,dc=com
+objectClass: radiusObjectProfile
+objectClass: radiusprofile
+cn: radprofile
+radiusFramedIPNetmask: 255.255.255.0
+
+dn: uid=fred,ou=people,dc=subdept,dc=example,dc=com
+objectClass: inetOrgPerson
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: radiusprofile
+uid: fred
+sn: Jones
+givenName: Fred
+cn: Fred Jones
+displayName: Fred Jones
+userPassword: password
+uidNumber: 100
+gidNumber: 100
+homeDirectory: /home/fred
+radiusIdleTimeout: 3600
+radiusAttribute: reply.Session-Timeout := 7200
+radiusAttribute: control.NAS-IP-Address := 1.2.3.4
+radiusProfileDN: cn=radprofile,ou=profiles,ou=subdept,dc=example,dc=com
+
+dn: ou=offsite,dc=subdept,dc=example,dc=com
+objectClass: referral
+objectClass: extensibleObject
+ou: offsite
+ref: ldap://127.0.0.1:3890/dc=example,dc=com??sub
+
+dn: ou=bounce1,dc=subdept,dc=example,dc=com
+objectClass: referral
+objectClass: extensibleObject
+ou: bounce1
+ref: ldap://127.0.0.1:3890/ou=bounce2,dc=example,dc=com??sub