So I'm working on a way to Improve the User Experience.  I've gotten a LONG 
way, but now I'm stuck.  Here's the short/long version (all details, without 
undue explanation or discussion of what I tried that doesn't work):

WARNING:  This may well be a case of doing it the hard way.  If that's the 
case, feel free to tell me, but it's not for lack of trying to research this 
via Google, searching archives of this list, etc.  Just tell me what I'm doing 
wrong.  I can handle it.  ;)

Okay, here goes:

1)  I created two custom attributes named "My-NT-Domain" and "My-User-Name" and 
added them to the dictionary file as 3003 and 3004, respectively.

2)  I added sections to sites-enabled/my-virt-server in the "authorize {" like 
this:

        # Allow host-based authentication for computers in the domain.
        if ( User-Name =~ /host\/[^\.]+\.(.+)/ ) {
                update request {
                        My-User-Name = "%{mschap:User-Name}"
                        My-NT-Domain = "%{1}"
                }
        }
        # Fix the forward slash.
        elsif ( User-Name =~ /([^\/]+)\/(.+)/ ) {
                update request {
                        My-User-Name = "%{2}"
                        My-NT-Domain = "%{1}"
                }
        }
        # New student e-mail format.
        elsif ( User-Name =~ /([^@]+)@mail.missouri.edu/ ) {
                update request {
                        My-User-Name = "%{1}"
                        My-NT-Domain = "TIGERS"
                }
        }

... and so on.

3)  I changed /etc/raddb/modules/mschap to call ntlm_auth like this:

ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key 
--username=%{%{My-User-Name}:-%{mschap:User-Name}} 
--domain=%{%{My-NT-Domain}:-%{mschap:NT-Domain}} 
--challenge=%{mschap:Challenge:-00} --nt-response=%{mschap:NT-Response:-00}"


So at this point, if a user plugs in the correct "domain\username" stuff, none 
of the "cleanup" cases match, so my custom attributes are empty, and the usual 
%{mschap:xx} variables work fine.  If fixes were necessary, the custom 
attributes take over.

All that works fine.

NOW we want to be able to have a user authenticate without specifying a domain. 
 In theory, that's no big deal.  If the users NEVER specify a domain at all, I 
can populate my custom attributes with this:

        if ( ! My-NT-Domain ) {
                    update request {
                            My-User-Name = "%{User-Name}"
                            My-NT-Domain = `/etc/raddb/bin/GetDomain.pl 
%{User-Name}`
                    }
        }

The "GetDomain.pl" script does a command-line LDAP search (using "ldapsearch") 
against our AD for %{User-Name}, grabs the dn attribute, matches the AD domain, 
and returns the NT domain that corresponds.  This also works.

NOW, the problem is that if the user DOES specify "domain\username" correctly, 
then none of the "cleanup" cases match, so My-NT-Domain is empty.  But since my 
custom attribute is empty, the Perl script is being called unnecessarily to run 
the LDAP search.

Solution:

I was still thinking about this as I wrote it, and I modified the "final check" 
clause (that looks for the total absence of domain hints) and I thought of a 
way to implicitly resolve the case where the user passes scary characters in 
the user ID (injection attack) AND the case where the user specified a valid 
domain\username set of creds at the same time:

# Check special fix-it cases above.
# These could probably be done as a single if statement.
# It was simpler to keep them separate while testing.
  if ( ! My-NT-Domain ) {
                if ( User-Name =~ /^[a-zA-Z0-9]+$/ ) {
                        update request {
                                My-User-Name = "%{User-Name}"
                                My-NT-Domain = `/etc/raddb/bin/GetDomain.pl 
%{User-Name}`
                        }
          }
  }


This appears to be working.

Overall, I give this solution about a B+.

PROS:
Works in a single forest, multi-domain environment, regardless of any 
conformity to typical AD domain naming standards.
Makes authentication SIMPLE for the users.
The way I wrote the GetDomain script, it always returns DOMAIN or (null) after 
only a single LDAP query (efficient).
Combined with judicious use of "radiusd -XC" provides a simple way to correct 
common typos.
Permits computer-based authentication to work again in multi-domain or 
non-typical-naming cases (where mschap currently fails).
Still reports the original creds as given by user (in case you still want to 
report on the cases that needed fixing and resolve the problem at the source, 
rather than making FR do all the work.
Limited to this virtual server.

CONS:
In many cases - like translating "col.missouri.edu" to "UMC-USERS", the "fixes" 
are hard-coded.  By comparison, changing the / to a \ works for any domain in a 
single check.
Doubles (at least) the number of calls to AD in cases where everyone is lazy 
and leaves out the domain.  I.e. an LDAP call to get the domain plus the 
authentication itself.
Encourages user ignorance.  (Judgement call.)
Limited to this virtual server.


Thoughts?  Opinions?  Better ways to accomplish any/all of this?

--J

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

Reply via email to