more changes

This commit is contained in:
rsc 2006-02-12 19:40:23 +00:00
parent d0d15c12d4
commit 5cc53af92d
11 changed files with 234 additions and 412 deletions

View file

@ -18,6 +18,8 @@ enum
Elemlen= 28, Elemlen= 28,
Errlen= 128, Errlen= 128,
Pathlen= 256, Pathlen= 256,
RetryCode = 2,
}; };
/* /*

View file

@ -1,3 +1,7 @@
#include <u.h>
#include <sys/types.h>
#include <pwd.h>
#include <netdb.h>
#include "common.h" #include "common.h"
#include <auth.h> #include <auth.h>
#include <ndb.h> #include <ndb.h>
@ -407,6 +411,7 @@ sysdirreadall(int fd, Dir **d)
/* /*
* read in the system name * read in the system name
*/ */
static char *unix_hostname_read(void);
extern char * extern char *
sysname_read(void) sysname_read(void)
{ {
@ -424,19 +429,26 @@ sysname_read(void)
extern char * extern char *
alt_sysname_read(void) alt_sysname_read(void)
{ {
char *cp;
static char name[128]; static char name[128];
int n, fd;
fd = open("/dev/sysname", OREAD); cp = getenv("sysname");
if(fd < 0) if(cp == 0 || *cp == 0)
cp = unix_hostname_read();
if(cp == 0 || *cp == 0)
return 0; return 0;
n = read(fd, name, sizeof(name)-1); strecpy(name, name+sizeof name, cp);
close(fd);
if(n <= 0)
return 0;
name[n] = 0;
return name; return name;
} }
static char *
unix_hostname_read(void)
{
static char hostname[256];
if(gethostname(hostname, sizeof hostname) < 0)
return nil;
return hostname;
}
/* /*
* get all names * get all names
@ -445,57 +457,49 @@ extern char**
sysnames_read(void) sysnames_read(void)
{ {
static char **namev; static char **namev;
Ndbtuple *t, *nt; struct hostent *h;
Ndb* db; char **p, **a;
Ndbs s;
int n;
char *cp;
if(namev) if(namev)
return namev; return namev;
/* XXX */ h = gethostbyname(alt_sysname_read());
/* free(csgetvalue(0, "sys", alt_sysname_read(), "dom", &t)); jpc */ for(p=h->h_aliases; *p; p++)
db = ndbopen(unsharp("#9/ndb/local")); ;
free(ndbgetvalue(db, &s, "sys", sysname(),"dom", &t));
/* t = nil; /* jpc */ namev = malloc((2+p-h->h_aliases)*sizeof namev[0]);
/* fprint(2,"csgetvalue called: fixme"); /* jpc */ if(namev == 0)
return 0;
n = 0; a = namev;
for(nt = t; nt; nt = nt->entry) *a++ = strdup(h->h_name);
if(strcmp(nt->attr, "dom") == 0) for(p=h->h_aliases; *p; p++)
n++; *a++ = strdup(*p);
*a = 0;
namev = (char**)malloc(sizeof(char *)*(n+3));
if(namev){
n = 0;
namev[n++] = strdup(sysname_read());
cp = alt_sysname_read();
if(cp)
namev[n++] = strdup(cp);
for(nt = t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0)
namev[n++] = strdup(nt->val);
namev[n] = 0;
}
if(t)
ndbfree(t);
return namev; return namev;
} }
/* /*
* read in the domain name * read in the domain name.
* chop off beginning pieces until we find one with an mx record.
*/ */
extern char * extern char *
domainname_read(void) domainname_read(void)
{ {
char **namev; char **namev, *p;
Ndbtuple *t;
for(namev = sysnames_read(); *namev; namev++) for(namev = sysnames_read(); *namev; namev++){
if(strchr(*namev, '.')) if(strchr(*namev, '.')){
return *namev; for(p=*namev-1; p && *++p; p=strchr(p, '.')){
if((t = dnsquery(nil, p, "mx")) != nil){
ndbfree(t);
return p;
}
}
}
}
return 0; return 0;
} }
@ -607,37 +611,13 @@ sysisdir(char *file)
return rv; return rv;
} }
/*
* kill a process or process group
*/
static int
stomp(int pid, char *file)
{
char name[64];
int fd;
snprint(name, sizeof(name), "/proc/%d/%s", pid, file);
fd = open(name, 1);
if(fd < 0)
return -1;
if(write(fd, "die: yankee pig dog\n", sizeof("die: yankee pig dog\n") - 1) <= 0){
close(fd);
return -1;
}
close(fd);
return 0;
}
/* /*
* kill a process * kill a process
*/ */
extern int extern int
syskill(int pid) syskill(int pid)
{ {
return stomp(pid, "note"); return postnote(PNPROC, pid, "kill");
} }
/* /*
@ -646,7 +626,7 @@ syskill(int pid)
extern int extern int
syskillpg(int pid) syskillpg(int pid)
{ {
return stomp(pid, "notepg"); return postnote(PNGROUP, pid, "kill");
} }
extern int extern int
@ -723,12 +703,24 @@ sysfiles(void)
extern String * extern String *
mboxpath(char *path, char *user, String *to, int dot) mboxpath(char *path, char *user, String *to, int dot)
{ {
upasconfig(); char *dir;
String *s;
if (dot || *path=='/' || strncmp(path, "./", 2) == 0 if (dot || *path=='/' || strncmp(path, "./", 2) == 0
|| strncmp(path, "../", 3) == 0) { || strncmp(path, "../", 3) == 0) {
to = s_append(to, path); to = s_append(to, path);
} else { } else {
if ((dir = homedir(user)) != nil) {
s = s_copy(dir);
s_append(s, "/mail/");
if(access(s_to_c(s), AEXIST) >= 0){
to = s_append(to, s_to_c(s));
s_free(s);
to = s_append(to, path);
return to;
}
s_free(s);
}
to = s_append(to, MAILROOT); to = s_append(to, MAILROOT);
to = s_append(to, "/box/"); to = s_append(to, "/box/");
to = s_append(to, user); to = s_append(to, user);
@ -755,13 +747,6 @@ deadletter(String *to) /* pass in sender??? */
return mboxpath("dead.letter", cp, to, 0); return mboxpath("dead.letter", cp, to, 0);
} }
char *
homedir(char *user)
{
USED(user);
return getenv("home");
}
String * String *
readlock(String *file) readlock(String *file)
{ {
@ -776,56 +761,48 @@ readlock(String *file)
String * String *
username(String *from) username(String *from)
{ {
int n; String* s;
Biobuf *bp; struct passwd* pw;
char *p, *q;
String *s;
bp = Bopen("/adm/keys.who", OREAD); setpwent();
if(bp == 0) while((pw = getpwent()) != nil){
bp = Bopen("/adm/netkeys.who", OREAD); if(strcmp(s_to_c(from), pw->pw_name) == 0){
if(bp == 0) s = s_new();
return 0; s_append(s, "\"");
s_append(s, pw->pw_gecos);
s = 0; s_append(s, "\"");
n = strlen(s_to_c(from)); return s;
for(;;) { }
p = Brdline(bp, '\n');
if(p == 0)
break;
p[Blinelen(bp)-1] = 0;
if(strncmp(p, s_to_c(from), n))
continue;
p += n;
if(*p != ' ' && *p != '\t') /* must be full match */
continue;
while(*p && (*p == ' ' || *p == '\t'))
p++;
if(*p == 0)
continue;
for(q = p; *q; q++)
if(('0' <= *q && *q <= '9') || *q == '<')
break;
while(q > p && q[-1] != ' ' && q[-1] != '\t')
q--;
while(q > p && (q[-1] == ' ' || q[-1] == '\t'))
q--;
*q = 0;
s = s_new();
s_append(s, "\"");
s_append(s, p);
s_append(s, "\"");
break;
} }
Bterm(bp); return nil;
return s; }
char *
homedir(char *user)
{
static char buf[1024];
struct passwd* pw;
setpwent();
while((pw = getpwent()) != nil)
if(strcmp(user, pw->pw_name) == 0){
strecpy(buf, buf+sizeof buf, pw->pw_dir);
return buf;
}
return nil;
} }
char * char *
remoteaddr(int fd, char *dir) remoteaddr(int fd, char *dir)
{ {
/* XXX should call netconninfo */ char *raddr;
return ""; NetConnInfo *nci;
if((nci = getnetconninfo(dir, fd)) == nil)
return nil;
raddr = strdup(nci->raddr);
freenetconninfo(nci);
return raddr;
} }
// create a file and // create a file and

View file

@ -1104,7 +1104,7 @@ sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
exec(s_to_c(cmd), av); exec(s_to_c(cmd), av);
exec("myupassend", av); exec("myupassend", av);
exec(unsharp("#9/bin/upas/send"), av); exec(unsharp("#9/bin/upas/send"), av);
fatal("execing: %r"); fatal("exec: %r");
break; break;
default: default:
if(rcvr != nil) if(rcvr != nil)

View file

@ -513,7 +513,7 @@ dofile(Dir *dp)
if(wm->msg[0]){ if(wm->msg[0]){
if(debug) if(debug)
fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg); fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg);
if(!Rflag && strstr(wm->msg, "Retry")==0){ if(!Rflag && atoi(wm->msg) != RetryCode){
/* return the message and remove it */ /* return the message and remove it */
if(returnmail(av, dp->name, wm->msg) != 0) if(returnmail(av, dp->name, wm->msg) != 0)
logit("returnmail failed", dp->name, av); logit("returnmail failed", dp->name, av);

View file

@ -2,7 +2,7 @@
#include "send.h" #include "send.h"
#include "../smtp/smtp.h" #include "../smtp/smtp.h"
#include "../smtp/y.tab.h" #include "../smtp/rfc822.tab.h"
/* global to this file */ /* global to this file */
static Reprog *rfprog; static Reprog *rfprog;

View file

@ -301,6 +301,7 @@ substitute(String *source, Resub *subexp, message *mp)
sp = getrcvar(sp+1, &s); sp = getrcvar(sp+1, &s);
s_append(stp, s); s_append(stp, s);
free(s); free(s);
sp--; /* counter sp++ below */
} else } else
s_putc(stp, *sp); s_putc(stp, *sp);
sp++; sp++;

View file

@ -241,7 +241,6 @@ isrcptrecent(char *rcpt)
void void
vfysenderhostok(void) vfysenderhostok(void)
{ {
char *fqdn;
int recent = 0; int recent = 0;
Link *l; Link *l;
@ -258,7 +257,7 @@ vfysenderhostok(void)
if (fd >= 0) { if (fd >= 0) {
seek(fd, 0, 2); /* paranoia */ seek(fd, 0, 2); /* paranoia */
fprint(fd, "# %s\n%s\n\n", fqdn, nci->rsys); fprint(fd, "# unknown\n%s\n\n", nci->rsys);
close(fd); close(fd);
} }
} else { } else {

View file

@ -22,7 +22,6 @@ Ndb *db;
extern int debug; extern int debug;
static int mxlookup(DS*, char*); static int mxlookup(DS*, char*);
static int mxlookup1(DS*, char*);
static int compar(const void*, const void*); static int compar(const void*, const void*);
static int callmx(DS*, char*, char*); static int callmx(DS*, char*, char*);
static void expand_meta(DS *ds); static void expand_meta(DS *ds);
@ -113,83 +112,28 @@ callmx(DS *ds, char *dest, char *domain)
} }
/* /*
* call the dns process and have it try to resolve the mx request * use dns to resolve the mx request
*
* this routine knows about the firewall and tries inside and outside
* dns's seperately.
*/ */
static int static int
mxlookup(DS *ds, char *domain) mxlookup(DS *ds, char *domain)
{ {
int n; int i, n, nmx;
Ndbtuple *t, *tmx, *tpref, *tip;
/* just in case we find no domain name */
strcpy(domain, ds->host); ds->netdir = "/net";
if(ds->netdir){
n = mxlookup1(ds, domain);
} else {
ds->netdir = "/net";
n = mxlookup1(ds, domain);
if(n == 0) {
ds->netdir = "/net.alt";
n = mxlookup1(ds, domain);
}
}
return n;
}
static int
mxlookup1(DS *ds, char *domain)
{
char buf[1024];
char dnsname[Maxstring];
char *fields[4];
int i, n, fd, nmx;
snprint(dnsname, sizeof dnsname, "%s/dns", ds->netdir);
fd = open(dnsname, ORDWR);
if(fd < 0)
return 0;
nmx = 0; nmx = 0;
snprint(buf, sizeof(buf), "%s mx", ds->host); if((t = dnsquery(nil, ds->host, "mx")) != nil){
if(debug) for(tmx=t; (tmx=ndbfindattr(tmx->entry, nil, "mx")) != nil && nmx<Nmx; ){
fprint(2, "sending %s '%s'\n", dnsname, buf); for(tpref=tmx->line; tpref != tmx; tpref=tmx->line){
n = write(fd, buf, strlen(buf)); if(strcmp(tpref->attr, "pref") == 0){
if(n < 0){ strncpy(mx[nmx].host, tmx->val, sizeof(mx[n].host)-1);
rerrstr(buf, sizeof buf); mx[nmx].pref = atoi(tpref->val);
if(debug) nmx++;
fprint(2, "dns: %s\n", buf); break;
if(strstr(buf, "dns failure")){ }
/* if dns fails for the mx lookup, we have to stop */ }
close(fd);
return -1;
} }
} else { ndbfree(t);
/*
* get any mx entries
*/
seek(fd, 0, 0);
while(nmx < Nmx && (n = read(fd, buf, sizeof(buf)-1)) > 0){
buf[n] = 0;
if(debug)
fprint(2, "dns mx: %s\n", buf);
n = getfields(buf, fields, 4, 1, " \t");
if(n < 4)
continue;
if(strchr(domain, '.') == 0)
strcpy(domain, fields[0]);
strncpy(mx[nmx].host, fields[3], sizeof(mx[n].host)-1);
mx[nmx].pref = atoi(fields[2]);
nmx++;
}
if(debug)
fprint(2, "dns mx; got %d entries\n", nmx);
} }
/* /*
@ -210,20 +154,16 @@ mxlookup1(DS *ds, char *domain)
* look up all ip addresses * look up all ip addresses
*/ */
for(i = 0; i < nmx; i++){ for(i = 0; i < nmx; i++){
seek(fd, 0, 0); if((t = dnsquery(nil, mx[i].host, "ip")) == nil)
snprint(buf, sizeof buf, "%s ip", mx[i].host);
mx[i].ip[0] = 0;
if(write(fd, buf, strlen(buf)) < 0)
goto no; goto no;
seek(fd, 0, 0); if((tip = ndbfindattr(t, nil, "ip")) == nil){
if((n = read(fd, buf, sizeof buf-1)) < 0) ndbfree(t);
goto no; goto no;
buf[n] = 0; }
if(getfields(buf, fields, 4, 1, " \t") < 3) strncpy(mx[i].ip, tip->val, sizeof(mx[i].ip)-1);
goto no; ndbfree(t);
strncpy(mx[i].ip, fields[2], sizeof(mx[i].ip)-1);
continue; continue;
no: no:
/* remove mx[i] and go around again */ /* remove mx[i] and go around again */
nmx--; nmx--;
@ -274,74 +214,17 @@ dial_string_parse(char *str, DS *ds)
expand_meta(ds); expand_meta(ds);
} }
#if 0 /* jpc */
static void static void
expand_meta(DS *ds) expand_meta(DS *ds)
{ {
char buf[128], cs[128], *net, *p; static Ndb *db;
int fd, n;
net = ds->netdir;
if(!net)
net = "/net";
if(debug)
fprint(2, "expanding %s!%s\n", net, ds->host);
snprint(cs, sizeof(cs), "%s/cs", net);
if((fd = open(cs, ORDWR)) == -1){
if(debug)
fprint(2, "open %s: %r\n", cs);
syslog(0, "smtp", "cannot open %s: %r", cs);
return;
}
snprint(buf, sizeof(buf), "!ipinfo %s", ds->host+1); // +1 to skip $
if(write(fd, buf, strlen(buf)) <= 0){
if(debug)
fprint(2, "write %s: %r\n", cs);
syslog(0, "smtp", "%s to %s - write failed: %r", buf, cs);
close(fd);
return;
}
seek(fd, 0, 0);
if((n = read(fd, ds->expand, sizeof(ds->expand)-1)) < 0){
if(debug)
fprint(2, "read %s: %r\n", cs);
syslog(0, "smtp", "%s - read failed: %r", cs);
close(fd);
return;
}
close(fd);
ds->expand[n] = 0;
if((p = strchr(ds->expand, '=')) == nil){
if(debug)
fprint(2, "response %s: %s\n", cs, ds->expand);
syslog(0, "smtp", "%q from %s - bad response: %r", ds->expand, cs);
return;
}
ds->host = p+1;
/* take only first one returned (quasi-bug) */
if((p = strchr(ds->host, ' ')) != nil)
*p = 0;
}
#endif /* jpc */
/* XXX */
static void
expand_meta(DS *ds)
{
Ndb *db;
Ndbs s; Ndbs s;
char *sys, *smtpserver; char *sys, *smtpserver;
/* can't ask cs, so query database directly. */
sys = sysname(); sys = sysname();
db = ndbopen(unsharp("#9/ndb/local")); if(db == nil)
fprint(2,"%s",ds->host); db = ndbopen(0);
smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil); smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil);
snprint(ds->host,128,"%s",smtpserver); snprint(ds->host, 128, "%s", smtpserver);
fprint(2," exanded to %s\n",ds->host);
} }

View file

@ -1,98 +1,25 @@
/* A Bison parser, made by GNU Bison 2.0. */ #define WORD 57346
#define DATE 57347
/* Skeleton parser for Yacc-like parsing with Bison, #define RESENT_DATE 57348
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. #define RETURN_PATH 57349
#define FROM 57350
This program is free software; you can redistribute it and/or modify #define SENDER 57351
it under the terms of the GNU General Public License as published by #define REPLY_TO 57352
the Free Software Foundation; either version 2, or (at your option) #define RESENT_FROM 57353
any later version. #define RESENT_SENDER 57354
#define RESENT_REPLY_TO 57355
This program is distributed in the hope that it will be useful, #define SUBJECT 57356
but WITHOUT ANY WARRANTY; without even the implied warranty of #define TO 57357
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #define CC 57358
GNU General Public License for more details. #define BCC 57359
#define RESENT_TO 57360
You should have received a copy of the GNU General Public License #define RESENT_CC 57361
along with this program; if not, write to the Free Software #define RESENT_BCC 57362
Foundation, Inc., 59 Temple Place - Suite 330, #define REMOTE 57363
Boston, MA 02111-1307, USA. */ #define PRECEDENCE 57364
#define MIMEVERSION 57365
/* As a special exception, when this file is copied by Bison into a #define CONTENTTYPE 57366
Bison output file, you may use that output file without restriction. #define MESSAGEID 57367
This special exception was added by the Free Software Foundation #define RECEIVED 57368
in version 1.24 of Bison. */ #define MAILER 57369
#define BADTOKEN 57370
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
WORD = 258,
DATE = 259,
RESENT_DATE = 260,
RETURN_PATH = 261,
FROM = 262,
SENDER = 263,
REPLY_TO = 264,
RESENT_FROM = 265,
RESENT_SENDER = 266,
RESENT_REPLY_TO = 267,
SUBJECT = 268,
TO = 269,
CC = 270,
BCC = 271,
RESENT_TO = 272,
RESENT_CC = 273,
RESENT_BCC = 274,
REMOTE = 275,
PRECEDENCE = 276,
MIMEVERSION = 277,
CONTENTTYPE = 278,
MESSAGEID = 279,
RECEIVED = 280,
MAILER = 281,
BADTOKEN = 282
};
#endif
#define WORD 258
#define DATE 259
#define RESENT_DATE 260
#define RETURN_PATH 261
#define FROM 262
#define SENDER 263
#define REPLY_TO 264
#define RESENT_FROM 265
#define RESENT_SENDER 266
#define RESENT_REPLY_TO 267
#define SUBJECT 268
#define TO 269
#define CC 270
#define BCC 271
#define RESENT_TO 272
#define RESENT_CC 273
#define RESENT_BCC 274
#define REMOTE 275
#define PRECEDENCE 276
#define MIMEVERSION 277
#define CONTENTTYPE 278
#define MESSAGEID 279
#define RECEIVED 280
#define MAILER 281
#define BADTOKEN 282
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

View file

@ -5,6 +5,7 @@
#include <libsec.h> #include <libsec.h>
#include <auth.h> #include <auth.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
static char* connect(char*); static char* connect(char*);
static char* dotls(char*); static char* dotls(char*);
@ -59,7 +60,7 @@ void
usage(void) usage(void)
{ {
fprint(2, "usage: smtp [-adips] [-uuser] [-hhost] [.domain] net!host[!service] sender rcpt-list\n"); fprint(2, "usage: smtp [-adips] [-uuser] [-hhost] [.domain] net!host[!service] sender rcpt-list\n");
exits(Giveup); threadexitsall(Giveup);
} }
int int
@ -70,17 +71,16 @@ timeout(void *x, char *msg)
if(strstr(msg, "alarm")){ if(strstr(msg, "alarm")){
fprint(2, "smtp timeout: connection to %s timed out\n", farend); fprint(2, "smtp timeout: connection to %s timed out\n", farend);
if(quitting) if(quitting)
exits(quitrv); threadexitsall(quitrv);
exits(Retry); threadexitsall(Retry);
} }
if(strstr(msg, "closed pipe")){ if(strstr(msg, "closed pipe")){
/* call _exits() to prevent Bio from trying to flush closed pipe */
fprint(2, "smtp timeout: connection closed to %s\n", farend); fprint(2, "smtp timeout: connection closed to %s\n", farend);
if(quitting){ if(quitting){
syslog(0, "smtp.fail", "closed pipe to %s", farend); syslog(0, "smtp.fail", "closed pipe to %s", farend);
_exits(quitrv); threadexitsall(quitrv);
} }
_exits(Retry); threadexitsall(Retry);
} }
return 0; return 0;
} }
@ -96,6 +96,14 @@ removenewline(char *p)
p[n] = 0; p[n] = 0;
} }
int
exitcode(char *s)
{
if(strstr(s, "Retry")) /* known to runq */
return RetryCode;
return 1;
}
void void
threadmain(int argc, char **argv) threadmain(int argc, char **argv)
{ {
@ -171,7 +179,7 @@ threadmain(int argc, char **argv)
if(*argv == 0) if(*argv == 0)
usage(); usage();
addr = *argv++; argc--; addr = *argv++; argc--;
// expand $smtp if necessary XXX // expand $smtp if necessary
addr = expand_addr(addr); addr = expand_addr(addr);
farend = addr; farend = addr;
@ -199,12 +207,12 @@ threadmain(int argc, char **argv)
rv = data(from, &bfile); rv = data(from, &bfile);
if(rv != 0) if(rv != 0)
goto error; goto error;
exits(0); threadexitsall(0);
} }
/* mxdial uses its own timeout handler */ /* mxdial uses its own timeout handler */
if((rv = connect(addr)) != 0) if((rv = connect(addr)) != 0)
exits(rv); threadexitsall(rv);
/* 10 minutes to get through the initial handshake */ /* 10 minutes to get through the initial handshake */
atnotify(timeout, 1); atnotify(timeout, 1);
@ -238,7 +246,7 @@ threadmain(int argc, char **argv)
if(ping){ if(ping){
quit(0); quit(0);
exits(0); threadexitsall(0);
} }
rv = data(from, &bfile); rv = data(from, &bfile);
@ -246,7 +254,7 @@ threadmain(int argc, char **argv)
goto error; goto error;
quit(0); quit(0);
if(rcvrs == ok) if(rcvrs == ok)
exits(0); threadexitsall(0);
/* /*
* here when some but not all rcvrs failed * here when some but not all rcvrs failed
@ -258,7 +266,7 @@ threadmain(int argc, char **argv)
fprint(2, " mail to %s failed: %s", argv[i], errs[i]); fprint(2, " mail to %s failed: %s", argv[i], errs[i]);
} }
} }
exits(Giveup); threadexitsall(Giveup);
/* /*
* here when all rcvrs failed * here when all rcvrs failed
@ -271,7 +279,7 @@ error:
fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply)); fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply));
if(!filter) if(!filter)
quit(rv); quit(rv);
exits(rv); threadexitsall(rv);
} }
/* /*
@ -319,6 +327,8 @@ dotls(char *me)
int fd; int fd;
uchar hash[SHA1dlen]; uchar hash[SHA1dlen];
return Giveup;
c = mallocz(sizeof(*c), 1); /* Note: not freed on success */ c = mallocz(sizeof(*c), 1); /* Note: not freed on success */
if (c == nil) if (c == nil)
return Giveup; return Giveup;
@ -1097,27 +1107,44 @@ dBputc(int x)
return Bputc(&bout, x); return Bputc(&bout, x);
} }
/* XXX */
char* char*
expand_addr(char* a) expand_addr(char *addr)
{ {
static char buf[256];
char *p, *q, *name, *sys;
Ndbtuple *t;
Ndb *db; Ndb *db;
Ndbs s;
char *sys, *ret, *proto, *host; p = strchr(addr, '!');
if(p){
proto = strtok(a,"!"); q = strchr(p+1, '!');
if ( strcmp(proto,"net") != 0 ) { name = p+1;
fprint(2,"unknown proto %s\n",proto); }else{
name = addr;
q = nil;
} }
host = strtok(0,"!");
if ( strcmp(host,"$smtp") == 0 ) { if(name[0] != '$')
sys = sysname(); return addr;
db = ndbopen(unsharp("#9/ndb/local")); name++;
host = ndbgetvalue(db, &s, "sys", sys, "smtp", nil); if(q)
*q = 0;
sys = sysname();
db = ndbopen(0);
t = ndbipinfo(db, "sys", sys, &name, 1);
if(t == nil){
ndbclose(db);
if(q)
*q = '!';
return addr;
} }
ret = malloc(strlen(proto)+strlen(host)+2);
sprint(ret,"%s!%s",proto,host); *(name-1) = 0;
if(q)
return ret; *q = '!';
else
q = "";
snprint(buf, sizeof buf, "%s%s%s", addr, t->val, q);
return buf;
} }

View file

@ -7,6 +7,7 @@
#include <mp.h> #include <mp.h>
#include <libsec.h> #include <libsec.h>
#include <auth.h> #include <auth.h>
#include <thread.h>
#include "../smtp/rfc822.tab.h" #include "../smtp/rfc822.tab.h"
#define DBGMX 1 #define DBGMX 1
@ -84,11 +85,11 @@ s_error(char *f, char *status)
else else
reply("452 out of memory %s\r\n", errbuf); reply("452 out of memory %s\r\n", errbuf);
syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys); syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys);
exits(status); threadexitsall(status);
} }
void void
main(int argc, char **argv) threadmain(int argc, char **argv)
{ {
char *p, buf[1024]; char *p, buf[1024];
char *netdir; char *netdir;
@ -137,6 +138,8 @@ main(int argc, char **argv)
passwordinclear = 1; passwordinclear = 1;
break; break;
case 'c': case 'c':
fprint(2, "tls is not available\n");
threadexitsall("no tls");
tlscert = ARGF(); tlscert = ARGF();
break; break;
case 't': case 't':
@ -145,7 +148,7 @@ main(int argc, char **argv)
break; break;
default: default:
fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n"); fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n");
exits("usage"); threadexitsall("usage");
}ARGEND; }ARGEND;
nci = getnetconninfo(netdir, 0); nci = getnetconninfo(netdir, 0);
@ -179,7 +182,7 @@ main(int argc, char **argv)
atnotify(catchalarm, 1); atnotify(catchalarm, 1);
alarm(45*60*1000); alarm(45*60*1000);
zzparse(); zzparse();
exits(0); threadexitsall(0);
} }
void void
@ -276,7 +279,7 @@ hello(String *himp, int extended)
syslog(0, "smtpd", "Hung up on %s; claimed to be %s", syslog(0, "smtpd", "Hung up on %s; claimed to be %s",
nci->rsys, him); nci->rsys, him);
reply("554 Liar!\r\n"); reply("554 Liar!\r\n");
exits("client pretended to be us"); threadexitsall("client pretended to be us");
return; return;
} }
} }
@ -533,7 +536,7 @@ quit(void)
{ {
reply("221 Successful termination\r\n"); reply("221 Successful termination\r\n");
close(0); close(0);
exits(0); threadexitsall(0);
} }
void void
@ -1063,6 +1066,7 @@ sendermxcheck(void)
char *who; char *who;
int pid; int pid;
Waitmsg *w; Waitmsg *w;
static char *validate;
who = s_to_c(senders.first->p); who = s_to_c(senders.first->p);
if(strcmp(who, "/dev/null") == 0){ if(strcmp(who, "/dev/null") == 0){
@ -1074,7 +1078,9 @@ sendermxcheck(void)
return 0; return 0;
} }
if(access("/mail/lib/validatesender", AEXEC) < 0) if(validate == nil)
validate = unsharp("#9/mail/lib/validatesender");
if(access(validate, AEXEC) < 0)
return 0; return 0;
senddom = strdup(who); senddom = strdup(who);
@ -1095,9 +1101,9 @@ sendermxcheck(void)
* Could add an option with the remote IP address * Could add an option with the remote IP address
* to allow validatesender to implement SPF eventually. * to allow validatesender to implement SPF eventually.
*/ */
execl("/mail/lib/validatesender", "validatesender", execl(validate, "validatesender",
"-n", nci->root, senddom, user, nil); "-n", nci->root, senddom, user, nil);
_exits("exec validatesender: %r"); threadexitsall("exec validatesender: %r");
default: default:
break; break;
} }
@ -1265,7 +1271,7 @@ rejectcheck(void)
if(rejectcount > MAXREJECTS){ if(rejectcount > MAXREJECTS){
syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys); syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys);
reply("554 too many errors. transaction failed.\r\n"); reply("554 too many errors. transaction failed.\r\n");
exits("errcount"); threadexitsall("errcount");
} }
if(hardreject){ if(hardreject){
rejectcount++; rejectcount++;
@ -1344,7 +1350,7 @@ starttls(void)
/* force the client to hang up */ /* force the client to hang up */
close(Bfildes(&bin)); /* probably fd 0 */ close(Bfildes(&bin)); /* probably fd 0 */
close(1); close(1);
exits("tls failed"); threadexitsall("tls failed");
} }
Bterm(&bin); Bterm(&bin);
Binit(&bin, fd, OREAD); Binit(&bin, fd, OREAD);