diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 11 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 10 | ||||
-rw-r--r-- | usr.sbin/smtpd/util.c | 33 |
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; +} |