diff -ruN popa3d-0.4/Makefile popa3d-0.4-ldapauth/Makefile --- popa3d-0.4/Makefile Mon Jan 31 22:56:46 2000 +++ popa3d-0.4-ldapauth/Makefile Wed Sep 5 01:39:58 2001 @@ -1,9 +1,9 @@ CC = gcc LD = gcc RM = rm -f -CFLAGS = -c -Wall -O2 -fomit-frame-pointer -LDFLAGS = -s -#LDFLAGS = -s -lcrypt +CFLAGS = -c -Wall -g #-fomit-frame-pointer +LDFLAGS = -g +LDFLAGS = -g -lcrypt -lldap -llber PROJ = popa3d OBJS = md5/md5.o \ diff -ruN popa3d-0.4/mailbox.c popa3d-0.4-ldapauth/mailbox.c --- popa3d-0.4/mailbox.c Wed Mar 24 23:25:55 1999 +++ popa3d-0.4-ldapauth/mailbox.c Wed Sep 5 01:50:44 2001 @@ -280,9 +280,15 @@ mailbox_fd = -1; - pathname = malloc(strlen(MAIL_SPOOL_PATH) + strlen(mailbox) + 2); - if (!pathname) return 1; - sprintf(pathname, "%s/%s", MAIL_SPOOL_PATH, mailbox); + if(*mailbox == '/') { + pathname = malloc(strlen(mailbox)+1); + if (!pathname) return 1; + sprintf(pathname, "%s", mailbox); + } else { + pathname = malloc(strlen(MAIL_SPOOL_PATH) + strlen(mailbox) + 2); + if (!pathname) return 1; + sprintf(pathname, "%s/%s", MAIL_SPOOL_PATH, mailbox); + } if (lstat(pathname, &stat)) { free(pathname); diff -ruN popa3d-0.4/params.h popa3d-0.4-ldapauth/params.h --- popa3d-0.4/params.h Tue Feb 1 01:16:24 2000 +++ popa3d-0.4-ldapauth/params.h Mon Sep 10 22:04:57 2001 @@ -59,10 +59,22 @@ #define MAX_MAILBOX_BYTES 100000000 /* + * Authentication support for virtual domains defined on an LDAP server. + */ + +#define AUTH_LDAP 1 +#define AUTH_LDAP_SERVER "127.0.0.1" +#define AUTH_LDAP_BINDDN_TEMPLATE "uid=%s,dc=%s,o=top" +#define AUTH_LDAP_FORCE_UGID 0 +#define AUTH_LDAP_UID 8 +#define AUTH_LDAP_GID 12 + +/* * Do we have shadow passwords? (Not for *BSD.) * Note: password aging is not supported. */ -#define AUTH_SHADOW 1 + +#define AUTH_SHADOW 0 /* * A salt used to waste some CPU time on dummy crypt(3) calls and make @@ -81,7 +93,7 @@ * Your mail spool directory. Note: only local (non-NFS) mode 775 mail * spools are currently supported. */ -#define MAIL_SPOOL_PATH "/var/spool/mail" +#define MAIL_SPOOL_PATH "/opt/mailspool" /* * How do we talk to syslogd? These should be fine for most systems. diff -ruN popa3d-0.4/pop_root.c popa3d-0.4-ldapauth/pop_root.c --- popa3d-0.4/pop_root.c Tue Feb 1 01:18:12 2000 +++ popa3d-0.4-ldapauth/pop_root.c Mon Sep 10 22:18:37 2001 @@ -21,7 +21,9 @@ #include "pop_auth.h" #include "pop_trans.h" -#if AUTH_SHADOW +#if AUTH_LDAP +#include +#elif AUTH_SHADOW #include #ifdef __GLIBC__ #include @@ -73,7 +75,104 @@ return offset; } -#if AUTH_SHADOW +#if AUTH_LDAP +/* + * Basic LDAP authenticator. + * Supports virtual domains, doesn't support groups + */ +char mailboxpath[AUTH_BUFFER_SIZE]; + +static int ldap_get_uidgid(LDAP *l, char *ldap_binddn, uid_t *uid, gid_t *gid) +{ + char *attrs[3] = { NULL, NULL, NULL}; + char **val; + LDAPMessage *elem; + BerElement *cookie; + LDAPMessage *msg; + char *ap; + + attrs[0] = "uidNumber"; + attrs[1] = "gidNumber"; + if(ldap_search_s(l, ldap_binddn, LDAP_SCOPE_BASE, "(objectClass=person)", attrs, 0, &msg) != LDAP_SUCCESS) + return 1; + + if(!(elem = ldap_first_entry(l, msg))) { + ldap_msgfree(msg); + return 1; + } + + if(!(ap = ldap_first_attribute(l, elem, &cookie))) { + ldap_msgfree(msg); + ldap_msgfree(elem); + return 1; + } + + if(!(val = ldap_get_values(l, elem, ap))) { + ldap_msgfree(msg); + ldap_msgfree(elem); + return 1; + } + + *uid = atoi(val[0]); + ldap_value_free(val); + + if(!(ap = ldap_next_attribute(l, elem, cookie))) { + ldap_msgfree(msg); + ldap_msgfree(elem); + return 1; + } + + if(!(val = ldap_get_values(l, elem, ap))) { + ldap_msgfree(msg); + ldap_msgfree(elem); + return 1; + } + + *gid = atoi(val[0]); + + ldap_value_free(val); + ldap_msgfree(msg); + return 0; +} + +static struct passwd *do_ldap_auth(char *user, char *pass) +{ + char ldap_binddn[AUTH_BUFFER_SIZE]; + char *t; + LDAP *l; + struct passwd *pw; + + if(!(t = index(user, '@'))) + return NULL; + *t++ = '\0'; + + if(!(l = ldap_init(AUTH_LDAP_SERVER, LDAP_PORT))) + return NULL; + + snprintf(ldap_binddn, AUTH_BUFFER_SIZE, AUTH_LDAP_BINDDN_TEMPLATE, user, t); + if(ldap_simple_bind_s(l, ldap_binddn, pass) != LDAP_SUCCESS) + return NULL; + + /* + * to avoid static strings, we query on the popa3d user and + * overwrite the uid/gid fields. + */ + + if(!(pw = getpwnam(POP_USER))) + return NULL; + snprintf(mailboxpath, AUTH_BUFFER_SIZE, "%s/%s/%s", MAIL_SPOOL_PATH, t, user); + mailbox = mailboxpath; + +#if AUTH_LDAP_FORCE_UGID + pw->pw_uid = AUTH_LDAP_UID; + pw->pw_gid = AUTH_LDAP_GID; +#else + ldap_get_uidgid(l, ldap_binddn, &pw->pw_uid, &pw->pw_gid); +#endif + return pw; +} + +#elif AUTH_SHADOW /* * The /etc/shadow authentication routine. This one is really tricky, * in order to make sure we don't have an /etc/shadow fd or sensitive @@ -180,7 +279,9 @@ user = auth; pass = &user[strlen(user) + 1]; -#if AUTH_SHADOW +#if AUTH_LDAP + if (!(pw = do_ldap_auth(user, pass))) return AUTH_FAILED; +#elif AUTH_SHADOW if (!(pw = do_shadow_auth(user, pass))) return AUTH_FAILED; #else if (!(pw = do_passwd_auth(user, pass))) return AUTH_FAILED;