Howdy!

Here is the patch file, for authlib/authmoduser.c that implements 
the "Carlos Paz <[EMAIL PROTECTED]> /etc/hosts.virtual "
approach to authentication via the authdaemon --> authmodules mechanism.

And, it fixes the Netscape Messenger login issue for vurtual domains.

------------------------------------------------------------------------------
It does the following things in roughly this order:

1. Checks to see if the AUTHTYPE is "login" (not cram or cram-md5)

2. Checks to see if there is an Netscape Messenger goofy chars. as 
    username--domain name separators, like ":" or "%" because
    Netscape 4.x Messenger e-Mail clients cannot handle fully
    specified username@domain constructs as the account name.

   If those constructions are encountered, this patch re-writes it
    to the correct "@" notation and passes it through for full authentication
    in any of the authentication modules.

3. If username portion of 'authdata' (during a "login") does NOT have
    an "@" separator, it is presumed to be a  locally hosted  e-Mail domain
    that CAN NOW HAVE a unique IP address assigned on the Courier
    machine.   NOTE" Most ISP's do this when hosting multiple domains
               so that reverse arp queries return the correct domain
               information, instead of some default machine name.

4. This patch then looks up the TCPLOCALIP address in a file "/etc/hosts.virtual"
    of the ASCII format:

        123.123.123.123 <TAB> domainname.tld
        456.456.456.456 <TAB> anotherdomain.tld
        .
        .
        321.321.321.321 <TAB> yetanothername.tld
        <BLANK>                                 end of file may be blank line

   The patch code then re-writes that username portion of the authdata record
    into a username@domain format, and passes it through the pipe connection
    to the authentication module(s) normally.

This patch has been tested with: 
        passwd, userdb and mysql authentication modules.
I have not had an opportunity to test it with postgres.

It has been tested with POP3, IMAP and IMAP-SSL,  but not POP3-SSL or LDAP.

The benefit of this patch is that legacy e-Mail implementations, especially
those that have suffered with Qmail IP based domains, can now easily be
upgraded to Courier. Fully specified "username@domain" logins are still
handled correctly, as should be the case.

System admins do NOT have to require their users (subscribers) to change anything
about their e-Mail account (login) so there is no trauma induced to the user base
and the risk of loosing clients is reduced. I needed this capability in order to
migrate 1500+ users, on 35+ domains away from Qmail+Vmailmgr to Courier.

My next project is to adapt 'Replex' (PHP4 script that manages MySQL userdb) to
the Courier way of doing things. This will more or less complete the tool set
so that e-Mail domains & user accounts can be set up and managed by sysadmin
and domain admin folks with very little intervention via Web interface.   Yeah!

Finally, one courier-users list member told me it "was not possible" to this.
Don't ever say that......Bill       (:-)

Randy
--- /tmp/courier-0.37.0/authlib/authmoduser.c   Thu Jan 31 10:00:45 2002
+++ courier-0.37.0/authlib/authmoduser.c        Thu Jan 31 10:13:57 2002
@@ -4,6 +4,8 @@
 */
 
 #include       "auth.h"
+#include       <stdio.h>
+#include       <errno.h>
 #include       "authmod.h"
 #include       "authwait.h"
 #include       <sys/types.h>
@@ -30,6 +32,14 @@
 char   *p;
 int    l;
 
+FILE           *ipmap; /* IP to domain name map file */
+char           *buffer;        /* some place to hold each entry */
+char           *newauth;       /* a place to use for re-write of username@ */
+char           *vuser; /* re-written name (if required) */
+char           *vpass;
+char           *charloc;       /* used for re-writing Netscape crap */
+char           *vdomain = 0;/* the domain name determined from TCPLOCALIP */
+
        signal(SIGCHLD, SIG_DFL);
 
        while (wait(&waitstat) >= 0)
@@ -44,8 +54,7 @@
                perror("pipe");
                authexit(1);
        }
-
-       while ((pid=fork()) == -1)
+    while ((pid = fork()) == -1) 
        {
                sleep(5);
        }
@@ -53,9 +62,10 @@
        if (pid)
        {
        char    *prog;
-       char    **argvec=authcopyargv(argc, argv, &prog);
+       char          **argvec = authcopyargv(argc, argv, &prog);
 
-               if (!prog)      authexit(1);
+       if (!prog)
+           authexit(1);
                close(3);
                dup(pipe3fd[0]);
                close(pipe3fd[0]);
@@ -66,22 +76,86 @@
        }
        close(3);
        close(pipe3fd[0]);
+    buf = malloc(strlen(service) + strlen(authtype) + strlen(authdata) + 128);
 
-       buf=malloc(strlen(service)+strlen(authtype)+strlen(authdata)+4);
-       if (!buf)
-       {
-               perror("malloc");
+    if (!buf) {
+       perror("malloc buf");
                authexit(1);
        }
-       sprintf(buf, "%s\n%s\n%s\n", service, authtype, authdata);
+    buffer = malloc(128);      /* for reading etc/hosts.vitual lines */
 
-       p=buf;
-       l=strlen(p);
-       while (l)
-       {
-       int     n=write(pipe3fd[1], p, l);
+    if (!buffer) {
+       perror("malloc buffer");
+       authexit(1);
+    }
+    newauth = malloc((strlen(service) + strlen(authtype) + strlen(authdata) + 128) * 
+2);
+
+    if (!newauth) {
+       perror("malloc newauth");
+       authexit(1);
+    }
+    strcpy(newauth, authdata); /* make working copy of authdata */
+
+    if (strspn(authtype, "login") == 5) {
+
+       vuser = malloc(strlen(authdata) + 128); /* extra workspace */
+
+       if (!vuser) {
+           perror("malloc vuser");
+           authexit(1);
+       }
+       vpass = malloc(strlen(authdata));       /* workspace */
+
+       if (!vpass) {
+           perror("malloc vpass");
+           authexit(1);
+       }
+       /*
+        * extract username from newauth (authdata copy)
+        * when authenticating, username is the first line of authdata
+        */
+
+       strcpy(vuser, strtok(newauth, "\n"));   /* parse it for vuser & vpass */
+       strcpy(vpass, strtok(NULL, "\n"));
+       strcpy(newauth, authdata);      /* restore working copy for later */
+
+       if ((charloc = strpbrk(vuser, ":%")))   /* re-write Netscape crap, if used */
+           *charloc = '@';
+
+       if ((!strchr(vuser, '@'))) {            /* authdata has been parsed, now check 
+vuser */
+
+           if ((p = getenv("TCPLOCALIP")) && (ipmap = fopen("/etc/hosts.virtual", 
+"r"))) {
+
+               while (fgets(buffer, 256, ipmap)) {     /* read a line */
+
+                   if (strcmp(strtok(buffer, " \t"), p) == 0) {        /* look for an 
+IP match */
+                       vdomain = strtok(NULL, " \t\r\n");      /* set vdomain to str
+                                                                * after separator */
+                       break;
+                   }
+               }
+               fclose(ipmap);
+
+
+               if ((vdomain) && (strlen(vuser) + strlen(vdomain) + 2 < 256)) {
+                   sprintf(buffer, "%s@%s", vuser, vdomain);
+
+                   strcpy(vuser, buffer);      /* now we have vuser@vdomain */
+               }
+           }
+       }
+       sprintf(newauth, "%s\n%s\n", vuser, vpass);
+    }                          /* else, this is not a login, just do w/o
+                                * mods */
+    sprintf(buf, "%s\n%s\n%s\n", service, authtype, newauth);
+
+    p = buf;
+    l = strlen(p);
+    while (l) {
+       int             n = write(pipe3fd[1], p, l);
 
-               if (n <= 0)     break;
+       if (n <= 0)
+           break;
                p += n;
                l -= n;
        }


Reply via email to