Index: Makefile =================================================================== RCS file: /cvsroot/vimap/vimap/Makefile,v retrieving revision 1.1.1.6 retrieving revision 1.7 diff -c -r1.1.1.6 -r1.7 *** Makefile 12 Jun 2003 06:58:58 -0000 1.1.1.6 --- Makefile 12 Jun 2003 07:06:41 -0000 1.7 *************** *** 110,115 **** --- 110,117 ---- # uw2 UnixWare SVR4.2 # vul VAX Ultrix # vu2 VAX Ultrix 2.3 (e.g. for VAXstation-2000 or similar old version) + # lnv Added by Patrik Hall , both pam and crypt + # authentication to support linuxconf virtual domains # Extra authenticators (e.g. OTP, Kerberos, etc.). Adds linkage for *************** *** 269,275 **** # Note on SCO you may have to set LN to "ln". ! a32 a41 aix bs3 bsf bsi bso d-g d54 do4 drs epx gas gh9 ghp ghs go5 gsc gsg gso gul hpp hpx lnp lyn mct mnt neb nec nto nxt nx3 osf os4 ptx qnx sc5 sco sgi sg6 shp sl4 sl5 slx snx sol sos uw2: an $(BUILD) BUILDTYPE=$@ # If you use sv4, you may find that it works to move it to use the an process. --- 271,277 ---- # Note on SCO you may have to set LN to "ln". ! a32 a41 aix bs3 bsf bsi bso d-g d54 do4 drs epx gas gh9 ghp ghs go5 gsc gsg gso gul hpp hpx lnp lyn mct mnt neb nec nto nxt nx3 osf os4 ptx qnx sc5 sco sgi sg6 shp sl4 sl5 slx snx sol sos uw2 lnv: an $(BUILD) BUILDTYPE=$@ # If you use sv4, you may find that it works to move it to use the an process. Index: README =================================================================== RCS file: /cvsroot/vimap/vimap/README,v retrieving revision 1.1.1.3 retrieving revision 1.5 diff -c -r1.1.1.3 -r1.5 *** README 17 Dec 2002 10:34:04 -0000 1.1.1.3 --- README 28 Apr 2003 14:42:54 -0000 1.5 *************** *** 51,53 **** --- 51,91 ---- The focus of development and support is for UNIX and Win32 (including Windows 95/98/Millenium, Windows NT, and Windows 2000). The other ports are not frequently used or tested, and may be incomplete. + + + --- + + + Addition to imap-2002 by Patrik Hall + ------------------------------------------------------------------------- + + This release of imap-2002 has support for linuxconf Virtual Pop-users. + Linuxconf offers a way to define users for virtual domains by storing + passwd entries in directory /etc/vmail/passwd.domain.com , shadow entries + in /etc/vmail/shadow.domain.com and aliases in + /etc/vmail/aliases.domain.com Inbox is stored in + /var/spool/vmail/domain.com/username and home directory in + /vhome/domain.com/home/username. Home directory however is parsed from the + passwd entry of the user. + + Passwords are stored using standard crypt()-encapsulation, no matter what + kind the system uses for regular accounts. This means that PAM + authentication is used for regular users and standard authentication for + virtual users. + + This release of imap supports two ways of determining use of virtual + domain. If the client connects to imap using other IP than main system, + the domainname is parsed from the hostname of the IP. If the IP resolvs to + mail.domain.com, imap checks if /etc/vmail/passwd.mail.domain.com exists + to validate if the domainname is ok. If not, /etc/vmail/passwd.domain.com + is also checked. If both fails main domain is used. This functionality is + aimed to be identical to vpop3d bundled with linuxconf. + + Users can also enter "user@domain.com" as username to imap. imap will then + use corresponding domainname. This enables use of virtual domains with one + single IP. Aliases are also solved to account level, making it possible to + use both the username@domain.com and Full.Username@domain.com if + Full.Username is mapped to username in aliases file. + + Some versions of Netscape will not work with "@"-character in username + field, "#"-character as well as "/"-character can also be used. Index: src/c-client/mail.h =================================================================== RCS file: /cvsroot/vimap/vimap/src/c-client/mail.h,v retrieving revision 1.1.1.7 retrieving revision 1.7 diff -c -r1.1.1.7 -r1.7 *** src/c-client/mail.h 12 Jun 2003 06:59:01 -0000 1.1.1.7 --- src/c-client/mail.h 12 Jun 2003 07:06:42 -0000 1.7 *************** *** 138,143 **** --- 138,145 ---- #define SET_MAILSUBDIR 220 #define GET_DISABLE822TZTEXT 221 #define SET_DISABLE822TZTEXT 222 + #define GET_DOMAINNAME 223 + #define SET_DOMAINNAME 224 /* 3xx: TCP/IP */ #define GET_OPENTIMEOUT (long) 300 #define SET_OPENTIMEOUT (long) 301 Index: src/imapd/imapd.c =================================================================== RCS file: /cvsroot/vimap/vimap/src/imapd/imapd.c,v retrieving revision 1.1.1.7 retrieving revision 1.7 diff -c -r1.1.1.7 -r1.7 *** src/imapd/imapd.c 12 Jun 2003 06:59:02 -0000 1.1.1.7 --- src/imapd/imapd.c 12 Jun 2003 07:06:42 -0000 1.7 *************** *** 27,32 **** --- 27,33 ---- #include #include #include "c-client.h" + #include "env.h" #include *************** *** 198,203 **** --- 199,205 ---- unsigned long nmsgs =0xffffffff;/* last reported # of messages and recent */ unsigned long recent = 0xffffffff; char *user = NIL; /* user name */ + char *domain = NIL; /* user domain */ char *pass = NIL; /* password */ char cmdbuf[CMDLEN]; /* command buffer */ char *tag; /* tag portion of command */ *************** *** 306,313 **** autologouttime = time (0) + LOGINTIMEOUT; break; case SELECT: ! syslog (LOG_INFO,"Preauthenticated user=%.80s host=%.80s", ! user,tcp_clienthost ()); break; } --- 308,316 ---- autologouttime = time (0) + LOGINTIMEOUT; break; case SELECT: ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Preauthenticated user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); break; } *************** *** 427,434 **** alerttime = 0; /* force alert */ /* return logged-in capabilities */ response = (response == altwin) ? logwinalt : logwin; ! syslog (LOG_INFO,"Authenticated user=%.80s host=%.80s", ! user,tcp_clienthost ()); } else { lsterr = cpystr (s); --- 430,438 ---- alerttime = 0; /* force alert */ /* return logged-in capabilities */ response = (response == altwin) ? logwinalt : logwin; ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Authenticated user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); } else { lsterr = cpystr (s); *************** *** 475,482 **** alerttime = 0; /* force alert */ /* return logged-in capabilities */ response = (response == altwin) ? logwinalt : logwin; ! syslog (LOG_INFO,"Login user=%.80s host=%.80s",user, ! tcp_clienthost ()); } else response = "%.80s NO %.80s failed\015\012"; } --- 479,487 ---- alerttime = 0; /* force alert */ /* return logged-in capabilities */ response = (response == altwin) ? logwinalt : logwin; ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Login user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); } else response = "%.80s NO %.80s failed\015\012"; } *************** *** 1161,1168 **** } } } ! syslog (LOG_INFO,"Logout user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); exit (0); /* all done */ return 0; /* stupid compilers */ } --- 1166,1173 ---- } } } ! syslog (LOG_INFO,"Logout user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); exit (0); /* all done */ return 0; /* stupid compilers */ } *************** *** 1183,1191 **** PSOUT (lasterror ()); CRLF; state = LOGOUT; /* go away */ syslog (LOG_INFO, ! "Fatal mailbox error user=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???",tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", lasterror ()); return; --- 1188,1197 ---- PSOUT (lasterror ()); CRLF; state = LOGOUT; /* go away */ + domain = (char *) env_parameters(GET_DOMAINNAME, 0); syslog (LOG_INFO, ! "Fatal mailbox error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", lasterror ()); return; *************** *** 1409,1416 **** server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Autologout; idle for too long\015\012"); ! syslog (LOG_INFO,"Autologout user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); PFLUSH (); /* make sure output blatted */ if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ --- 1415,1423 ---- server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Autologout; idle for too long\015\012"); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Autologout user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); PFLUSH (); /* make sure output blatted */ if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ *************** *** 1429,1436 **** server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Lost mailbox lock\015\012"); PFLUSH (); /* make sure output blatted */ ! syslog (LOG_INFO,"Killed (lost mailbox lock) user=%.80s host=%.80s", ! user ? user : "???",tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ if ((state == OPEN) && !stream->lock) stream = mail_close (stream); --- 1436,1443 ---- server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Lost mailbox lock\015\012"); PFLUSH (); /* make sure output blatted */ ! syslog (LOG_INFO,"Killed (lost mailbox lock) user=%.80s domain=.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ if ((state == OPEN) && !stream->lock) stream = mail_close (stream); *************** *** 1445,1452 **** { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"Hangup user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ if ((state == OPEN) && !stream->lock) stream = mail_close (stream); --- 1452,1460 ---- { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Hangup user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to close stream gracefully */ if ((state == OPEN) && !stream->lock) stream = mail_close (stream); *************** *** 1463,1470 **** alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Killed\015\012"); ! syslog (LOG_INFO,"Killed user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ /* Make no attempt at graceful closure since a shutdown may be in * in progress, and we won't have any time to do mail_close() actions --- 1471,1479 ---- alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); if (!quell_events) PSOUT ("* BYE Killed\015\012"); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Killed user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ /* Make no attempt at graceful closure since a shutdown may be in * in progress, and we won't have any time to do mail_close() actions *************** *** 1531,1538 **** char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"%.80s, while %s user=%.80s host=%.80s", ! e,reason,user ? user : "???",tcp_clienthost ()); /* try to gracefully close the stream */ if (state == OPEN) stream = mail_close (stream); _exit (1); --- 1540,1548 ---- char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"%.80s, while %s user=%.80s domain=%.80s host=%.80s", ! e,reason,user ? user : "???",domain ? domain : "???",tcp_clienthost ()); /* try to gracefully close the stream */ if (state == OPEN) stream = mail_close (stream); _exit (1); *************** *** 1578,1585 **** if (!isdigit (*s)) return NIL; if ((*size = i = strtoul (s,&t,10)) > MAXCLIENTLIT) { mm_notify (NIL,"Absurdly long client literal",ERROR); ! syslog (LOG_INFO,"Absurdly long client literal user=%.80s host=%.80s", ! user ? user : "???",tcp_clienthost ()); return NIL; } /* validate end of literal */ --- 1588,1596 ---- if (!isdigit (*s)) return NIL; if ((*size = i = strtoul (s,&t,10)) > MAXCLIENTLIT) { mm_notify (NIL,"Absurdly long client literal",ERROR); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Absurdly long client literal user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); return NIL; } /* validate end of literal */ *************** *** 3164,3171 **** if (s == t) return; /* check for completion */ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"%.80s, while writing text user=%.80s host=%.80s", ! strerror (errno),user ? user : "???",tcp_clienthost ()); if (state == OPEN) stream = mail_close (stream); _exit (1); } --- 3175,3183 ---- if (s == t) return; /* check for completion */ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"%.80s, while writing text user=%.80s domain=%.80s host=%.80s", ! strerror (errno),user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (state == OPEN) stream = mail_close (stream); _exit (1); } *************** *** 3837,3848 **** long mm_diskerror (MAILSTREAM *s,long errcode,long serious) { if (serious) { /* try your damnest if clobberage likely */ mm_notify (s,"Retrying to fix probable mailbox damage!",ERROR); PFLUSH (); /* dump output buffer */ syslog (LOG_ALERT, ! "Retrying after disk error user=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???",tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); alarm (0); /* make damn sure timeout disabled */ --- 3849,3861 ---- long mm_diskerror (MAILSTREAM *s,long errcode,long serious) { + domain = (char *) env_parameters(GET_DOMAINNAME, 0); if (serious) { /* try your damnest if clobberage likely */ mm_notify (s,"Retrying to fix probable mailbox damage!",ERROR); PFLUSH (); /* dump output buffer */ syslog (LOG_ALERT, ! "Retrying after disk error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); alarm (0); /* make damn sure timeout disabled */ *************** *** 3854,3859 **** --- 3867,3876 ---- PSOUT (strerror (errcode)); CRLF; } + syslog (LOG_ALERT,"Fatal disk error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", + user ? user : "???", domain ? domain : "???", tcp_clienthost (), + (stream && stream->mailbox) ? stream->mailbox : "???", + strerror (errcode)); return T; } *************** *** 3874,3880 **** PSOUTR (&msg); CRLF; } ! syslog (LOG_ALERT,"Fatal error user=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???",tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???",string); } --- 3891,3898 ---- PSOUTR (&msg); CRLF; } ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_ALERT,"Fatal error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???",string); } Index: src/ipopd/ipop2d.c =================================================================== RCS file: /cvsroot/vimap/vimap/src/ipopd/ipop2d.c,v retrieving revision 1.1.1.5 retrieving revision 1.5 diff -c -r1.1.1.5 -r1.5 *** src/ipopd/ipop2d.c 28 Apr 2003 14:29:37 -0000 1.1.1.5 --- src/ipopd/ipop2d.c 28 Apr 2003 14:40:49 -0000 1.5 *************** *** 28,34 **** #include #include #include "c-client.h" ! /* Autologout timer */ #define KODTIMEOUT 60*5 --- 28,34 ---- #include #include #include "c-client.h" ! #include "env.h" /* Autologout timer */ #define KODTIMEOUT 60*5 *************** *** 61,66 **** --- 61,67 ---- unsigned long size = 0; /* size of current message */ char status[MAILTMPLEN]; /* space for status string */ char *user = ""; /* user name */ + char *domain = 0; /* user domain */ char *pass = ""; /* password */ unsigned long *msg = NIL; /* message translation vector */ *************** *** 280,287 **** /* no, delimit user from possible admin */ if (s = strchr (u,'*')) *s++ = '\0'; if (server_login (user = cpystr (u),pass,s,argc,argv)) { ! syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s",s ? "Admin " : "", ! user,tcp_clienthost ()); return c_fold ("INBOX"); /* local; select INBOX */ } } --- 281,289 ---- /* no, delimit user from possible admin */ if (s = strchr (u,'*')) *s++ = '\0'; if (server_login (user = cpystr (u),pass,s,argc,argv)) { ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"%sLogin user=%.80s domain=.80s host=%.80s",s ? "Admin " : "", ! user,domain ? domain : "???",tcp_clienthost ()); return c_fold ("INBOX"); /* local; select INBOX */ } } Index: src/ipopd/ipop3d.c =================================================================== RCS file: /cvsroot/vimap/vimap/src/ipopd/ipop3d.c,v retrieving revision 1.1.1.6 retrieving revision 1.6 diff -c -r1.1.1.6 -r1.6 *** src/ipopd/ipop3d.c 28 Apr 2003 14:29:37 -0000 1.1.1.6 --- src/ipopd/ipop3d.c 28 Apr 2003 14:40:49 -0000 1.6 *************** *** 27,33 **** #include #include #include "c-client.h" ! #define CRLF PSOUT ("\015\012") /* primary output terpri */ --- 27,33 ---- #include #include #include "c-client.h" ! #include "env.h" #define CRLF PSOUT ("\015\012") /* primary output terpri */ *************** *** 69,74 **** --- 69,75 ---- char challenge[128]; /* challenge */ char *host = NIL; /* remote host name */ char *user = NIL; /* user name */ + char *domain = NIL; /* user domain */ char *pass = NIL; /* password */ char *initial = NIL; /* initial response */ long *msg = NIL; /* message translation vector */ *************** *** 144,151 **** char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ ! syslog (LOG_INFO,"%s while reading line user=%.80s host=%.80s", ! e,user ? user : "???",tcp_clienthost ()); rset (); /* try to gracefully close the stream */ if (state == TRANSACTION) mail_close (stream); stream = NIL; --- 145,152 ---- char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ ! syslog (LOG_INFO,"%s while reading line user=%.80s domain=%.80s host=%.80s", ! e,user ? user : "???", domain ? domain : "???", tcp_clienthost ()); rset (); /* try to gracefully close the stream */ if (state == TRANSACTION) mail_close (stream); stream = NIL; *************** *** 209,219 **** syslog (LOG_INFO,"AUTHENTICATE %s failure host=%.80s",s, tcp_clienthost ()); } ! else if ((state = mbxopen ("INBOX")) == TRANSACTION) ! syslog (LOG_INFO,"Auth user=%.80s host=%.80s nmsgs=%ld/%ld", ! user,tcp_clienthost (),nmsgs,stream->nmsgs); ! else syslog (LOG_INFO,"Auth user=%.80s host=%.80s no mailbox", ! user,tcp_clienthost ()); } else { AUTHENTICATOR *auth; --- 210,230 ---- syslog (LOG_INFO,"AUTHENTICATE %s failure host=%.80s",s, tcp_clienthost ()); } ! else ! { ! if ((state = mbxopen ("INBOX")) == TRANSACTION) ! { ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Auth user=%.80s domain=%.80s host=%.80s nmsgs=%ld/%ld", ! user,domain,tcp_clienthost (),nmsgs,stream->nmsgs); ! } ! else ! { ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"Auth user=%.80s domain=%.80s host=%.80s no mailbox", ! user,domain,tcp_clienthost ()); ! } ! } } else { AUTHENTICATOR *auth; *************** *** 248,258 **** PSOUT ("-ERR Missing APOP argument\015\012"); else if (!(user = apop_login (challenge,s,t,argc,argv))) PSOUT ("-ERR Bad APOP\015\012"); ! else if ((state = mbxopen ("INBOX")) == TRANSACTION) ! syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%ld/%ld", ! user,tcp_clienthost (),nmsgs,stream->nmsgs); ! else syslog (LOG_INFO,"APOP user=%.80s host=%.80s no mailbox", ! user,tcp_clienthost ()); } else PSOUT ("-ERR Not supported\015\012"); } --- 259,279 ---- PSOUT ("-ERR Missing APOP argument\015\012"); else if (!(user = apop_login (challenge,s,t,argc,argv))) PSOUT ("-ERR Bad APOP\015\012"); ! else ! { ! if ((state = mbxopen ("INBOX")) == TRANSACTION) ! { ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"APOP user=%.80s domain=%.80s host=%.80s nmsgs=%ld/%ld", ! user,domain,tcp_clienthost (),nmsgs,stream->nmsgs); ! } ! else ! { ! domain = (char *) env_parameters(GET_DOMAINNAME, 0); ! syslog (LOG_INFO,"APOP user=%.80s domain=%.80s host=%.80s no mailbox", ! user,domain,tcp_clienthost ()); ! } ! } } else PSOUT ("-ERR Not supported\015\012"); } *************** *** 455,466 **** } if (stream && (state == UPDATE)) { mail_expunge (stream); ! syslog (LOG_INFO,"Logout user=%.80s host=%.80s nmsgs=%ld ndele=%ld", ! user,tcp_clienthost (),stream->nmsgs,ndele); mail_close (stream); } ! else syslog (LOG_INFO,"Logout user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); PSOUT (sayonara); /* "now it's time to say sayonara..." */ PFLUSH (); /* make sure output finished */ exit (0); /* all done */ --- 476,487 ---- } if (stream && (state == UPDATE)) { mail_expunge (stream); ! syslog (LOG_INFO,"Logout user=%.80s domain=%.80s host=%.80s nmsgs=%ld ndele=%ld", ! user,domain,tcp_clienthost (),stream->nmsgs,ndele); mail_close (stream); } ! else syslog (LOG_INFO,"Logout user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); PSOUT (sayonara); /* "now it's time to say sayonara..." */ PFLUSH (); /* make sure output finished */ exit (0); /* all done */ *************** *** 473,480 **** void clkint () { PSOUT ("-ERR Autologout; idle for too long\015\012"); ! syslog (LOG_INFO,"Autologout user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); PFLUSH (); /* make sure output blatted */ if (critical) state = LOGOUT; /* badly hosed if in critical code */ else { /* try to gracefully close the stream */ --- 494,501 ---- void clkint () { PSOUT ("-ERR Autologout; idle for too long\015\012"); ! syslog (LOG_INFO,"Autologout user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); PFLUSH (); /* make sure output blatted */ if (critical) state = LOGOUT; /* badly hosed if in critical code */ else { /* try to gracefully close the stream */ *************** *** 499,506 **** alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Received Kiss of Death\015\012"); ! syslog (LOG_INFO,"Killed (lost mailbox lock) user=%.80s host=%.80s", ! user ? user : "???",tcp_clienthost ()); if (critical) state =LOGOUT;/* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { --- 520,527 ---- alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Received Kiss of Death\015\012"); ! syslog (LOG_INFO,"Killed (lost mailbox lock) user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state =LOGOUT;/* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { *************** *** 522,529 **** { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"Hangup user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { --- 543,550 ---- { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"Hangup user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { *************** *** 545,552 **** alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Killed\015\012"); ! syslog (LOG_INFO,"Killed user=%.80s host=%.80s",user ? user : "???", ! tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { --- 566,573 ---- alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Killed\015\012"); ! syslog (LOG_INFO,"Killed user=%.80s domain=%.80s host=%.80s", ! user ? user : "???", domain ? domain : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { *************** *** 580,590 **** /* attempt the login */ if (server_login (user,pass,t,argc,argv)) { int ret = mbxopen ("INBOX"); if (ret == TRANSACTION) /* mailbox opened OK? */ ! syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s nmsgs=%ld/%ld", ! t ? "Admin " : "",user,tcp_clienthost (),nmsgs,stream->nmsgs); ! else syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s no mailbox", ! t ? "Admin " : "",user,tcp_clienthost ()); return ret; } } --- 601,612 ---- /* attempt the login */ if (server_login (user,pass,t,argc,argv)) { int ret = mbxopen ("INBOX"); + domain = env_parameters(GET_DOMAINNAME, 0); if (ret == TRANSACTION) /* mailbox opened OK? */ ! syslog (LOG_INFO,"%sLogin user=%.80s domain=%.80s host=%.80s nmsgs=%ld/%ld", ! t ? "Admin " : "",user,domain,tcp_clienthost (),nmsgs,stream->nmsgs); ! else syslog (LOG_INFO,"%sLogin user=%.80s domain=%.80s host=%.80s no mailbox", ! t ? "Admin " : "",user,domain,tcp_clienthost ()); return ret; } } *************** *** 658,665 **** strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"%s, while reading auth char user=%.80s host=%.80s", ! e,user ? user : "???",tcp_clienthost ()); state = UPDATE; _exit (1); } --- 680,687 ---- strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); ! syslog (LOG_INFO,"%s, while reading auth char user=%.80s domain=%.80s host=%.80s", ! e,user ? user : "???", domain ? domain : "???", tcp_clienthost ()); state = UPDATE; _exit (1); } *************** *** 704,711 **** else sayonara = "-ERR Can't get lock. Mailbox in use\015\012"; } else sayonara = "-ERR Unable to open user's INBOX\015\012"; ! syslog (LOG_INFO,"Error opening or locking INBOX user=%.80s host=%.80s", ! user,tcp_clienthost ()); return UPDATE; } --- 726,733 ---- else sayonara = "-ERR Can't get lock. Mailbox in use\015\012"; } else sayonara = "-ERR Unable to open user's INBOX\015\012"; ! syslog (LOG_INFO,"Error opening or locking INBOX user=%.80s domain=%.80s host=%.80s", ! user,domain,tcp_clienthost ()); return UPDATE; } *************** *** 945,960 **** { if (serious) { /* try your damnest if clobberage likely */ syslog (LOG_ALERT, ! "Retrying after disk error user=%.80s host=%.80s mbx=%.80s: %.80s", ! user,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); alarm (0); /* make damn sure timeout disabled */ sleep (60); /* give it some time to clear up */ return NIL; } ! syslog (LOG_ALERT,"Fatal disk error user=%.80s host=%.80s mbx=%.80s: %.80s", ! user,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); return T; --- 967,982 ---- { if (serious) { /* try your damnest if clobberage likely */ syslog (LOG_ALERT, ! "Retrying after disk error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", ! user,domain,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); alarm (0); /* make damn sure timeout disabled */ sleep (60); /* give it some time to clear up */ return NIL; } ! syslog (LOG_ALERT,"Fatal disk error user=%.80s domain=%.80s host=%.80s mbx=%.80s: %.80s", ! user,domain,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); return T; Index: src/osdep/unix/Makefile =================================================================== RCS file: /cvsroot/vimap/vimap/src/osdep/unix/Makefile,v retrieving revision 1.1.1.6 retrieving revision 1.6 diff -c -r1.1.1.6 -r1.6 *** src/osdep/unix/Makefile 28 Apr 2003 14:29:38 -0000 1.1.1.6 --- src/osdep/unix/Makefile 28 Apr 2003 14:41:16 -0000 1.6 *************** *** 72,77 **** --- 72,78 ---- ACTIVEFILE=/usr/lib/news/active SPOOLDIR=/usr/spool MAILSPOOL=$(SPOOLDIR)/mail + VMAILSPOOL=$(SPOOLDIR)/vmail NEWSSPOOL=$(SPOOLDIR)/news RSHPATH=/usr/ucb/rsh LOCKPGM=/etc/mlock *************** *** 435,440 **** --- 436,450 ---- BASECFLAGS="-g -fno-omit-frame-pointer -O6" \ BASELDFLAGS="-lpam -ldl" + lnv: # Linux Pluggable Authentication modules with crypt + $(BUILD) `$(CAT) SPECIALS` OS=lnx \ + SIGTYPE=psx CHECKPW=pam CRXTYPE=nfs \ + SPOOLDIR=/var/spool \ + ACTIVEFILE=/var/lib/news/active \ + RSHPATH=/usr/bin/rsh \ + BASECFLAGS="-g ${RPM_OPT_FLAGS}" \ + BASELDFLAGS="-lpam -lcrypt -ldl" + lnx: # Linux non-shadow passwords @echo You are building for traditional Linux *without* shadow @echo passwords and with the crypt function in the C library. *************** *** 873,878 **** --- 883,889 ---- echo $(BASECFLAGS) '$(EXTRACFLAGS)' > CFLAGS echo -DCREATEPROTO=$(CREATEPROTO) -DEMPTYPROTO=$(EMPTYPROTO) \ -DMAILSPOOL=\"$(MAILSPOOL)\" \ + -DVMAILSPOOL=\"$(VMAILSPOOL)\" \ -DANONYMOUSHOME=\"$(MAILSPOOL)/anonymous\" \ -DACTIVEFILE=\"$(ACTIVEFILE)\" -DNEWSSPOOL=\"$(NEWSSPOOL)\" \ -DRSHPATH=\"$(RSHPATH)\" -DLOCKPGM=\"$(LOCKPGM)\" > OSCFLAGS Index: src/osdep/unix/env_unix.c =================================================================== RCS file: /cvsroot/vimap/vimap/src/osdep/unix/env_unix.c,v retrieving revision 1.1.1.6 retrieving revision 1.8 diff -c -r1.1.1.6 -r1.8 *** src/osdep/unix/env_unix.c 28 Apr 2003 14:29:38 -0000 1.1.1.6 --- src/osdep/unix/env_unix.c 28 Apr 2003 14:41:17 -0000 1.8 *************** *** 21,30 **** --- 21,32 ---- #include #include #include + #include /* c-client environment parameters */ static char *myUserName = NIL; /* user name */ + static char *myUserDomain = NIL;/* user domain */ static char *myHomeDir = NIL; /* home directory name */ static char *myMailboxDir = NIL;/* mailbox directory name */ static char *myLocalHost = NIL; /* local host name */ *************** *** 48,53 **** --- 50,57 ---- static short has_no_life = NIL; /* is a cretin with no life */ /* flock() emulator is a no-op */ static short disableFcntlLock = NIL; + /* warning on EACCES errors on .lock files */ + static short lockEaccesError = NIL; static short hideDotFiles = NIL;/* hide files whose names start with . */ /* advertise filesystem root */ static short advertisetheworld = NIL; *************** *** 152,157 **** --- 156,167 ---- case GET_USERNAME: ret = (void *) myUserName; break; + case SET_DOMAINNAME: + if (myUserDomain) fs_give ((void **) &myUserDomain); + myUserDomain = cpystr ((char *) value); + case GET_DOMAINNAME: + ret = (void *) myUserDomain; + break; case SET_HOMEDIR: if (myHomeDir) fs_give ((void **) &myHomeDir); myHomeDir = cpystr ((char *) value); *************** *** 465,470 **** --- 475,798 ---- return select (1,&rfd,0,&efd,&tmo) ? LONGT : NIL; } + + /* Virtual Support Functions */ + + /* vsplitline + * - splits a passwd or shadow entry into char[9][100], each parameter + * in each. Returns count of parameters. + */ + static int vsplitline(const char *line, char words[9][100]) + { + int nbword = 0; + char *dst = words[0]; + int i; + for (i=0; i<9; i++) words[i][0] = '\0'; + while (*line != '\0' && *line != '\n') + { + if (*line == ':') + { + line++; + *dst = '\0'; + dst = words[nbword]; + while (*dst == ' ' || *dst == '\t') + { + char *p; + dst++; + p = strdup(dst--); + strncpy(words[nbword], p, 100); + free(p); + } + if (strlen(words[nbword])>0) + { + for (dst=words[nbword];*dst!='\0';dst++) ; + dst--; + while (strlen(words[nbword])>0 && (*dst == ' ' || *dst == '\t')) + *(dst--) = '\0'; + } + nbword++; + dst = words[nbword]; + } + else *dst++ = *line++; + } + *dst = '\0'; + dst = words[nbword]; + while (*dst==' ' || *dst=='\t') + { + char *p; + dst++; + p = strdup(dst--); + strncpy(words[nbword], p, 100); + free(p); + } + if (strlen(words[nbword])>0) + { + for(dst=words[nbword];*dst!='\0';dst++) ; + dst--; + while(strlen(words[nbword])>0 && (*dst == ' ' || *dst == '\t')) + *(dst--) = '\0'; + } + + return nbword; + } + + /* makedomainnamesafe + * - removes dangerous characters like /, *, <, >, | and ? + * allowing only a-z, A-Z, 0-9, "." and "-" + */ + + void makedomainnamesafe(char *filename) + { + char *p; + + for (p=filename;*p!='\0';p++) + { + if (!((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || /* make a-z, A-Z legal */ + (*p>='0' && *p<='9') || *p == '.' || *p == '-')) /* make 0-9, '.', '-' legal */ + *p = '-'; + } + } + + /* solveusername + * - Checks aliases file + */ + + void solvealiases(char *name) + { + char newuser[128], filename[128], *p, buf[400]; + struct passwd *pw; + FILE *fin; + + if (myUserDomain) + sprintf(filename, "/etc/vmail/aliases.%s", myUserDomain); + else + strcpy(filename, "/etc/aliases"); + + fin = fopen(filename, "r"); + if (fin) + { + while (fgets(buf, sizeof(buf)-1, fin)) + { + char words[9][100]; + vsplitline(buf, words); + if (words[0][0] != '#') + { /* skip remarks */ + if (strchr(words[1], '@')==NULL && strchr(words[1], ',')==NULL && + strchr(words[1], ' ')==NULL) + { /* only single accounts, no lists or external adresses */ + if (!strcasecmp(words[0], name)) strcpy(name, words[1]); + } + } + } + fclose(fin); + } + } + + /* reducedomainnameifneed() + * Checks for /etc/vmail/passwd.myUserDomain and if not found reduces + * name with host entry, i.e. www.domain.com will become domain.com + */ + + void reducedomainnameifneeded() + { + char filename[256]; + FILE *fp; + + strncpy(filename, "/etc/vmail/passwd.", sizeof(filename)); + strncat(filename, myUserDomain, sizeof(filename)); + + if ((fp = fopen(filename, "r")) == NULL) { + char tmpspace[256]; + char *p; + + if ((p=strchr(myUserDomain, '.')) != NULL) { + p++; + strncpy(tmpspace, p, sizeof(tmpspace)); + fs_give((void **) &myUserDomain); + myUserDomain = cpystr(tmpspace); + } + + strncpy(filename, "/etc/vmail/passwd.", sizeof(filename)); + strncat(filename, myUserDomain, sizeof(filename)); + + if ((fp = fopen(filename, "r")) == NULL) + fs_give((void **) &myUserDomain); + else fclose(fp); + } + else fclose(fp); + } + + /* int checklinuxconfconfig(char *domain) + * read info from config file about domain lock and returns 1 if domain is locked, 0 otherwise + */ + + int checklinuxconfconfig(char *domain) + { + FILE *fp; + regex_t vdomainregex; + int ret=0; + int regexerror; + + regexerror = regcomp(&vdomainregex, "vdomain_retrievelock\\.\\([a-z0-9\\.]*\\) 1", 0); + + if ((regexerror==0) && (fp = fopen("/etc/conf.linuxconf", "r"))) { + char line[1024]; + char exdomain[1024]; + + while (!feof(fp)) + { + regmatch_t matches[5]; + + fgets(line,sizeof(line)-1,fp); + + if ((regexerror=regexec(&vdomainregex, &line[0], 5, matches, 0))==0) { + strncpy(exdomain, &line[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so); + if (strcmp(domain, exdomain)==0) + { + ret=1; + syslog(LOG_NOTICE|LOG_AUTH, "Domain %s is locked.", domain); + } + } + } + fclose(fp); + } + regfree(&vdomainregex); + + return ret; + } + + /* checkforvirtual(char *username) + * separate domainname from username if present + */ + + void checkforvirtualdomain(char * name) + { + #ifdef VMAILSPOOL + char *p; + if (strlen(name)>96) return; /* Return if username is long */ + if (myUserDomain) fs_give((void **) &myUserDomain); + if ((p = strchr(name, '@')) || (p = strchr(name, '#')) || + (p = strchr(name, '/'))) + { + char myHostname[128], myDomainname[128]; + gethostname(myHostname, sizeof(myHostname)-1); + getdomainname(myDomainname, sizeof(myDomainname)-1); + *(p++) = '\0'; /* Truncate username at "@"-char */ + if (strcasecmp(p, myHostname) || strcasecmp(p, myDomainname)) { + myUserDomain = cpystr(p); + makedomainnamesafe(myUserDomain); + } + solvealiases(name); + } + + if (!myUserDomain) { + struct sockaddr_in adr; + unsigned int len = sizeof(adr); + if (getsockname(0, (struct sockaddr*) &adr, &len) != 1) { + struct hostent *ent, *main; + ent = gethostbyaddr((const char*) &adr.sin_addr, + sizeof(adr.sin_addr.s_addr), AF_INET); + if (ent != NULL) { + char mainhost[256]; + myUserDomain = cpystr(ent->h_name); + gethostname((char *) &mainhost, sizeof(mainhost)); + main = gethostbyname((const char *) &mainhost); + if (strcmp(main->h_name, myUserDomain) == 0) + fs_give((void **) &myUserDomain); + else { + makedomainnamesafe(myUserDomain); + reducedomainnameifneeded(); + } + } + } else { + syslog(LOG_ERR, "getsockname failed (errno %m)"); + } + } + + /* Check if domain is locked in linuxconf configuration file */ + if (myUserDomain && checklinuxconfconfig(myUserDomain)==1) + fs_give((void **) &myUserDomain); + + #endif + } + + /* vgetpwnam - virtual getpwnam + * returns passwd entry for username specified. If domainname is present + * vgetpwnam searches virtual directories, otherwise calls getpwnam to + * perform the task. + */ + struct passwd *vgetpwnam(const char * name) + { + #ifdef VMAILSPOOL + char filename[128]; + struct passwd *ret = NIL; + FILE *fin; + + if (myUserDomain) { + strcpy(filename, "/etc/vmail/passwd."); + strcat(filename, myUserDomain); + fin = fopen(filename, "r"); + if (fin) { + char buf[400]; + while (fgets(buf,sizeof(buf)-1, fin)!=NULL) { + static char words[9][100]; + static struct passwd p = { + words[0], words[1], 0, 0, words[4], words[5], words[6] + }; + vsplitline( buf, words ); + if (strcmp(name, words[0]) == 0) { + ret = &p; + p.pw_uid = atoi(words[2]); + p.pw_gid = atoi(words[3]); + break; + } + } + fclose(fin); + if (ret) { + strcpy(filename, "/etc/vmail/shadow."); + strcat(filename, myUserDomain); + fin = fopen(filename, "r"); + if (fin) { + while (fgets(buf, sizeof(buf)-1, fin) != NULL) { + char words[9][100]; + vsplitline( buf, words ); + if (strcmp(name,words[0]) == 0) { + int last = atoi(words[2]); + int expire = atoi(words[6]); + int disable = atoi(words[7]); + time_t tim = time(NULL); + int days = tim /(24*60*60); + if ((disable>0 && disable < days) || + (expire>0 && last > 0 && last + expire < days)) + strcpy(ret->pw_passwd,"*"); + else + strcpy(ret->pw_passwd,words[1]); + break; + } + } + fclose(fin); + } + } + } + } + else + ret = getpwnam(name); + return ret; + #else + return getpwnam(name); + #endif + } + + struct passwd *vcheckpw (struct passwd *pw,char *pass,int argc,char *argv[]) + { + #ifdef VMAILSPOOL + if (myUserDomain) + return strcmp (pw->pw_passwd,(char *) crypt (pass,pw->pw_passwd)) ? NIL : pw; + else + return checkpw(pw, pass, argc, argv); + #endif + } + /* Return UNIX password entry for user name * Accepts: user name string * Returns: password entry *************** *** 475,492 **** static struct passwd *pwuser (char *user) { char *s; ! struct passwd *pw = getpwnam (user); if (!pw) { /* failed, see if any uppercase characters */ for (s = user; *s && !isupper (*s); s++); if (*s) { /* yes, try all lowercase form */ ! pw = getpwnam (s = lcase (cpystr (user))); fs_give ((void **) &s); } } return pw; } - /* Validate password for user name * Accepts: user name string * password string --- 803,819 ---- static struct passwd *pwuser (char *user) { char *s; ! struct passwd *pw = vgetpwnam (user); if (!pw) { /* failed, see if any uppercase characters */ for (s = user; *s && !isupper (*s); s++); if (*s) { /* yes, try all lowercase form */ ! pw = vgetpwnam (s = lcase (cpystr (user))); fs_give ((void **) &s); } } return pw; } /* Validate password for user name * Accepts: user name string * password string *************** *** 501,513 **** static struct passwd *valpwd (char *user,char *pwd,int argc,char *argv[]) { struct passwd *pw; ! char *usr; ! if (pw = pwuser (user)) { /* can get user? */ ! usr = cpystr (pw->pw_name); /* copy returned name in case we need it */ ! if (!(pw = checkpw (pw,pwd,argc,argv)) && (*pwd == ' ') && ! (pw = pwuser (usr))) pw = checkpw (pw,pwd+1,argc,argv); ! fs_give ((void **) &usr); /* don't need copy of name any more */ } return pw; } --- 828,840 ---- static struct passwd *valpwd (char *user,char *pwd,int argc,char *argv[]) { struct passwd *pw; ! char *usr = cpystr(user); ! checkforvirtualdomain(usr); /* check for virtual domain request */ ! if (pw = pwuser (usr)) { /* can get user? */ ! if (!(pw = vcheckpw (pw,pwd,argc,argv)) && (*pwd == ' ') && ! (pw = pwuser (usr))) pw = vcheckpw (pw,pwd+1,argc,argv); } + fs_give ((void **) &usr); return pw; } *************** *** 548,555 **** else if (!(authuser && *authuser)) pw = valpwd (user,pwd,argc,argv); else if (valpwd (authuser,pwd,argc,argv)) pw = pwuser (user); if (pw && pw_login (pw,authuser,pw->pw_name,NIL,argc,argv)) return T; ! syslog (level|LOG_AUTH,"Login %s user=%.64s auth=%.64s host=%.80s",err, ! user,(authuser && *authuser) ? authuser : user,tcp_clienthost ()); sleep (3); /* slow down possible cracker */ return NIL; } --- 875,882 ---- else if (!(authuser && *authuser)) pw = valpwd (user,pwd,argc,argv); else if (valpwd (authuser,pwd,argc,argv)) pw = pwuser (user); if (pw && pw_login (pw,authuser,pw->pw_name,NIL,argc,argv)) return T; ! syslog (level|LOG_AUTH,"Login %s user=%.64s domain=%.64s auth=%.64s host=%.80s",err, ! user,myUserDomain,(authuser && *authuser) ? authuser : user,tcp_clienthost ()); sleep (3); /* slow down possible cracker */ return NIL; } *************** *** 608,615 **** if ((gr = getgrnam (ADMINGROUP)) && (t = gr->gr_mem)) while (*t && !ret) if (!compare_cstring (auser,*t++)) ret = pw_login (pw,NIL,user,home,argc,argv); ! syslog (LOG_NOTICE|LOG_AUTH,"%s %.80s override of user=%.80s host=%.80s", ! ret ? "Admin" : "Failed",auser,user,tcp_clienthost ()); } else if (closedBox) { /* paranoid site, lock out other directories */ if (chdir (home) || chroot (home)) --- 935,942 ---- if ((gr = getgrnam (ADMINGROUP)) && (t = gr->gr_mem)) while (*t && !ret) if (!compare_cstring (auser,*t++)) ret = pw_login (pw,NIL,user,home,argc,argv); ! syslog (LOG_NOTICE|LOG_AUTH,"%s %.80s override of user=%.80s domain=%.80s host=%.80s", ! ret ? "Admin" : "Failed",auser,user,myUserDomain,tcp_clienthost ()); } else if (closedBox) { /* paranoid site, lock out other directories */ if (chdir (home) || chroot (home)) *************** *** 804,810 **** { char tmp[MAILTMPLEN]; if (!sysInbox) { /* initialize if first time */ ! sprintf (tmp,"%s/%s",MAILSPOOL,myusername ()); sysInbox = cpystr (tmp); /* system inbox is from mail spool */ } return sysInbox; --- 1131,1140 ---- { char tmp[MAILTMPLEN]; if (!sysInbox) { /* initialize if first time */ ! if (!myUserDomain) ! sprintf (tmp,"%s/%s",MAILSPOOL,myusername ()); ! else ! sprintf (tmp,"%s/%s/%s",VMAILSPOOL,myUserDomain,myusername ()); sysInbox = cpystr (tmp); /* system inbox is from mail spool */ } return sysInbox; Index: src/tmail/tmail.1 =================================================================== RCS file: /cvsroot/vimap/vimap/src/tmail/tmail.1,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -c -r1.1.1.1 -r1.2 *** src/tmail/tmail.1 17 Dec 2002 10:34:29 -0000 1.1.1.1 --- src/tmail/tmail.1 7 May 2003 17:38:36 -0000 1.2 *************** *** 4,10 **** .nh .SH SYNOPSIS .B tmail ! .I [\-D] [-f from_name] [\-I inbox_specifier] user[+folder] ... .SH DESCRIPTION .I tmail delivers mail to a user's INBOX or a designated folder. --- 4,10 ---- .nh .SH SYNOPSIS .B tmail ! .I [\-D] [-f from_name] [\-I inbox_specifier] user[@virtual_domain][+folder] ... .SH DESCRIPTION .I tmail delivers mail to a user's INBOX or a designated folder. *************** *** 124,134 **** --- 124,144 ---- sendmail version 8: .sp .nf + #Local mailer Mlocal, P=/usr/local/etc/tmail, F=lsDFMAw5:/|@qPrn+, S=10/30, R=20/40, E=\\r\\n, T=DNS/RFC822/X-Unix, A=tmail $u .fi .PP + + .sp + .nf + #Virtual domain mailer + Mtmail, P=/usr/bin/tmail, F=lsDFMShPue, E=\\r\\n, + S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, + T=DNS/RFC822/X-Unix, + A=tmail $u + If .I tmail is to be called with the \fB-I\fR flag, it must be invoked with both Index: src/tmail/tmail.c =================================================================== RCS file: /cvsroot/vimap/vimap/src/tmail/tmail.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -c -r1.1.1.1 -r1.2 *** src/tmail/tmail.c 17 Dec 2002 10:34:29 -0000 1.1.1.1 --- src/tmail/tmail.c 7 May 2003 17:38:36 -0000 1.2 *************** *** 130,136 **** openlog ("tmail",LOG_PID,LOG_MAIL); #include "linkage.c" /* make sure have some arguments */ ! if (--argc < 1) _exit (fail ("usage: tmail [-D] user[+folder]",EX_USAGE)); /* process all flags */ while (argc && (*(s = *++argv)) == '-') { argc--; /* gobble this argument */ --- 130,136 ---- openlog ("tmail",LOG_PID,LOG_MAIL); #include "linkage.c" /* make sure have some arguments */ ! if (--argc < 1) _exit (fail ("usage: tmail [-D] user[@domain][+folder]",EX_USAGE)); /* process all flags */ while (argc && (*(s = *++argv)) == '-') { argc--; /* gobble this argument */ *************** *** 245,252 **** struct stat sbuf; uid_t duid; uid_t euid = geteuid (); ! /* get user record */ ! if (!(pwd = getpwnam (getusername (user,&mailbox)))) { sprintf (tmp,"no such user as %.80s",user); return fail (tmp,EX_NOUSER); } --- 245,253 ---- struct stat sbuf; uid_t duid; uid_t euid = geteuid (); ! /* get user record*/ ! /* CHANGES !! vgetpwnam */ ! if (! (pwd = vgetpwnam (getusername (user,&mailbox)))) { sprintf (tmp,"no such user as %.80s",user); return fail (tmp,EX_NOUSER); } *************** *** 552,558 **** } ! /* Get user name from username+mailbox specifier * Accepts: username/mailbox specifier * pointer to return location for mailbox specifier * Returns: user name, mailbox specifier value NIL if INBOX, patches out + --- 553,559 ---- } ! /* Get user name from username@domain+mailbox specifier * Accepts: username/mailbox specifier * pointer to return location for mailbox specifier * Returns: user name, mailbox specifier value NIL if INBOX, patches out + *************** *** 561,570 **** char *getusername (char *s,char **t) { char tmp[MAILTMPLEN]; if (*t = strchr (s,'+')) { /* have a mailbox specifier? */ ! *(*t)++ = '\0'; /* yes, tie off user name */ /* user+ and user+INBOX same as user */ if (!**t || !strcmp ("INBOX",ucase (strcpy (tmp,*t)))) *t = NIL; } return s; /* return user name */ } --- 562,576 ---- char *getusername (char *s,char **t) { char tmp[MAILTMPLEN]; + char *p; if (*t = strchr (s,'+')) { /* have a mailbox specifier? */ ! *(*t)++ = '\0'; /* yes, tie off user name[@domain] */ /* user+ and user+INBOX same as user */ if (!**t || !strcmp ("INBOX",ucase (strcpy (tmp,*t)))) *t = NIL; + } + if (p = strrchr (s,'@')) { /* have a domain specified? */ + *p = '\0'; p++; /* yes, tie off user name */ + env_parameters(SET_DOMAINNAME,p); } return s; /* return user name */ }