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; }