X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/28d2517c9cd3a1c6b21d0db91b93e01e9a84ed39..367d81afe3d72b6bc1519d2ae2187a6535370025:/exec.c diff --git a/exec.c b/exec.c index d81aeae..d41a31d 100644 --- a/exec.c +++ b/exec.c @@ -1,96 +1,30 @@ /* -*-c-*- * - * $Id: exec.c,v 1.2 1999/10/22 22:46:17 mdw Exp $ - * * Source and target for executable programs * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * - * This file is part of the `fw' port forwarder. + * This file is part of the `fwd' port forwarder. * - * `fw' is free software; you can redistribute it and/or modify + * `fwd' is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * `fw' is distributed in the hope that it will be useful, + * + * `fwd' is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with `fw'; if not, write to the Free Software Foundation, + * along with `fwd'; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: exec.c,v $ - * Revision 1.2 1999/10/22 22:46:17 mdw - * When a non-file endpoint is attached to a file, keep the file endpoint - * open until the nonfile is done. This stops socket sources from - * resetting their connection limits too early. - * - * Revision 1.1 1999/07/26 23:33:32 mdw - * New sources and targets. - * - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "config.h" - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef HAVE_SETRLIMIT -# include -#endif - -#ifndef DECL_ENVIRON - extern char **environ; -#endif - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "endpt.h" -#include "exec.h" -#include "fattr.h" -#include "fw.h" -#include "reffd.h" -#include "scan.h" -#include "source.h" -#include "target.h" +#include "fwd.h" /*----- Data structures ---------------------------------------------------*/ @@ -99,8 +33,9 @@ #ifdef HAVE_SETRLIMIT typedef struct xlimit { -#define R(r, n) struct rlimit n; -#include "rlimits.h" +#define XLIMIT_ENTRY(name, constant) struct rlimit name; + RLIMITS(XLIMIT_ENTRY) +#undef XLIMIT_ENTRY } xlimit; #endif @@ -152,7 +87,7 @@ typedef struct xept { struct xept *next, *prev; pid_t kid; endpt *f; - const char *desc; + char *desc; int st; xargs *xa; xopts *xo; @@ -204,8 +139,10 @@ typedef struct rlimit_ent { } rlimit_ent; static rlimit_ent rlimits[] = { -#define R(r, n) { #n, #r, r, offsetof(xlimit, n) }, -#include "rlimits.h" +#define TABLE_ENTRY(name, constant) \ + { #name, #constant, constant, offsetof(xlimit, name) }, + RLIMITS(TABLE_ENTRY) +#undef TABLE_ENTRY { 0, 0, 0, 0 } }; @@ -335,8 +272,9 @@ static int rlimit_option(xlimit *xl, scanner *sc) break; case w_soft: if (v > rl->rlim_max) - error(sc, "soft limit %l exceeds hard limit %l for %s", - v, rl->rlim_max, chosen->rname); + error(sc, "soft limit %lu exceeds hard limit %lu for %s", + (unsigned long)v, (unsigned long)rl->rlim_max, + chosen->rname); rl->rlim_cur = v; break; case w_hard: @@ -465,9 +403,9 @@ static void xenv_destroy(xenv *xe) while (xe) { xenv *xxe = xe; xe = xe->next; - free(xxe->name); + xfree(xxe->name); if (xxe->value) - free(xxe->value); + xfree(xxe->value); DESTROY(xxe); } } @@ -488,7 +426,7 @@ static void x_tidy(xargs *xa, xopts *xo) { xa->ref--; if (!xa->ref) - free(xa); + xfree(xa); xo->ref--; if (!xo->ref) { @@ -501,7 +439,7 @@ static void x_tidy(xargs *xa, xopts *xo) /* --- @attach@ --- */ -static void xept_error(char */*p*/, void */*v*/); +static void xept_error(char */*p*/, size_t /*len*/, void */*v*/); static void xept_attach(endpt *e, reffd *in, reffd *out) { @@ -512,7 +450,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) /* --- Make a pipe for standard error --- */ if (pipe(fd)) { - fw_log(-1, "[%s] couldn't create pipe: %s", xe->desc, strerror(errno)); + fw_log(NOW, "[%s] couldn't create pipe: %s", xe->desc, strerror(errno)); return; } fdflags(fd[0], O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC); @@ -520,7 +458,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) /* --- Fork a child, and handle an error if there was one --- */ if ((kid = fork()) == -1) { - fw_log(-1, "[%s] couldn't fork: %s", xe->desc, strerror(errno)); + fw_log(NOW, "[%s] couldn't fork: %s", xe->desc, strerror(errno)); close(fd[0]); close(fd[1]); return; @@ -530,6 +468,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) if (kid == 0) { xopts *xo = xe->xo; + mdup_fd md[3]; /* --- Fiddle with the file descriptors --- * * @@ -539,18 +478,14 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) */ close(fd[0]); - if (dup2(in->fd, STDIN_FILENO) < 0 || - dup2(out->fd, STDOUT_FILENO) < 0 || - dup2(fd[1], STDERR_FILENO) < 0) { + md[0].cur = in->fd; md[0].want = STDIN_FILENO; + md[1].cur = out->fd; md[1].want = STDOUT_FILENO; + md[2].cur = fd[1]; md[2].want = STDERR_FILENO; + if (mdup(md, 3)) { moan("couldn't manipulate file descriptors: %s", strerror(errno)); _exit(1); } - if (in->fd > 2) - close(in->fd); - if (out->fd > 2) - close(out->fd); - fdflags(STDIN_FILENO, O_NONBLOCK, 0, FD_CLOEXEC, 0); fdflags(STDOUT_FILENO, O_NONBLOCK, 0, FD_CLOEXEC, 0); fdflags(STDERR_FILENO, O_NONBLOCK, 0, FD_CLOEXEC, 0); @@ -579,7 +514,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) /* --- Set group id --- */ - if (xo->gid != -1) { + if (xo->gid != (gid_t)-1) { if (setgid(xo->gid)) { moan("couldn't set gid %i: %s", xo->gid, strerror(errno)); _exit(1); @@ -593,7 +528,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) /* --- Set uid --- */ - if (xo->uid != -1) { + if (xo->uid != (uid_t)-1) { if (setuid(xo->uid)) { moan("couldn't set uid %i: %s", xo->uid, strerror(errno)); _exit(1); @@ -628,7 +563,7 @@ static void xept_attach(endpt *e, reffd *in, reffd *out) xept_list->prev = xe; xept_list = xe; if (!(xe->xo->f & XF_NOLOG)) - fw_log(-1, "[%s] started with pid %i", xe->desc, kid); + fw_log(NOW, "[%s] started with pid %i", xe->desc, kid); fw_inc(); return; } @@ -665,9 +600,9 @@ static void xept_destroy(xept *xe) /* Nothin' doin' */; else if (WIFEXITED(xe->st)) { if (WEXITSTATUS(xe->st) == 0) - fw_log(-1, "[%s] pid %i exited successfully", xe->desc, xe->kid); + fw_log(NOW, "[%s] pid %i exited successfully", xe->desc, xe->kid); else { - fw_log(-1, "[%s] pid %i failed: status %i", + fw_log(NOW, "[%s] pid %i failed: status %i", xe->desc, xe->kid, WEXITSTATUS(xe->st)); } } else if (WIFSIGNALED(xe->st)) { @@ -681,9 +616,10 @@ static void xept_destroy(xept *xe) sprintf(buf, "signal %i", WTERMSIG(xe->st)); s = buf; #endif - fw_log(-1, "[%s] pid %i failed: %s", xe->desc, xe->kid, s); + fw_log(NOW, "[%s] pid %i failed: %s", xe->desc, xe->kid, s); } else - fw_log(-1, "[%s] pid %i failed: unrecognized status", xe->desc, xe->kid); + fw_log(NOW, "[%s] pid %i failed: unrecognized status", + xe->desc, xe->kid); /* --- Free up the parent-side resources --- */ @@ -694,6 +630,7 @@ static void xept_destroy(xept *xe) else xept_list = xe->next; + xfree(xe->desc); if (xe->f) xe->f->ops->close(xe->f); x_tidy(xe->xa, xe->xo); @@ -735,6 +672,7 @@ static void xept_chld(int n, void *p) /* --- @xept_error@ --- * * * Arguments: @char *p@ = pointer to string read from stderr + * @size_t len@ = length of the string * @void *v@ = pointer to by endpoint * * Returns: --- @@ -742,14 +680,14 @@ static void xept_chld(int n, void *p) * Use: Handles error reports from a child process. */ -static void xept_error(char *p, void *v) +static void xept_error(char *p, size_t len, void *v) { xept *xe = v; if (p) - fw_log(-1, "[%s] pid %i: %s", xe->desc, xe->kid, p); + fw_log(NOW, "[%s] pid %i: %s", xe->desc, xe->kid, p); else { - selbuf_disable(&xe->err); close(xe->err.reader.fd); + selbuf_destroy(&xe->err); xe->e.f |= XEF_CLOSE; if (xe->e.f & XEF_EXIT) xept_destroy(xe); @@ -773,7 +711,9 @@ static endpt_ops xept_ops = { xept_attach, xept_file, 0, xept_close }; void exec_init(void) { +#ifdef HAVE_SETRLIMIT rlimit_get(&exec_opts.xl); +#endif sig_add(&xept_sig, SIGCHLD, xept_chld, 0); sym_create(&env); env_import(&env, environ); @@ -814,7 +754,7 @@ static int exec_option(xdata *x, scanner *sc) token(sc); if (sc->t == '=') token(sc); - conf_name(sc, '/', &d); + conf_fname(sc, &d); xo->dir = xstrdup(d.buf); dstr_destroy(&d); CONF_ACCEPT; @@ -823,12 +763,12 @@ static int exec_option(xdata *x, scanner *sc) /* --- Set a chroot prison --- */ if (strcmp(sc->d.buf, "root") == 0 || - strcmp(sc->d.buf, "chroot") == 0) { + strcmp(sc->d.buf, "chroot") == 0) { dstr d = DSTR_INIT; token(sc); if (sc->t == '=') token(sc); - conf_name(sc, '/', &d); + conf_fname(sc, &d); xo->root = xstrdup(d.buf); dstr_destroy(&d); CONF_ACCEPT; @@ -878,8 +818,10 @@ static int exec_option(xdata *x, scanner *sc) /* --- Now try resource limit settings --- */ +#ifdef HAVE_SETRLIMIT if (rlimit_option(&xo->xl, sc)) CONF_ACCEPT; +#endif /* --- And then environment settings --- */ @@ -957,8 +899,12 @@ static void exec_read(xdata *x, scanner *sc) char *p, *q; char **v; - /* --- Strip off the leading `[' --- */ + /* --- Strip off the leading `[' --- * + * + * Allow various handy filename characters to be entered without quoting. + */ + conf_undelim(sc, "=:/.", "=:/."); token(sc); /* --- Read a sequence of arguments --- */ @@ -968,6 +914,7 @@ static void exec_read(xdata *x, scanner *sc) token(sc); argc++; } + conf_undelim(sc, 0, 0); /* --- Expect the closing `]' --- */ @@ -1026,7 +973,7 @@ static endpt *exec_endpt(xdata *x, const char *desc) xe->xo = x->xo; xe->xo->ref++; xe->kid = -1; xe->f = 0; - xe->desc = desc; + xe->desc = xstrdup(desc); return (&xe->e); } @@ -1090,7 +1037,7 @@ static void xsource_attach(source *s, scanner *sc, target *t) ee->ops->close(ee); goto tidy; } - endpt_join(e, ee); + endpt_join(e, ee, xs->s.desc); /* --- Dispose of source and target --- */ @@ -1104,6 +1051,7 @@ tidy: static void xsource_destroy(source *s) { xsource *xs = (xsource *)s; + xfree(xs->s.desc); exec_destroy(&xs->x); DESTROY(xs); } @@ -1157,6 +1105,7 @@ static endpt *xtarget_create(target *t, const char *desc) static void xtarget_destroy(target *t) { xtarget *xt = (xtarget *)t; + xfree(xt->t.desc); exec_destroy(&xt->x); DESTROY(xt); } @@ -1165,7 +1114,7 @@ static void xtarget_destroy(target *t) target_ops xtarget_ops = { "exec", - xtarget_option, xtarget_read, xtarget_create, xtarget_destroy + xtarget_option, xtarget_read, 0, xtarget_create, xtarget_destroy }; /*----- That's all, folks -------------------------------------------------*/