Alan Buxey alan.buxey at gmail.com
Sat May 26 21:10:33 CEST 2018


from the output you have

uid=u5496622,ou=Techmahindra,ou=Partners,o= mydomain.com

which doesnt match any of your checks, neither

ou=guest,ou=wifi,o= mydomain.com

nor

cn=WiFiGuestPartners,ou=RADIUS Groups,ou=Groups,ou=staff,o=mydomain.com"

so it fails those 2 checks and rejects.


alan



On 26 May 2018 at 11:16, Saurabh Lahoti <saurabh.astronomy at gmail.com> wrote:

> Dear Alan,
>
> Below is the configuration for wifi virtual server: specific to post-auth
> section
>
> post-auth {
>     if( Airespace-Wlan-Id == 2 ) {
>       if( "%{control:LDAP-UserDN}" =~ /ou=guest,ou=wifi,o=mydomain.com$/i
> )
> {
>         noop
>       }
>       elsif( LDAP_Group  == "cn=WiFiGuestPartners,ou=RADIUS
> Groups,ou=Groups,ou=staff,o=mydomain.com") {
>         noop
>       }
>     else {
>         reject
>     }
>  }
>
> LDAP module config:
> # -*- text -*-
> #
> #  $Id$
>
> #
> #  Lightweight Directory Access Protocol (LDAP)
> #
> ldap ldapwifi {
>         #  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 = 'ldapcorp.ux.mydomain.com'
> #       server = 'ldap.rrdns.example.org'
> #       server = 'ldap.rrdns.example.org'
>
>         #  Port to connect on, defaults to 389, will be ignored for LDAP
> URIs.
>         port = 389
>
>         #  Administrator account for searching and possibly modifying.
>         #  If using SASL + KRB5 these should be commented out.
>         identity = 'uid=wifiadmin,ou=production,ou=system,o=mydomain.com'
>         password = xxxxxxx
>
>         #  Unless overridden in another section, the dn from which all
>         #  searches will start from.
>         base_dn = 'o=mydomain.com'
>
>         #
>         #  SASL parameters to use for admin binds
>         #
>         #  When we're prompted by the SASL library, these control
>         #  the responses given, as well as the identity and password
>         #  directives above.
>         #
>         #  If any directive is commented out, a NULL response will be
>         #  provided to cyrus-sasl.
>         #
>         #  Unfortunately the only way to control Keberos here is through
>         #  environmental variables, as cyrus-sasl provides no API to
>         #  set the krb5 config directly.
>         #
>         #  Full documentation for MIT krb5 can be found here:
>         #
>         #
> http://web.mit.edu/kerberos/krb5-devel/doc/admin/env_variables.html
>         #
>         #  At a minimum you probably want to set KRB5_CLIENT_KTNAME.
>         #
> #       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'
> #               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 = "${..base_dn}"
>
>                 #  Filter for user objects, should be specific enough
>                 #  to identify a single user object.
>                 #
>                 #  For Active Directory, you should use
>                 #  "samaccountname=" instead of "uid="
>                 #
>                 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'
>
>                 #  Server side result sorting
>                 #
>                 #  A list of space delimited attributes to order the result
>                 #  set by, if the filter matches multiple objects.
>                 #  Only the first result in the set will be processed.
>                 #
>                 #  If the attribute name is prefixed with a hyphen '-' the
>                 #  sorting order will be reversed for that attribute.
>                 #
>                 #  If sort_by is set, and the server does not support
> sorting
>                 #  the search will fail.
> #               sort_by = '-uid'
>
>                 #  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 = "${..base_dn}"
>
>                 #  Filter for group objects, should match all available
>                 #  group objects a user might be a member of.
>                 filter =
> '(&(objectClass=GroupOfUniqueNames)(uniquemember=%{control:LDAP-UserDN}))'
>
>                 # 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 =
> "(|(&(objectClass=group)(member=%{control:Ldap-UserDn})))"
>
>                 #  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 = 'no'
> #               cacheable_dn = 'no'
>
>                 #  Override the normal cache attribute (<inst>-LDAP-Group
> or
>                 #  LDAP-Group if using the default instance) 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 (the update
> section above).
>         #
> #       profile {
>                 #  Filter for RADIUS profile objects
> #               filter = '(objectclass=radiusprofile)'
>
>                 #  The default profile.  This may be a DN or an attribute
>                 #  reference.
>                 #  To get old v2.2.x style behaviour, or to use the
>                 #  &User-Profile attribute to specify the default profile,
>                 #  set this to &control:User-Profile.
> #               default = 'cn=radprofile,dc=example,dc=org'
>
>                 #  The LDAP attribute containing profile DNs to apply
>                 #  in addition to the default profile above.  These are
>                 #  retrieved from the user object, at the same time as the
>                 #  attributes from the update section, are are applied
>                 #  if authorization is successful.
> #               attribute = 'radiusProfileDn'
> #       }
>
>         #
>         #  Bulk load clients from the directory
>         #
> #       client {
>                 #   Where to start searching in the tree for clients
> #               base_dn = "${..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 := "Online at %S"
>                                 }
>                         }
>
>                         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 := "Authenticated at %S"
>                 }
>         }
>
>         #
>         #  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
>
>                 # SASL Security Properties (see SASL_SECPROPS in ldap.conf
> man page).
>                 # Note - uncomment when using GSS-API sasl mechanism along
> with TLS
>                 # encryption against Active-Directory LDAP servers (this
> disables
>                 # sealing and signing at the GSS level as required by AD).
>                 #sasl_secprops = 'noanonymous,noplain,maxssf=0'
>
>                 #  Seconds to wait for LDAP query to finish. default: 20
>                 res_timeout = 10
>
>                 #  Seconds LDAP server has to process the query
> (server-side
>                 #  time limit). default: 20
>                 #
>                 #  LDAP_OPT_TIMELIMIT is set to this value.
>                 srv_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 = 0x0028
>         }
>
>         #
>         #  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 = no
>
> #               ca_file = ${certdir}/cacert.pem
>
> #               ca_path = ${certdir}
> #               certificate_file = /path/to/radius.crt
> #               private_key_file = /path/to/radius.key
> #               random_file = /dev/urandom
>
>                 #  Certificate Verification requirements.  Can be:
>                 #    'never' (do not even bother trying)
>                 #    'allow' (try, but don't fail if the certificate
>                 #               cannot be verified)
>                 #    'demand' (fail if the certificate does not verify)
>                 #    'hard'  (similar to 'demand' but fails if TLS
>                 #             cannot negotiate)
>                 #
>                 #  The default is libldap's default, which varies based
>                 #  on the contents of ldap.conf.
>
> #               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 {
>                 #  Connections to create during module instantiation.
>                 #  If the server cannot create specified number of
>                 #  connections during instantiation it will exit.
>                 #  Set to 0 to allow the server to start without the
>                 #  directory being available.
>                 start = ${thread[pool].start_servers}
>
>                 #  Minimum number of connections to keep open
>                 min = ${thread[pool].min_spare_servers}
>
>                 #  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 = ${thread[pool].max_servers}
>
>                 #  Spare connections to be left idle
>                 #
>                 #  NOTE: Idle connections WILL be closed if "idle_timeout"
>                 #  is set.  This should be less than or equal to "max"
> above.
>                 spare = ${thread[pool].max_spare_servers}
>
>                 #  Number of uses before the connection is closed
>                 #
>                 #  0 means "infinite"
>                 uses = 0
>
>                 #  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 = 30
>
>                 #  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
>
>                 #  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.
>         }
> }
>
> ERROR received:
> (0)     if ( Airespace-Wlan-Id == 2 ) {
> (0)     if ( Airespace-Wlan-Id == 2 )  -> TRUE
> (0)     if ( Airespace-Wlan-Id == 2 )  {
> (0)       if ( "%{control:LDAP-UserDN}" =~ /ou=guest,ou=wifi,o=
> mydomain.com$/i
> ) {
> (0)       EXPAND %{control:LDAP-UserDN}
> (0)          --> uid=u5496622,ou=Techmahindra,ou=Partners,o= mydomain.com
> (0)       if ( "%{control:LDAP-UserDN}" =~ /ou=guest,ou=wifi,o=
> mydomain.com
> $/i )  -> FALSE
> (0)       elsif ( LDAP_Group == "cn=WiFiGuestPartners,ou=RADIUS
> Groups,ou=Groups,ou=staff,o=mydomain.com" ) {
> (0)       elsif ( LDAP_Group == "cn=WiFiGuestPartners,ou=RADIUS
> Groups,ou=Groups,ou=staff,o=mydomain.com )  -> FALSE
> (0)       else {
> (0)         [reject] = reject
> (0)       } # else = reject
> (0)     } # if ( Airespace-Wlan-Id == 2 )  = reject
> (0)   } # post-auth = reject
> (0) Using Post-Auth-Type Reject
>
> Probably, radius isn't able to glance into the LDAP group & search for uid.
> Perhaps, query syntax is wrong or incorrect.
>
> Could you please help with correct syntax..?
>
> ----
>
> *Thanks & Kind Regards,*
> Saurabh LAHOTI.
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/
> list/users.html


More information about the Freeradius-Users mailing list