summaryrefslogtreecommitdiffstats
path: root/src/tests/modules/ldap
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/modules/ldap')
-rw-r--r--src/tests/modules/ldap/acct.attrs35
-rw-r--r--src/tests/modules/ldap/acct.unlang23
-rw-r--r--src/tests/modules/ldap/all.mk8
-rw-r--r--src/tests/modules/ldap/auth.attrs15
-rw-r--r--src/tests/modules/ldap/auth.unlang72
l---------src/tests/modules/ldap/example.com.ldif1
-rw-r--r--src/tests/modules/ldap/groups_rfc2307bis.attrs15
-rw-r--r--src/tests/modules/ldap/groups_rfc2307bis.unlang41
-rw-r--r--src/tests/modules/ldap/module.conf537
9 files changed, 747 insertions, 0 deletions
diff --git a/src/tests/modules/ldap/acct.attrs b/src/tests/modules/ldap/acct.attrs
new file mode 100644
index 0000000..1d57034
--- /dev/null
+++ b/src/tests/modules/ldap/acct.attrs
@@ -0,0 +1,35 @@
+#
+# Input packet
+#
+User-Name = 'john'
+NAS-Port = 17826193
+NAS-IP-Address = 192.0.2.10
+Framed-IP-Address = 198.51.100.59
+NAS-Identifier = 'nas.example.org'
+Acct-Status-Type = Start
+Acct-Delay-Time = 1
+Acct-Input-Octets = 0
+Acct-Output-Octets = 0
+Acct-Session-Id = '00000000'
+Acct-Unique-Session-Id = '00000000'
+Acct-Authentic = RADIUS
+Acct-Session-Time = 0
+Acct-Input-Packets = 0
+Acct-Output-Packets = 0
+Acct-Input-Gigawords = 0
+Acct-Output-Gigawords = 0
+Event-Timestamp = 'Feb 1 2015 08:28:58 WIB'
+NAS-Port-Type = Ethernet
+NAS-Port-Id = 'port 001'
+Service-Type = Framed-User
+Framed-Protocol = PPP
+Acct-Link-Count = 0
+Idle-Timeout = 0
+Session-Timeout = 604800
+Access-Loop-Encapsulation = 0x000000
+Proxy-State = 0x323531
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
diff --git a/src/tests/modules/ldap/acct.unlang b/src/tests/modules/ldap/acct.unlang
new file mode 100644
index 0000000..2297ea7
--- /dev/null
+++ b/src/tests/modules/ldap/acct.unlang
@@ -0,0 +1,23 @@
+#
+# Run the "ldap" module
+# PRE: auth
+#
+ldap.accounting {
+}
+if (ok) {
+ test_pass
+}
+else {
+ test_fail
+}
+
+update {
+ Tmp-String-0 := "%{ldap:ldap://$ENV{TEST_SERVER}/uid=john,ou=people,dc=example,dc=com?description}"
+}
+
+if (&Tmp-String-0 != "User john is online") {
+ test_fail
+}
+else {
+ test_pass
+}
diff --git a/src/tests/modules/ldap/all.mk b/src/tests/modules/ldap/all.mk
new file mode 100644
index 0000000..1fc53d1
--- /dev/null
+++ b/src/tests/modules/ldap/all.mk
@@ -0,0 +1,8 @@
+#
+# Test the "ldap" module
+#
+
+# MODULE.test is the main target for this module.
+
+# Don't test ldap if TEST_SERVER ENV is not set
+ldap_require_test_server := 1
diff --git a/src/tests/modules/ldap/auth.attrs b/src/tests/modules/ldap/auth.attrs
new file mode 100644
index 0000000..be988ee
--- /dev/null
+++ b/src/tests/modules/ldap/auth.attrs
@@ -0,0 +1,15 @@
+#
+# Input packet
+#
+User-Name = "john"
+User-Password = "password"
+NAS-IP-Address = 1.2.3.5
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
+Idle-Timeout == 3600
+Session-Timeout == 7200
+Acct-Interim-Interval == 1800
+Framed-IP-Netmask == "255.255.0.0"
diff --git a/src/tests/modules/ldap/auth.unlang b/src/tests/modules/ldap/auth.unlang
new file mode 100644
index 0000000..edf14bf
--- /dev/null
+++ b/src/tests/modules/ldap/auth.unlang
@@ -0,0 +1,72 @@
+#
+# Run the "ldap" module
+#
+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
+}
+
+ldap.post-auth
+
+update {
+ Tmp-String-0 := "%{ldap:ldap://$ENV{TEST_SERVER}/uid=john,ou=people,dc=example,dc=com?description}"
+}
+
+if (&Tmp-String-0 != "User %{User-Name} authenticated") {
+ test_fail
+}
+else {
+ test_pass
+}
diff --git a/src/tests/modules/ldap/example.com.ldif b/src/tests/modules/ldap/example.com.ldif
new file mode 120000
index 0000000..055d379
--- /dev/null
+++ b/src/tests/modules/ldap/example.com.ldif
@@ -0,0 +1 @@
+../../salt-test-server/salt/ldap/base.ldif \ No newline at end of file
diff --git a/src/tests/modules/ldap/groups_rfc2307bis.attrs b/src/tests/modules/ldap/groups_rfc2307bis.attrs
new file mode 100644
index 0000000..be988ee
--- /dev/null
+++ b/src/tests/modules/ldap/groups_rfc2307bis.attrs
@@ -0,0 +1,15 @@
+#
+# Input packet
+#
+User-Name = "john"
+User-Password = "password"
+NAS-IP-Address = 1.2.3.5
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
+Idle-Timeout == 3600
+Session-Timeout == 7200
+Acct-Interim-Interval == 1800
+Framed-IP-Netmask == "255.255.0.0"
diff --git a/src/tests/modules/ldap/groups_rfc2307bis.unlang b/src/tests/modules/ldap/groups_rfc2307bis.unlang
new file mode 100644
index 0000000..b8f48b5
--- /dev/null
+++ b/src/tests/modules/ldap/groups_rfc2307bis.unlang
@@ -0,0 +1,41 @@
+#
+# Run the "ldap" module
+#
+ldap
+
+#
+# Resolve using group name attribute
+#
+if (LDAP-Group == 'foo') {
+ test_pass
+}
+else {
+ test_fail
+}
+
+#
+# Resolve using group DN
+#
+if (LDAP-Group == 'cn=foo,ou=groups,dc=example,dc=com') {
+ test_pass
+}
+else {
+ test_fail
+}
+
+#
+# Check we have these values cached
+#
+if (&control:LDAP-Cached-Membership[*] == 'foo') {
+ test_pass
+}
+else {
+ test_fail
+}
+
+if (&control:LDAP-Cached-Membership[*] == 'cn=foo,ou=groups,dc=example,dc=com') {
+ test_pass
+}
+else {
+ test_fail
+}
diff --git a/src/tests/modules/ldap/module.conf b/src/tests/modules/ldap/module.conf
new file mode 100644
index 0000000..dcf3126
--- /dev/null
+++ b/src/tests/modules/ldap/module.conf
@@ -0,0 +1,537 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Lightweight Directory Access Protocol (LDAP)
+#
+ldap {
+ # Note that this needs to match the name(s) in the LDAP server
+ # certificate, if you're using ldaps. See OpenLDAP documentation
+ # for the behavioral semantics of specifying more than one host.
+ #
+ # Depending on the libldap in use, server may be an LDAP URI.
+ # In the case of OpenLDAP this allows additional the following
+ # additional schemes:
+ # - ldaps:// (LDAP over SSL)
+ # - ldapi:// (LDAP over Unix socket)
+ # - ldapc:// (Connectionless LDAP)
+ server = $ENV{LDAP_TEST_SERVER}
+# server = 'ldap.rrdns.example.org'
+
+ # Port to connect on, defaults to 389, will be ignored for LDAP URIs.
+ port = $ENV{LDAP_TEST_SERVER_PORT}
+
+ # Administrator account for searching and possibly modifying.
+ identity = 'cn=admin,dc=example,dc=com'
+ password = secret
+
+ # Unless overridden in another section, the dn from which all
+ # searches will start from.
+ base_dn = 'dc=example,dc=com'
+
+ # SASL parameters to use for admin binds
+ #
+ # When we're prompted by the SASL library, these control
+ # the responses given.
+ #
+ sasl {
+ # SASL mechanism
+# mech = 'PLAIN'
+
+ # SASL authorisation identity to proxy.
+# proxy = 'autz_id'
+
+ # SASL realm. Used for kerberos.
+# realm = 'example.org'
+ }
+
+ #
+ # Generic valuepair attribute
+ #
+
+ # If set, this will attribute will be retrieved in addition to any
+ # mapped attributes.
+ #
+ # Values should be in the format:
+ # <radius attr> <op> <value>
+ #
+ # Where:
+ # <radius attr>: Is the attribute you wish to create
+ # with any valid list and request qualifiers.
+ # <op>: Is any assignment operator (=, :=, +=, -=).
+ # <value>: Is the value to parse into the new valuepair.
+ # If the value is wrapped in double quotes it
+ # will be xlat expanded.
+ valuepair_attribute = 'radiusAttribute'
+
+ #
+ # 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.
+ #
+ # Configuration items are in the format:
+ # <radius attr> <op> <ldap attr>
+ #
+ # Where:
+ # <radius attr>: Is the destination RADIUS attribute
+ # with any valid list and request qualifiers.
+ # <op>: Is any assignment attribute (=, :=, +=, -=).
+ # <ldap attr>: Is the attribute associated with user or
+ # profile objects in the LDAP directory.
+ # If the attribute name is wrapped in double
+ # quotes it will be xlat expanded.
+ #
+ # Request and list qualifiers may also be placed after the 'update'
+ # section name to set defaults destination requests/lists
+ # for unqualified RADIUS attributes.
+ #
+ # Note: LDAP attribute names should be single quoted unless you want
+ # the name value to be derived from an xlat expansion, or an
+ # attribute ref.
+ update {
+ control:Password-With-Header += 'userPassword'
+ reply:Idle-Timeout := 'radiusIdleTimeout'
+ reply:Framed-IP-Netmask := 'radiusFramedIPNetmask'
+# control:NT-Password := 'ntPassword'
+# reply:Reply-Message := 'radiusReplyMessage'
+# reply:Tunnel-Type := 'radiusTunnelType'
+# reply:Tunnel-Medium-Type := 'radiusTunnelMediumType'
+# reply:Tunnel-Private-Group-ID := 'radiusTunnelPrivategroupId'
+
+ # Where only a list is specified as the RADIUS attribute,
+ # the value of the LDAP attribute is parsed as a valuepair
+ # in the same format as the 'valuepair_attribute' (above).
+ control: += 'radiusControlAttribute'
+ request: += 'radiusRequestAttribute'
+ reply: += 'radiusReplyAttribute'
+ }
+
+ # Set to yes if you have eDirectory and want to use the universal
+ # password mechanism.
+# edir = no
+
+ # Set to yes if you want to bind as the user after retrieving the
+ # Cleartext-Password. This will consume the login grace, and
+ # verify user authorization.
+# edir_autz = no
+
+ # Note: set_auth_type was removed in v3.x.x
+ # Equivalent functionality can be achieved by adding the following
+ # stanza to the authorize {} section of your virtual server.
+ #
+ # ldap
+ # if ((ok || updated) && User-Password) {
+ # update {
+ # control:Auth-Type := ldap
+ # }
+ # }
+
+ #
+ # User object identification.
+ #
+ user {
+ # Where to start searching in the tree for users
+ base_dn = "ou=people,${..base_dn}"
+
+ # Filter for user objects, should be specific enough
+ # to identify a single user object.
+ filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+
+ # SASL parameters to use for user binds
+ #
+ # When we're prompted by the SASL library, these control
+ # the responses given.
+ #
+ # Any of the config items below may be an attribute ref
+ # or and expansion, so different SASL mechs, proxy IDs
+ # and realms may be used for different users.
+ sasl {
+ # SASL mechanism
+# mech = 'PLAIN'
+
+ # SASL authorisation identity to proxy.
+# proxy = &User-Name
+
+ # SASL realm. Used for kerberos.
+# realm = 'example.org'
+ }
+
+ # Search scope, may be 'base', 'one', sub' or 'children'
+# scope = 'sub'
+
+ # If this is undefined, anyone is authorised.
+ # If it is defined, the contents of this attribute
+ # determine whether or not the user is authorised
+# access_attribute = 'dialupAccess'
+
+ # Control whether the presence of 'access_attribute'
+ # allows access, or denys access.
+ #
+ # If 'yes', and the access_attribute is present, or
+ # 'no' and the access_attribute is absent then access
+ # will be allowed.
+ #
+ # If 'yes', and the access_attribute is absent, or
+ # 'no' and the access_attribute is present, then
+ # access will not be allowed.
+ #
+ # If the value of the access_attribute is 'false', it
+ # will negate the result.
+ #
+ # e.g.
+ # access_positive = yes
+ # access_attribute = userAccessAllowed
+ #
+ # With an LDAP object containing:
+ # userAccessAllowed: false
+ #
+ # Will result in the user being locked out.
+# access_positive = yes
+ }
+
+ #
+ # User membership checking.
+ #
+ group {
+ # Where to start searching in the tree for groups
+ base_dn = "ou=groups,${..base_dn}"
+
+ # Filter for group objects, should match all available
+ # group objects a user might be a member of.
+ filter = '(objectClass=groupOfNames)'
+
+ # Search scope, may be 'base', 'one', sub' or 'children'
+ scope = 'sub'
+
+ # Attribute that uniquely identifies a group.
+ # Is used when converting group DNs to group
+ # names.
+ name_attribute = cn
+
+ # Filter to find group objects a user is a member of.
+ # That is, group objects with attributes that
+ # identify members (the inverse of membership_attribute).
+ membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
+
+ # The attribute in user objects which contain the names
+ # or DNs of groups a user is a member of.
+ #
+ # Unless a conversion between group name and group DN is
+ # needed, there's no requirement for the group objects
+ # referenced to actually exist.
+ membership_attribute = 'memberOf'
+
+ # If cacheable_name or cacheable_dn are enabled,
+ # all group information for the user will be
+ # retrieved from the directory and written to LDAP-Group
+ # attributes appropriate for the instance of rlm_ldap.
+ #
+ # For group comparisons these attributes will be checked
+ # instead of querying the LDAP directory directly.
+ #
+ # This feature is intended to be used with rlm_cache.
+ #
+ # If you wish to use this feature, you should enable
+ # the type that matches the format of your check items
+ # i.e. if your groups are specified as DNs then enable
+ # cacheable_dn else enable cacheable_name.
+ cacheable_name = yes
+ cacheable_dn = yes
+
+ # Override the normal cache attribute (<inst>-LDAP-Group)
+ # and create a custom attribute. This can help if multiple
+ # module instances are used in fail-over.
+ cache_attribute = 'LDAP-Cached-Membership'
+ }
+
+ #
+ # User profiles. RADIUS profile objects contain sets of attributes
+ # to insert into the request. These attributes are mapped using
+ # the same mapping scheme applied to user objects.
+ #
+ profile {
+ # Filter for RADIUS profile objects
+ filter = '(objectclass=radiusprofile)'
+
+ # The default profile applied to all users.
+ default = 'cn=radprofile,ou=profiles,dc=example,dc=com'
+
+ # The list of profiles which are applied (after the default)
+ # to all users.
+ # The 'User-Profile' attribute in the control list
+ # will override this setting at run-time.
+ attribute = 'radiusProfileDn'
+ }
+
+ #
+ # Bulk load clients from the directory
+ #
+ client {
+ # Where to start searching in the tree for clients
+ base_dn = "ou=clients,${..base_dn}"
+
+ #
+ # Filter to match client objects
+ #
+ filter = '(objectClass=radiusClient)'
+
+ # Search scope, may be 'base', 'one', 'sub' or 'children'
+# scope = 'sub'
+
+ #
+ # Sets default values (not obtained from LDAP) for new client entries
+ #
+ template {
+# login = 'test'
+# password = 'test'
+# proto = tcp
+# require_message_authenticator = yes
+
+ # Uncomment to add a home_server with the same
+ # attributes as the client.
+# coa_server {
+# response_window = 2.0
+# }
+ }
+
+ #
+ # Client attribute mappings are in the format:
+ # <client attribute> = <ldap attribute>
+ #
+ # The following attributes are required:
+ # * ipaddr | ipv4addr | ipv6addr - Client IP Address.
+ # * secret - RADIUS shared secret.
+ #
+ # All other attributes usually supported in a client
+ # definition are also supported here.
+ #
+ # Schemas are available in doc/schemas/ldap for openldap and eDirectory
+ #
+ attribute {
+ ipaddr = 'radiusClientIdentifier'
+ secret = 'radiusClientSecret'
+# shortname = 'radiusClientShortname'
+# nas_type = 'radiusClientType'
+# virtual_server = 'radiusClientVirtualServer'
+# require_message_authenticator = 'radiusClientRequireMa'
+ }
+ }
+
+ # Load clients on startup
+# read_clients = no
+
+ #
+ # Modify user object on receiving Accounting-Request
+ #
+
+ # Useful for recording things like the last time the user logged
+ # in, or the Acct-Session-ID for CoA/DM.
+ #
+ # LDAP modification items are in the format:
+ # <ldap attr> <op> <value>
+ #
+ # Where:
+ # <ldap attr>: The LDAP attribute to add modify or delete.
+ # <op>: One of the assignment operators:
+ # (:=, +=, -=, ++).
+ # Note: '=' is *not* supported.
+ # <value>: The value to add modify or delete.
+ #
+ # WARNING: If using the ':=' operator with a multi-valued LDAP
+ # attribute, all instances of the attribute will be removed and
+ # replaced with a single attribute.
+ 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 can modify LDAP objects too
+ #
+ post-auth {
+ update {
+ description := "User %{User-Name} authenticated"
+ }
+ }
+
+ #
+ # LDAP connection-specific options.
+ #
+ # 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 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
+
+ # Seconds to wait for LDAP query to finish. default: 20
+ timeout = 10
+
+ # Seconds LDAP server has to process the query (server-side
+ # time limit). default: 20
+ #
+ # LDAP_OPT_TIMELIMIT is set to this value.
+ timelimit = 3
+
+ # Seconds to wait for response of the server. (network
+ # failures) default: 10
+ #
+ # LDAP_OPT_NETWORK_TIMEOUT is set to this value.
+ net_timeout = 1
+
+ # LDAP_OPT_X_KEEPALIVE_IDLE
+ idle = 60
+
+ # LDAP_OPT_X_KEEPALIVE_PROBES
+ probes = 3
+
+ # 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 = 0x0801
+ }
+
+ #
+ # This subsection configures the tls related items
+ # that control how FreeRADIUS connects to an LDAP
+ # server. It contains all of the 'tls_*' configuration
+ # entries used in older versions of FreeRADIUS. Those
+ # configuration entries can still be used, but we recommend
+ # using these.
+ #
+ tls {
+ # Set this to 'yes' to use TLS encrypted connections
+ # to the LDAP database by using the StartTLS extended
+ # operation.
+ #
+ # The StartTLS operation is supposed to be
+ # used with normal ldap connections instead of
+ # using ldaps (port 636) connections
+# start_tls = yes
+
+# ca_file = ${certdir}/cacert.pem
+
+# ca_path = ${certdir}
+# certificate_file = /path/to/radius.crt
+# private_key_file = /path/to/radius.key
+# random_file = ${certdir}/random
+
+ # Certificate Verification requirements. Can be:
+ # 'never' (don't even bother trying)
+ # 'allow' (try, but don't fail if the certificate
+ # can't be verified)
+ # 'demand' (fail if the certificate doesn't verify.)
+ #
+ # The default is 'allow'
+# require_cert = 'demand'
+ }
+
+
+ # As of version 3.0, the 'pool' section has replaced the
+ # following configuration items:
+ #
+ # ldap_connections_number
+
+ # The connection pool is new for 3.0, and will be used in many
+ # modules, for all kinds of connection-related activity.
+ #
+ # When the server is not threaded, the connection pool
+ # limits are ignored, and only one connection is used.
+ pool {
+ # Number of connections to start
+ start = 5
+
+ # Minimum number of connections to keep open
+ min = 4
+
+ # Maximum number of connections
+ #
+ # If these connections are all in use and a new one
+ # is requested, the request will NOT get a connection.
+ #
+ # Setting 'max' to LESS than the number of threads means
+ # that some threads may starve, and you will see errors
+ # like 'No connections available and at max connection limit'
+ #
+ # Setting 'max' to MORE than the number of threads means
+ # that there are more connections than necessary.
+ max = 4
+
+ # Spare connections to be left idle
+ #
+ # NOTE: Idle connections WILL be closed if 'idle_timeout'
+ # is set.
+ spare = 3
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means 'infinite'
+ uses = 0
+
+ # The lifetime (in seconds) of the connection
+ lifetime = 0
+
+ # Idle timeout (in seconds). A connection which is
+ # unused for this length of time will be closed.
+ idle_timeout = 60
+
+ # The number of seconds to wait after the server tries
+ # to open a connection, and fails. During this time,
+ # no new connections will be opened.
+ #
+ retry_delay = 1
+
+ # NOTE: All configuration settings are enforced. If a
+ # connection is closed because of 'idle_timeout',
+ # 'uses', or 'lifetime', then the total number of
+ # connections MAY fall below 'min'. When that
+ # happens, it will open a new connection. It will
+ # also log a WARNING message.
+ #
+ # The solution is to either lower the 'min' connections,
+ # or increase lifetime/idle_timeout.
+ }
+}