diff options
Diffstat (limited to 'src/tests/modules/ldap')
-rw-r--r-- | src/tests/modules/ldap/acct.attrs | 35 | ||||
-rw-r--r-- | src/tests/modules/ldap/acct.unlang | 23 | ||||
-rw-r--r-- | src/tests/modules/ldap/all.mk | 8 | ||||
-rw-r--r-- | src/tests/modules/ldap/auth.attrs | 15 | ||||
-rw-r--r-- | src/tests/modules/ldap/auth.unlang | 72 | ||||
l--------- | src/tests/modules/ldap/example.com.ldif | 1 | ||||
-rw-r--r-- | src/tests/modules/ldap/groups_rfc2307bis.attrs | 15 | ||||
-rw-r--r-- | src/tests/modules/ldap/groups_rfc2307bis.unlang | 41 | ||||
-rw-r--r-- | src/tests/modules/ldap/module.conf | 537 |
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. + } +} |