| t@@ -9,6 +9,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
t@@ -115,7 +117,7 @@ mlfi_helo(SMFICTX *ctx, char *helohost)
return SMFIS_CONTINUE;
}
- switch((pid = fork())) {
+ switch ((pid = fork())) {
case 0:
while(dup2(priv->execpipe[0], 0) < 0 && errno == EINTR);
close(priv->execpipe[1]);
t@@ -330,26 +332,66 @@ struct smfiDesc smfilter =
};
void
+sighandler(int sig)
+{
+ int i;
+
+ switch (sig) {
+ case SIGCHLD:
+ while (waitpid(-1, NULL, WNOHANG) > 0);
+ break;
+ case SIGINT:
+ case SIGQUIT:
+ case SIGABRT:
+ case SIGTERM:
+ case SIGKILL:
+ smfi_stop();
+ break;
+ default:
+ break;
+ }
+}
+
+void
+initsignals(void)
+{
+ signal(SIGCHLD, sighandler);
+ signal(SIGHUP, sighandler);
+ signal(SIGINT, sighandler);
+ signal(SIGQUIT, sighandler);
+ signal(SIGABRT, sighandler);
+ signal(SIGTERM, sighandler);
+ signal(SIGKILL, sighandler);
+
+ /*
+ * done by smfi_main():
+ * signal(SIGPIPE, SIG_IGN);
+ */
+}
+
+void
usage(char *argv0)
{
fprintf(stderr,
- "Usage: %s [-h] [-d dbglvl] [-p listen] [-t timeout]\n",
+ "Usage: %s [-hd] [-v dbglvl] [-p listen] [-t timeout] "
+ "[-u user] [-g group]\n",
argv0);
}
int
main(int argc, char *argv[])
{
- char *argv0, *port;
- int timeout;
-
- port = "inet:9957";
- timeout = -1;
+ char *argv0, *user = NULL, *group = NULL, *port = "inet:9957";
+ int timeout = -1, dofork = 1;
+ struct passwd *us = NULL;
+ struct group *gr = NULL;
ARGBEGIN(argv0) {
case 'd':
- smfi_setdbg(atoi(EARGF(argv0)));
- dodebug = 1;
+ dofork = 0;
+ break;
+ case 'g':
+ group = EARGF(usage(argv0));
break;
case 'p':
port = EARGF(usage(argv0));
t@@ -357,11 +399,70 @@ main(int argc, char *argv[])
case 't':
timeout = atoi(EARGF(usage(argv0)));
break;
+ case 'u':
+ user = EARGF(usage(argv0));
+ break;
+ case 'v':
+ smfi_setdbg(atoi(EARGF(argv0)));
+ dodebug = 1;
+ break;
default:
usage(argv0);
return 1;
} ARGEND;
+ if (group != NULL) {
+ errno = 0;
+ if ((gr = getgrnam(group)) == NULL) {
+ if (errno == 0) {
+ fprintf(stderr, "no such group '%s'\n",
+ group);
+ } else {
+ perror("getgrnam");
+ }
+ return 1;
+ }
+ }
+
+ if (user != NULL) {
+ errno = 0;
+ if ((us = getpwnam(user)) == NULL) {
+ if (errno == 0) {
+ fprintf(stderr, "no such user '%s'\n",
+ user);
+ } else {
+ perror("getpwnam");
+ }
+ return 1;
+ }
+ }
+
+ if (dofork) {
+ switch (fork()) {
+ case -1:
+ perror("fork");
+ return 1;
+ case 0:
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ if (gr != NULL) {
+ if (setgroups(1, &gr->gr_gid) != 0 || setgid(gr->gr_gid) != 0)
+ return -1;
+ }
+ if (us != NULL) {
+ if (gr == NULL) {
+ if (setgroups(1, &us->pw_gid) != 0 ||
+ setgid(us->pw_gid) != 0)
+ return -1;
+ }
+ if (setuid(us->pw_uid) != 0)
+ return -1;
+ }
+
if (smfi_setconn(port) == MI_FAILURE) {
perror("smfi_setconn");
return 1; |