--- Makefile.in | 5 - auth_vmpop3d.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ auth_vmpop3d.h | 7 ++ mechanisms.c | 2 4 files changed, 184 insertions(+), 2 deletions(-) Index: cyrus-sasl-2.1.22/saslauthd/Makefile.in =================================================================== --- cyrus-sasl-2.1.22.orig/saslauthd/Makefile.in +++ cyrus-sasl-2.1.22/saslauthd/Makefile.in @@ -144,7 +144,8 @@ saslauthd_SOURCES = mechanisms.c globals auth_ldap.c auth_ldap.h cache.c cache.h cfile.c cfile.h \ krbtf.c krbtf.h utils.c utils.h \ ipc_unix.c ipc_doors.c saslauthd-main.c saslauthd-main.h \ - md5.c saslauthd_md5.h md5global.h + md5.c saslauthd_md5.h md5global.h \ + auth_vmpop3d.c auth_vmpop3d.h EXTRA_saslauthd_sources = getaddrinfo.c getnameinfo.c saslauthd_DEPENDENCIES = saslauthd-main.o @LTLIBOBJS@ @@ -178,7 +179,7 @@ am_saslauthd_OBJECTS = mechanisms.$(OBJE lak.$(OBJEXT) auth_ldap.$(OBJEXT) cache.$(OBJEXT) \ cfile.$(OBJEXT) krbtf.$(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) Index: cyrus-sasl-2.1.22/saslauthd/auth_vmpop3d.c =================================================================== --- /dev/null +++ cyrus-sasl-2.1.22/saslauthd/auth_vmpop3d.c @@ -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"); +} Index: cyrus-sasl-2.1.22/saslauthd/auth_vmpop3d.h =================================================================== --- /dev/null +++ cyrus-sasl-2.1.22/saslauthd/auth_vmpop3d.h @@ -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 *); Index: cyrus-sasl-2.1.22/saslauthd/mechanisms.c =================================================================== --- cyrus-sasl-2.1.22.orig/saslauthd/mechanisms.c +++ cyrus-sasl-2.1.22/saslauthd/mechanisms.c @@ -60,6 +60,7 @@ #ifdef AUTH_HTTPFORM #include "auth_httpform.h" #endif +#include "auth_vmpop3d.h" /* END PUBLIC DEPENDENCIES */ authmech_t mechanisms[] = @@ -93,6 +94,7 @@ authmech_t mechanisms[] = #ifdef AUTH_HTTPFORM { "httpform", auth_httpform_init, auth_httpform }, #endif /* AUTH_LDAP */ + { "vmpop3d", 0, auth_vmpop3d }, { 0, 0, 0 } };