summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacek Masiulaniec <jacekm@cvs.openbsd.org>2009-03-09 23:35:05 +0000
committerJacek Masiulaniec <jacekm@cvs.openbsd.org>2009-03-09 23:35:05 +0000
commitf4214c6b1d0e13d5695fa4f5790970f25bccf189 (patch)
treedbb959d8e29abab923d481ffb9f6eebb691a6c3c
parent3107c7f02b22c8d6b9393f1d1baa1d716938f77a (diff)
run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@
-rw-r--r--usr.sbin/smtpd/smtpd.c11
-rw-r--r--usr.sbin/smtpd/smtpd.h10
-rw-r--r--usr.sbin/smtpd/util.c33
3 files changed, 50 insertions, 4 deletions
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 6d3217e8683..c9f491333ec 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.42 2009/03/08 17:54:20 gilles Exp $ */
+/* $OpenBSD: smtpd.c,v 1.43 2009/03/09 23:35:04 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -1093,6 +1093,8 @@ parent_external_mda(char *path, struct passwd *pw, struct batch *batchp)
{
pid_t pid;
int pipefd[2];
+ arglist args;
+ char *word;
struct mdaproc *mdaproc;
log_debug("executing filter as user: %s", pw->pw_name);
@@ -1125,12 +1127,17 @@ parent_external_mda(char *path, struct passwd *pw, struct batch *batchp)
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("mta: cannot drop privileges");
+ bzero(&args, sizeof(args));
+ while ((word = strsep(&path, " \t")) != NULL)
+ if (*word != '\0')
+ addargs(&args, "%s", word);
+
close(pipefd[0]);
close(STDOUT_FILENO);
close(STDERR_FILENO);
dup2(pipefd[1], 0);
- execlp(_PATH_BSHELL, "sh", "-c", path, (void *)NULL);
+ execvp(args.list[0], args.list);
_exit(1);
}
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 9e2cbe537a8..0c1ba8fe063 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.88 2009/03/09 16:31:09 jacekm Exp $ */
+/* $OpenBSD: smtpd.h,v 1.89 2009/03/09 23:35:04 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -939,6 +939,14 @@ struct map *map_find(struct smtpd *, objid_t);
struct map *map_findbyname(struct smtpd *, const char *);
/* util.c */
+typedef struct arglist arglist;
+struct arglist {
+ char **list;
+ u_int num;
+ u_int nalloc;
+};
+void addargs(arglist *, char *, ...)
+ __attribute__((format(printf, 2, 3)));
int bsnprintf(char *, size_t, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
int safe_fclose(FILE *);
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index ed7462eba85..27e76c6f47d 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.16 2009/03/01 21:58:53 jacekm Exp $ */
+/* $OpenBSD: util.c,v 1.17 2009/03/09 23:35:04 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -311,3 +311,34 @@ secure_file(int fd, char *path, struct passwd *pw)
return 1;
}
+
+void
+addargs(arglist *args, char *fmt, ...)
+{
+ va_list ap;
+ char *cp;
+ u_int nalloc;
+ int r;
+
+ va_start(ap, fmt);
+ r = vasprintf(&cp, fmt, ap);
+ va_end(ap);
+ if (r == -1)
+ fatal("addargs: argument too long");
+
+ nalloc = args->nalloc;
+ if (args->list == NULL) {
+ nalloc = 32;
+ args->num = 0;
+ } else if (args->num+2 >= nalloc)
+ nalloc *= 2;
+
+ if (SIZE_T_MAX / nalloc < sizeof(char *))
+ fatalx("addargs: nalloc * size > SIZE_T_MAX");
+ args->list = realloc(args->list, nalloc * sizeof(char *));
+ if (args->list == NULL)
+ fatal("addargs: realloc");
+ args->nalloc = nalloc;
+ args->list[args->num++] = cp;
+ args->list[args->num] = NULL;
+}