Case insensitive username

Alan DeKok aland at deployingradius.com
Fri May 13 13:08:30 UTC 2022


On May 13, 2022, at 8:44 AM, Simon Dankau <SDankau at rf-computer.de> wrote:
> Our users are logging in via LDAP. I´ve seen that the file "ldap" has some filter rules.
> 
> # filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
> filter = "(uid=%{mschap:User-Name:-%%{User-Name}})"

  The default filter is the first one.  Changing it to mschap likely isn't correct.

> I´ve activated the first one without mschap and the variations with tolower -> filter = "(uid=%{mschap:User-Name:-%{tolower:%{User-Name}}})"

  That should work.  Or just lowercase the whole thing:

	filter = "(uid=%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}})"

> After starting freeradius in the debug mode i saw a configuration file that contains the attribute case_sensitive. That  file "is called radutmp". But from my understanding of the file description that file is only for some sort of logging. To see who is logged in and some other stuff.

  Yes.  Configuration for one module doesn't affect another module.

> After testing the the login while in debug mode, the error message stays the same. I´ve added the debug messages.

  That's good.

> You can see that the username is affected from the tolower in the server configuration in the authorize section. The problem lies with the ldap. The uid of the user stays as the normal input and seems not to be affected by the tolower string.

  The server is printing out what it got from LDAP.

> LDAP somehow has no problem with it, because an user object is found with the right name. But it somehow can´t change the username in the request while searching the groups.

  Because it gets an LDAP user DN from the first LDAP search, which it then uses for the group lookups.  That LDAP user DN comes from LDAP.

  So... how are the user names stored in LDAP?  Lowercase?

> I hope my bad english is understandable. 

  Your English is fine.

> Received Access-Request Id 51 from 10.11.100.31:45609 to 10.11.100.31:1812 length 74
> (1)   User-Name = "Test"
> (1)   User-Password = "start12K"
> (1)   NAS-IP-Address = 10.11.100.31
> (1)   NAS-Port = 10
> (1)   Message-Authenticator = 0x4098a526c0098b192ce7ac66a620125f

  That's good...

> (1)     update request {
> (1)       EXPAND %{tolower:%{User-Name}}
> (1)          --> test
> (1)       Stripped-User-Name := test

  You're setting that, but not using it anywhere.  This doesn't seem right.  Just delete this.

> (1) ldap: EXPAND (uid=%{mschap:User-Name:-%{tolower:%{User-Name}}})
> (1) ldap:    --> (uid=Test)

  Because of the %{mschap:User-Name} expansion.  Don't do that.  Just do:

	filter = "(uid=%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}})"

> (1) ldap: Performing search in "dc=my,dc=bkrnet,dc=de" with filter "(uid=Test)", scope "sub"
> (1) ldap: Waiting for search result...
> (1) ldap: User object found at DN "uid=TEST,cn=lehrer,cn=users,ou=bkrheine,dc=my,dc=bkrnet,dc=de"

  That is information which is coming from LDAP.  Go check LDAP.  The user name in LDAP is "TEST".  Not "test".

  And also the LDAP database is doing case insensitive name comparisons.  You ask it for "Test", and it returns user "TEST".

  So at least part of the problem here is that you're not really clear on what the problem is.  You think it's that the name checks are case sensitive, but they're not.

  And then in an attempt to fix this, you're trying a bunch of random things, without being clear on what you're changing or why.

> (1) pap: Converted: &control:Password-With-Header -> &control:Crypt-Password
> (1) pap: Removing &control:Password-With-Header
> (1) pap: Normalizing NT-Password from hex encoding, 32 bytes -> 16 bytes
> (1)     [pap] = updated
> (1)   } # authorize = updated
> (1) Found Auth-Type = PAP
> (1) # Executing group from file /etc/freeradius/3.0/sites-enabled/VPN
> (1)   Auth-Type PAP {
> (1) pap: Login attempt with password
> (1) pap: Comparing with "known-good" NT-Password
> (1) pap: User authenticated successfully

  That's good.

> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=schueler-bkrheine))}") {
> rlm_ldap (ldap): Reserved connection (4)
> (1)     Performing search in "dc=my,dc=bkrnet,dc=de" with filter "(&(memberUid=test)(cn=schueler-bkrheine))", scope "sub"
> (1)     Waiting for search result...
> (1)     Search returned no results
> rlm_ldap (ldap): Released connection (4)
> (1)     EXPAND %{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=schueler-bkrheine))}
> (1)        --> 
> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=schueler-bkrheine))}")  -> FALSE

  You can run those queries manually via "ldapsearch" to verify what they do.  See the documentation in mods-available/ldap.

> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=lehrer-bkrheine))}") {
> rlm_ldap (ldap): Reserved connection (0)
> (1)     Performing search in "dc=my,dc=bkrnet,dc=de" with filter "(&(memberUid=test)(cn=lehrer-bkrheine))", scope "sub"
> (1)     Waiting for search result...
> (1)     Search returned no results
> rlm_ldap (ldap): Released connection (0)
> (1)     EXPAND %{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=lehrer-bkrheine))}
> (1)        --> 
> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=lehrer-bkrheine))}")  -> FALSE
> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=admins-bkrheine))}") {
> rlm_ldap (ldap): Reserved connection (5)
> (1)     Performing search in "dc=my,dc=bkrnet,dc=de" with filter "(&(memberUid=test)(cn=admins-bkrheine))", scope "sub"
> (1)     Waiting for search result...
> (1)     Search returned no results
> rlm_ldap (ldap): Released connection (5)
> (1)     EXPAND %{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=admins-bkrheine))}
> (1)        --> 
> (1)     elsif ("%{ldap:ldap:///dc=my,dc=bkrnet,dc=de?cn?sub?(&(memberUid=%{User-Name})(cn=admins-bkrheine))}")  -> FALSE
> (1)     else {
> (1)       update reply {
> (1)         Reply-Message := "DEBUG: Not found, reject"

 i.e. the "test' user isn't in any of the groups.   And you configured the server to reject users who aren't in any of those groups.

  So FreeRADIUS is doing exactly what you told it to do.

  If you want an Access-Accept, put the "test" user into one of the groups.

  Once that works, you can go check real user accounts.   Tests are nice, but they're not always the same was what is coming in for real users.
  
  Alan DeKok.



More information about the Freeradius-Users mailing list