diff -ruN cyrus-sasl-2.1.18/saslauthd/Makefile.in cyrus-sasl-vmpop-2.1.18/saslauthd/Makefile.in --- cyrus-sasl-2.1.18/saslauthd/Makefile.in 2004-03-10 16:56:16.000000000 +0100 +++ cyrus-sasl-vmpop-2.1.18/saslauthd/Makefile.in 2004-03-14 14:44:23.000000000 +0100 @@ -141,6 +141,7 @@ auth_sia.h auth_sasldb.c auth_sasldb.h lak.c lak.h \ auth_ldap.c auth_ldap.h cache.c cache.h utils.c utils.h \ ipc_unix.c ipc_doors.c saslauthd-main.c saslauthd-main.h \ + auth_vmpop3d.c auth_vmpop3d.h \ md5.c saslauthd_md5.h md5global.h EXTRA_saslauthd_sources = getaddrinfo.c getnameinfo.c @@ -174,7 +175,7 @@ auth_sia.$(OBJEXT) auth_sasldb.$(OBJEXT) lak.$(OBJEXT) \ auth_ldap.$(OBJEXT) cache.$(OBJEXT) utils.$(OBJEXT) \ ipc_unix.$(OBJEXT) ipc_doors.$(OBJEXT) saslauthd-main.$(OBJEXT) \ - md5.$(OBJEXT) + auth_vmpop3d.$(OBJEXT) md5.$(OBJEXT) saslauthd_OBJECTS = $(am_saslauthd_OBJECTS) saslauthd_LDFLAGS = am_saslcache_OBJECTS = saslcache.$(OBJEXT) diff -ruN cyrus-sasl-2.1.18/saslauthd/auth_vmpop3d.c cyrus-sasl-vmpop-2.1.18/saslauthd/auth_vmpop3d.c --- cyrus-sasl-2.1.18/saslauthd/auth_vmpop3d.c 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-sasl-vmpop-2.1.18/saslauthd/auth_vmpop3d.c 2004-03-14 17:14:01.000000000 +0100 @@ -0,0 +1,172 @@ +/* COPYRIGHT + * Copyright (c) 1997-2000 Messaging Direct Ltd. + * All rights reserved. + * + * auth methods taken from vm-pop3d-1.1.6, so i guess this makes this gpl + * it works on my computer (virtual and shadow users) - domen@coderock.org + * + * END COPYRIGHT */ + +#define _GNU_SOURCE +#include "mechanisms.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define RETURN(x) return strdup(x) + +#define VIRTUAL_PASSWORDS_PATH "/etc/virtual" +#define VIRTUAL_PASSWORD_FNAME "passwd" + +/* The following should probably try to use some system defaults. */ +#define MAX_USERNAME_LENGTH 128 +#define MAX_PASSWORD_LENGTH 128 + +/* the following is just used by C preprocessor to stringify numbers */ +#define SNUMBER_(a) #a +#define SNUMBER(a) SNUMBER_(a) + +struct passwd global_pwdentry; +char global_pwdentry_pw_name[MAX_USERNAME_LENGTH + 1]; +char global_pwdentry_pw_passwd[MAX_PASSWORD_LENGTH + 1]; + +struct passwd *getvirtualpwnam(const char *username, + const char *domainname) +{ + FILE *passwdfd; + char buffer[256]; + struct passwd *pwdentry = &global_pwdentry; + int found = 0; + + /* return a pointer to an internal static object */ + pwdentry->pw_name = global_pwdentry_pw_name; + pwdentry->pw_passwd = global_pwdentry_pw_passwd; + + snprintf(buffer, 256, "%s/%s/%s", + VIRTUAL_PASSWORDS_PATH, domainname, + VIRTUAL_PASSWORD_FNAME); + + if ((passwdfd = fopen(buffer, "r")) == (FILE *) NULL) { + syslog(LOG_ERR, "Couldn't open password file: %s", buffer); + return (0); + } + while (fgets(buffer, sizeof(buffer), passwdfd) != (char *) NULL) { + + /* skip comments, blank lines */ + if (*buffer == '#' || *buffer == '\n' || *buffer == '\0') { + continue; + } + if (sscanf(buffer, + "%" SNUMBER(MAX_USERNAME_LENGTH) "[^:]:" + "%" SNUMBER(MAX_PASSWORD_LENGTH) "[^:\n]", + pwdentry->pw_name, pwdentry->pw_passwd) != 2) { + /* fprintf (stderr, "%s: Trouble parsing passwd file\n", buffer); */ + continue; + } + if (strcmp(pwdentry->pw_name, username) == 0) { + found = 1; + break; + } + } + + (void) fclose(passwdfd); /* what should I do? Log if it doesn't + * close? */ + if (found) + return (pwdentry); + else + return (0); +} + + +int pass_ok(const char *arg, const char *domainname, const char *pass) +{ + struct passwd *pw = NULL; + + if (domainname) { + pw = getvirtualpwnam(arg, domainname); + + if (pw == NULL) { +#ifdef DEBUG + if (debug > 3) + syslog(LOG_INFO, + "Non-existent user: %s (%s)", arg, + domainname); +#endif + return 0; + } + if (strcmp(pw->pw_passwd, crypt(pass, pw->pw_passwd))) + return 0; + } else { /* no domain part so revert to normal */ + pw = getpwnam(arg); + + if (pw == NULL) { +#ifdef DEBUG + if (debug > 3) + syslog(LOG_INFO, "Non-existent user: %s", + arg); +#endif + return 0; + } + if (strcmp(pw->pw_passwd, crypt(pass, pw->pw_passwd))) { + struct spwd *spw; + + spw = getspnam(arg); + if (spw == NULL) + return 0; + if (strcmp + (spw->sp_pwdp, crypt(pass, spw->sp_pwdp))) + return 0; + } + } + return 1; +} + + +char * /* R: allocated response string */ +auth_vmpop3d( + const char *login, /* I: plaintext authenticator */ + const char *password, /* I: plaintext password */ + const char *service __attribute__ ((unused)), + const char *realm __attribute__ ((unused)) + ) +{ + int status; + char *arg = login; + char *temp_domain; + const char domain_delimiters[] = ";!:@"; + int i; + + char *virtualdomain = NULL; + + /* Some mail clients pre-parse out the username before sending */ + /* so allow colon or at-sign to separate username and domain name */ + + for (i = strlen(domain_delimiters) - 1; i >= 0; i--) { + temp_domain = strchr(arg, domain_delimiters[i]); + if (temp_domain) { + temp_domain++; + virtualdomain = strdup(temp_domain); + arg = strtok(arg, domain_delimiters); + break; + } + } + + status = pass_ok(arg, virtualdomain, password); + if (virtualdomain) { + free(virtualdomain); + virtualdomain = NULL; + } + + + if (status) + RETURN("OK"); + else + RETURN("NO"); +} diff -ruN cyrus-sasl-2.1.18/saslauthd/auth_vmpop3d.h cyrus-sasl-vmpop-2.1.18/saslauthd/auth_vmpop3d.h --- cyrus-sasl-2.1.18/saslauthd/auth_vmpop3d.h 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-sasl-vmpop-2.1.18/saslauthd/auth_vmpop3d.h 2004-03-14 14:31:42.000000000 +0100 @@ -0,0 +1,7 @@ +/* COPYRIGHT + * Copyright (c) 1997 Messaging Direct Ltd. + * All rights reserved. + * + * END COPYRIGHT */ + +char *auth_vmpop3d(const char *, const char *, const char *, const char *); diff -ruN cyrus-sasl-2.1.18/saslauthd/mechanisms.c cyrus-sasl-vmpop-2.1.18/saslauthd/mechanisms.c --- cyrus-sasl-2.1.18/saslauthd/mechanisms.c 2002-05-17 18:53:37.000000000 +0200 +++ cyrus-sasl-vmpop-2.1.18/saslauthd/mechanisms.c 2004-03-14 13:31:09.000000000 +0100 @@ -57,6 +57,7 @@ #ifdef AUTH_LDAP #include "auth_ldap.h" #endif +#include "auth_vmpop3d.h" /* END PUBLIC DEPENDENCIES */ authmech_t mechanisms[] = @@ -87,6 +88,7 @@ #ifdef AUTH_LDAP { "ldap", auth_ldap_init, auth_ldap }, #endif /* AUTH_LDAP */ + { "vmpop3d", 0, auth_vmpop3d }, { 0, 0, 0 } };