Allow mschap_xlat to return the correctly formatted username when given
authormgriego <mgriego>
Mon, 17 Oct 2005 02:20:42 +0000 (02:20 +0000)
committermgriego <mgriego>
Mon, 17 Oct 2005 02:20:42 +0000 (02:20 +0000)
a User-Name in the format of host/fully.qualified.name.  A Windows domain
expects a machine name in the format of shortname$, ie the SAM version of
the account name.  mschap_xlat will also pull the first domain component
following the hostname a host/ formatted username and return that as the
NT-Domain xlat.  With these changes, the ntlm_auth command can be assured
to always have the correct formatting of the username for either user
authentication and machine authentication by simply passing the xlats of
%{mschap:User-Name} and %{mschap:NT-Domain}

src/modules/rlm_mschap/rlm_mschap.c

index 47ccd0f..169c633 100644 (file)
@@ -421,7 +421,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                 *      Pull the NT-Domain out of the User-Name, if it exists.
                 */
        } else if (strcasecmp(fmt, "NT-Domain") == 0) {
-               char *p;
+               char *p, *q;
 
                user_name = pairfind(request->packet->vps, PW_USER_NAME);
                if (!user_name) {
@@ -429,18 +429,39 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        return 0;
                }
                
-               p = strchr(user_name->vp_strvalue, '\\');
-               if (!p) {
-                       DEBUG2("  rlm_mschap: No NT-Domain was found in the User-Name.");
-                       return 0;
-               }
-
                /*
-                *      Hack.  This is simpler than the alternatives.
+                *      First check to see if this is a host/ style User-Name
+                *      (a la Kerberos host principal)
                 */
-               *p = '\0';
-               strNcpy(out, user_name->vp_strvalue, outlen);
-               *p = '\\';
+               if (strncmp(user_name->vp_strvalue, "host/", 5) == 0) {
+                       /*
+                        *      If we're getting a User-Name formatted in this way,
+                        *      it's likely due to PEAP.  The Windows Domain will be
+                        *      the first domain component following the hostname.
+                        */
+                       p = strchr(user_name->vp_strvalue, '.');
+                       p++;
+                       q = strchr(p, '.');
+                       /*
+                        * use the same hack as below
+                        */
+                       *q = '\0';
+                       strNcpy(out, p, outlen);
+                       *q = '.';
+               } else {
+                       p = strchr(user_name->vp_strvalue, '\\');
+                       if (!p) {
+                               DEBUG2("  rlm_mschap: No NT-Domain was found in the User-Name.");
+                               return 0;
+                       }
+
+                       /*
+                        *      Hack.  This is simpler than the alternatives.
+                        */
+                       *p = '\0';
+                       strNcpy(out, user_name->vp_strvalue, outlen);
+                       *p = '\\';
+               }
 
                return strlen(out);
 
@@ -456,14 +477,38 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        return 0;
                }
                
-               p = strchr(user_name->vp_strvalue, '\\');
-               if (p) {
-                       p++;    /* skip the backslash */
+               /*
+                *      First check to see if this is a host/ style User-Name
+                *      (a la Kerberos host principal)
+                */
+               if (strncmp(user_name->vp_strvalue, "host/", 5) == 0) {
+                       /*
+                        *      If we're getting a User-Name formatted in this way,
+                        *      it's likely due to PEAP.  When authenticating this against
+                        *      a Domain, Windows will expect the User-Name to be in the
+                        *      format of hostname$, the SAM version of the name, so we
+                        *      have to convert it to that here.  We do so by stripping
+                        *      off the first 5 characters (host/), and copying everything
+                        *      from that point to the first period into a string and appending
+                        *      a $ to the end.
+                        */
+                       p = strchr(user_name->vp_strvalue, '.');
+                       /*
+                        * use the same hack as above
+                        */
+                       *p = '\0';
+                       snprintf(out, outlen, "%s$", user_name->vp_strvalue + 5);
+                       *p = '.';
                } else {
-                       p = user_name->vp_strvalue; /* use the whole User-Name */
+                       p = strchr(user_name->vp_strvalue, '\\');
+                       if (p) {
+                               p++;    /* skip the backslash */
+                       } else {
+                               p = user_name->vp_strvalue; /* use the whole User-Name */
+                       }
+                       strNcpy(out, p, outlen);
                }
 
-               strNcpy(out, p, outlen);
                return strlen(out);
 
                /*