[PATCH] mod_auth_ntlm_winbind - new feature to omit domain name from username

Michael Baltaks mbaltaks at gmail.com
Wed Apr 4 05:46:01 GMT 2007


Hi,

Here is a patch that adds a new feature to mod_auth_ntlm_winbind, that 
allows you to specify the domain separator (since winbindd also allows 
changing this character) and will strip the domain part from the username.

I've also reworded some debug statements to make them more clear and 
fixed the two compile warnings. This is because I'm working on a fix for 
reverse proxy mode, that still doesn't work quite right with a rewrite 
rule using look ahead to get the REMOTE_USER var. I've hacked it to work 
by checking the length of the parameter we're passing to ntlm_auth, and 
sending "YR" in front of parameters less than 50 chars (rather than the 
"KK" that is incorrectly happening), but this is clearly not the correct 
solution. The current code sends YR only when 
ctxt->connected_user_authenticated == NULL, but with look ahead, there 
is another case, but I've not yet found the right way to detect this.

-Michael.
-------------- next part --------------
Index: mod_auth_ntlm_winbind/mod_auth_ntlm_winbind.c
===================================================================
--- mod_auth_ntlm_winbind/mod_auth_ntlm_winbind.c	(revision 288)
+++ mod_auth_ntlm_winbind/mod_auth_ntlm_winbind.c	(working copy)
@@ -97,6 +97,8 @@
     char *ntlm_auth_helper;
     char *negotiate_ntlm_auth_helper;
     char *ntlm_plaintext_helper;
+    unsigned int omit_domain;
+    char * domain_separator;
 } ntlm_config_rec;
 
 /* A structure to hold per-connection information about authentications
@@ -194,6 +196,15 @@
                    (void *) APR_OFFSETOF(ntlm_config_rec, ntlm_basic_realm),
                    OR_AUTHCFG, "realm to use for Basic authentication" ),
 
+    AP_INIT_FLAG( "NTLMOmitDomain", ap_set_flag_slot,
+                  (void *) APR_OFFSETOF(ntlm_config_rec, omit_domain),
+                  OR_AUTHCFG,
+                  "set to 'on' to strip the domain name from the user name" ),
+
+    AP_INIT_TAKE1( "NTLMDomainSeparator", ap_set_string_slot,
+                   (void *) APR_OFFSETOF(ntlm_config_rec, domain_separator),
+                   OR_AUTHCFG, "the separator between domain and user name" ),
+
 #else
     /* NTLM authentication commands */
 
@@ -234,11 +245,20 @@
     { "NTLMBasicRealm", ap_set_string_slot,
       (void *) XtOffsetOf(ntlm_config_rec, ntlm_basic_realm),
       OR_AUTHCFG, TAKE1, "realm to use for Basic authentication" },
+
+    { "NTLMOmitDomain", ap_set_flag_slot,
+      (void *) XtOffsetOf(ntlm_config_rec, omit_domain),
+      OR_AUTHCFG, FLAG, "set to 'on' to strip the domain name from the user name" },
+
+    { "NTLMDomainSeparator", ap_set_string_slot,
+      (void *) XtOffsetOf(ntlm_config_rec, domain_separator),
+      OR_AUTHCFG, TAKE1, "the separator between domain and user name" },
 #endif
 
     { NULL }
 };
 
+
 /* both apache1 and apache2 use this to maintain per-child context */
 static ntlm_context_t global_ntlm_context;
 
@@ -290,6 +310,30 @@
 }
 #endif
 
+
+/* strip domain name from user name */
+char *
+strip_domain_name(request_rec * r, char * username)
+{
+    char * new_username = username;
+    ntlm_config_rec *crec = (ntlm_config_rec *)
+        ap_get_module_config(   r->per_dir_config,
+                                &auth_ntlm_winbind_module );
+    if (crec->omit_domain)
+    {
+        RDEBUG( "removing domain name from %s", username);
+        char *s = strstr(username, crec->domain_separator);
+        if (s)
+        {
+            RDEBUG( "user name without domain is %s", s + 1);
+            s++;
+            new_username = s;
+        }
+    }
+    return new_username;
+}
+
+
 /* helper function to pull out the context data */
 static ntlm_connection_context_t *get_connection_context( struct conn_rec *connection ) {
     ntlm_connection_context_t *retval = NULL;
@@ -408,7 +452,7 @@
 static int
 send_auth_reply(request_rec * r, const char *auth_scheme, const char *reply)
 {
-    RDEBUG( "sending back %s", reply );
+    RDEBUG( "sending to http client: %s", reply );
     /* Read negotiate from ntlm_auth */
 
     apr_table_setn(r->err_headers_out,
@@ -495,7 +539,7 @@
     char *newline;
     char args_to_helper[HUGE_STRING_LEN];
     char args_from_helper[HUGE_STRING_LEN];
-    unsigned int bytes_written;
+    apr_size_t bytes_written;
     int bytes_read;
 
     if (( global_ntlm_context.ntlm_plaintext_helper = get_auth_helper( r, global_ntlm_context.ntlm_plaintext_helper, crec->ntlm_plaintext_helper, CLEANUP(cleanup_ntlm_plaintext_helper))) == NULL ) {
@@ -505,7 +549,7 @@
     if ( ctxt->connected_user_authenticated == NULL ) {
         apr_pool_t *pool;
 
-        RDEBUG( "creating auth user" );
+        RDEBUG( "creating auth user for plaintext" );
 
 #ifdef APACHE2
         apr_pool_create_ex( &pool, r->connection->pool, NULL, NULL );
@@ -585,7 +629,7 @@
 
     if ( strncmp( args_from_helper, "OK", 2 ) == 0 ) {
         RDEBUG( "authentication succeeded!" );
-        ctxt->connected_user_authenticated->user = apr_pstrdup(ctxt->connected_user_authenticated->pool, user);
+        ctxt->connected_user_authenticated->user = apr_pstrdup(ctxt->connected_user_authenticated->pool, strip_domain_name(r, user) );
         ctxt->connected_user_authenticated->keepalives = r->connection->keepalives;
 #ifdef APACHE2
         r->user = ctxt->connected_user_authenticated->user;
@@ -624,7 +668,7 @@
     char args_to_helper[HUGE_STRING_LEN];
     char args_from_helper[HUGE_STRING_LEN];
     ntlm_connection_context_t *ctxt = get_connection_context( r->connection );
-    unsigned int bytes_written;
+    apr_size_t bytes_written;
     int bytes_read;
     struct _ntlm_auth_helper *auth_helper;
 
@@ -700,7 +744,7 @@
 #ifdef APACHE2
     apr_file_flush( auth_helper->proc->in );
 
-    RDEBUG( "parsing reply from helper to %s", args_to_helper );
+    RDEBUG( "sending to winbind via auth helper: %s", args_to_helper );
 
     if ( apr_file_gets(args_from_helper, HUGE_STRING_LEN, auth_helper->proc->out ) == APR_SUCCESS ) {
         bytes_read = strlen( args_from_helper );
@@ -738,7 +782,7 @@
         *newline = '\0';
     }
 
-    RDEBUG( "got response: %s", args_from_helper );
+    RDEBUG( "read from winbind via auth helper: %s", args_from_helper );
 
     /* inspect message type */
 
@@ -770,7 +814,7 @@
         if (strncmp(args_from_helper, "AF ", 3) == 0) {
             ctxt->connected_user_authenticated->user =
                 apr_pstrdup(ctxt->connected_user_authenticated->pool,
-                            childarg);
+                            strip_domain_name(r, childarg) );
             ctxt->connected_user_authenticated->keepalives =
                 r->connection->keepalives;
 #ifdef APACHE2
@@ -886,6 +930,8 @@
     crec->ntlm_auth_helper = "ntlm_auth --helper-protocol=squid-2.5-ntlmssp";
     crec->negotiate_ntlm_auth_helper = "ntlm_auth --helper-protocol=gss-spnego";
     crec->ntlm_plaintext_helper = "ntlm_auth --helper-protocol=squid-2.5-basic";
+    crec->omit_domain = 0;
+    crec->domain_separator = "\\";
 
     return crec;
 }
@@ -969,7 +1015,7 @@
 #endif
             return OK;
         } else {
-            RDEBUG( "reauth" );
+            RDEBUG( "client wishes to re-authenticate this TCP socket" );
             /* client wishes to re-authenticate this TCP socket */
             if ( ctxt->connected_user_authenticated->pool ) {
                 apr_pool_destroy(ctxt->connected_user_authenticated->pool);


More information about the samba-technical mailing list