= Configuring Authentication

== Testing

=== Authentication

Now in another terminal window run on the FreeRADIUS server to test authentication:

[source,shell]
----
cat <<'EOF' | radclient -x localhost auth testing123
User-Name = "john"
User-Password = "password"
EOF
----

==== Access-Accept

If this works you should see `radclient` report `Access-Accept` almostly immediately without delay:

[source,log]
----
Sent Access-Request Id 39 from 0.0.0.0:47493 to 127.0.0.1:1812 length 44
  User-Name = john
  User-Password = password
Received Access-Accept Id 39 from 127.0.0.1:1812 to 0.0.0.0:47493 via lo length 26
  User-Name = "john"
----

On the FreeRADIUS debug terminal side, you should see something like:

[source,log]
----
...
(0)    ldap - Reserved connection (0)
(0)    ldap - EXPAND (uid=%{%{Stripped-User-Name}:-%{User-Name}})
(0)    ldap - --> (uid=john)
(0)    ldap - Performing search in "dc=example,dc=com" with filter "(uid=john)", scope "sub"
(0)    ldap - Waiting for search result...
(0)    ldap - User object found at DN "uid=john,ou=people,dc=example,dc=com"
(0)    ldap - Processing user attributes
(0)    ldap -   &control.Password.With-Header += password
(0)    ldap - Released connection (0)
(0)    ldap (updated)
...
(0)    pap - No {...} in &Password.With-Header, re-writing to Password.Cleartext
(0)    pap - Normalized &control.Password.With-Header -> &control.Password.Cleartext
(0)    pap - Removing &control.Password.With-Header
(0)    pap - Setting &control.Auth-Type = pap
(0)    pap (updated)
(0)  } # recv Access-Request (updated)
(0)  Running 'authenticate pap' from file /usr/local/etc/raddb/sites-enabled/default
(0)  authenticate pap {
(0)    pap - Login attempt with password
(0)    pap - Comparing with "known-good" Password.Cleartext (8)
(0)    pap - User authenticated successfully
(0)    pap (ok)
(0)  } # authenticate pap (ok)
(0)  Running 'send Access-Accept' from file /usr/local/etc/raddb/sites-enabled/default
...
----

Here FreeRADIUS is describing what it did:

 . used the `ldap` module
 ** searched for `(uid=john)` in `dc=example,dc=com`
 *** this is doing the same as the following that you could run on the CLI
+
[source,shell]
----
ldapsearch -LL -H ldap://localhost -x -D cn=freeradius,dc=example,dc=com -w mypassword -b dc=example,dc=com '(uid=john)'
----
 ** found `uid=john,ou=people,dc=example,dc=com`
 *** if for you no user is found, but you know the user is in your directory, recheck the `user { ... }` section in `raddb/mods-available/ldap` as you may have a filter or attribute configuration set incorrectly
 ** found some useful attributes associated with that user
 *** the password which it placed into `control.Password.With-Header`
 *** as RADIUS attributes were changed, it returns `updated` as a result code to unlang
 . the module `pap` was used
 ** it found a suitable password to use in `&Password.With-Header`
 *** populates `&control.Password.Cleartext`
 *** the module decides it has everything it needs to do authentication so sets `&control.Auth-Type = pap`
 *** as RADIUS attributes were changed, it returns `updated` as a result code to unlang
 . the authenticate section runs and hands off to `pap` as `&control.Auth-Type = pap` was set earlier
 ** `&control.Password.Cleartext` is compared to `&request.User-Password`
 ** matches so `ok` is returned
 . we return `Access-Accept` as `ok` was returned to unlang

This worked as the LDAP credentials used by FreeRADIUS to connect to the LDAP server is able to extract a the `userPassword` attribute; as could been seen from the example `ldapsearch` command provided earlier.

==== `Access-Reject`

If this fails, the response will be delayed by one second and `Access-Reject` will be returned:

[source,shell]
----
Debug : Sent Access-Request Id 130 from 0.0.0.0:49353 to 127.0.0.1:1812 length 44
Debug : Received Access-Reject Id 130 from 127.0.0.1:1812 to 0.0.0.0:49353 via lo length 20
(0) -: Expected Access-Accept got Access-Reject
----

You should now look to the output of the debugging from the FreeRADIUS terminal window which may show something like:

[source,log]
----
(0)    ldap - Reserved connection (0)
(0)    ldap - EXPAND (uid=%{%{Stripped-User-Name}:-%{User-Name}})
(0)    ldap - --> (uid=john)
(0)    ldap - Performing search in "dc=example,dc=com" with filter "(uid=john)", scope "sub"
(0)    ldap - Waiting for search result...
(0)    ldap - User object found at DN "uid=john,ou=people,dc=example,dc=com"
(0)    ldap - Processing user attributes
(0)    ldap - Released connection (0)
(0)    ldap (ok)
(0)    expiration (noop)
(0)    pap - WARNING: No "known good" password found for the user.  Not setting Auth-Type
(0)    pap - WARNING: Authentication will fail unless a "known good" password is available
(0)    pap (noop)
(0)  } # recv Access-Request (ok)
(0)  ERROR: No Auth-Type available: rejecting the user.
(0)  Running 'send Access-Reject' from file /usr/local/etc/raddb/sites-enabled/default
----

Here FreeRADIUS describes it:

 . used the `ldap` module
 ** searched for `(uid=john)` in `dc=example,dc=com`
 ** found `uid=john,ou=people,dc=example,dc=com`
 ** did *not* find any useful attributes associated with that user
 ** module was successful in operation, but changed no RADIUS attributes so returns `ok`
 . the module `expiration` was used, but it had no effect (`noop`)
 . the module `pap` was used
 ** it finds no suitable password RADIUS attributes to use
 ** as it makes no changes, the module returns `noop`
 . no `Auth-Type` is set, so FreeRADIUS rejects the request (no even attempting to authenticate)
 . returns `Access-Reject`

This occurs as the LDAP credentials used by FreeRADIUS to connect to the LDAP server is *unable* to extract a the `userPassword` attribute; as could been seen from the example `ldapsearch` command provided earlier.

You have two options avaliable to you here (`Ctrl-C` the running FreeRADIUS server, make the change and restart):

 . change the permissions of the LDAP credentials used so that FreeRADIUS can read the LDAP `userPassword` attribute
 ** this is the recommended option
 ** fixing this, means you should see `Access-Accept` as described above
 . configure FreeRADIUS to attempt to 'bind' (LDAP language for 'login') as the user in the RADIUS request
 ** do this by editing `/usr/local/etc/raddb/sites-available/default`
 ** amend by adding after the call to `ldap` in `recv Access-Request { ... }` section, so that it looks like:
+
[source,unlang]
----
-ldap
if ((ok || updated) && &User-Password) {
  &control.Auth-Type := ldap
}
----
 ** FreeRADIUS is now configured to attempt to LDAP bind if the `ldap` module finds a user and the RADIUS request contains a `User-Password` RADIUS attribute

If you use LDAP bind'ing to perform user authentication, then when `radclient` receives `Accept-Accept', the FreeRADIUS debug terminal will look like:

[source,log]
----
(0)    ldap - Reserved connection (0)
(0)    ldap - EXPAND (uid=%{%{Stripped-User-Name}:-%{User-Name}})
(0)    ldap - --> (uid=john)
(0)    ldap - Performing search in "dc=example,dc=com" with filter "(uid=john)", scope "sub"
(0)    ldap - Waiting for search result...
(0)    ldap - User object found at DN "uid=john,ou=people,dc=example,dc=com"
(0)    ldap - Processing user attributes
(0)    ldap - Released connection (0)
(0)    ldap (ok)
(0)    if ((ok || updated) && &User-Password) {
(0)      &control.Auth-Type := ldap
(0)    } # if ((ok || updated) && &User-Password) (noop)
(0)    expiration (noop)
(0)    pap - WARNING: No "known good" password found for the user.  Not setting Auth-Type
(0)    pap - WARNING: Authentication will fail unless a "known good" password is available
(0)    pap (noop)
(0)  } # recv Access-Request (ok)
(0)  Running 'authenticate ldap' from file /usr/local/etc/raddb/sites-enabled/default
(0)  authenticate ldap {
(0)    ldap - Login attempt with password
(0)    ldap - Reserved connection (1)
(0)    ldap - Login attempt by "john"
(0)    ldap - Using user DN from request "uid=john,ou=people,dc=example,dc=com"
(0)    ldap - Waiting for bind result...
(0)    ldap - Bind successful
(0)    ldap - Bind as user "uid=john,ou=people,dc=example,dc=com" was successful
(0)    ldap - Released connection (1)
(0)    ldap (ok)
(0)  } # authenticate ldap (ok)
(0)  Running 'send Access-Accept' from file /usr/local/etc/raddb/sites-enabled/default
----

Here FreeRADIUS is describes it:

 . used the `ldap` module
 ** searched for `(uid=john)` in `dc=example,dc=com`
 ** found `uid=john,ou=people,dc=example,dc=com`
 ** did *not* find any useful attributes associated with that user
 ** module was successful in operation, but changed no RADIUS attributes so returns `ok`
 . `&control.Auth-Type := ldap` was set as the `ldap` module was successful in finding a user
 . the module `expiration` was used, but it had no effect (`noop`)
 . the module `pap` was used
 ** it finds no suitable password RADIUS attributes to use
 ** as it makes no changes, the module returns `noop`
 . the authenticate section runs and hands off to `ldap` as `&control.Auth-Type = ldap` was set earlier
 ** attemps to LDAP bind as `uid=john,ou=people,dc=example,dc=com`
 ** successful so `ok` is returned
 . we return `Access-Accept` as `ok` was returned to unlang
