1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
diff -ruNp tcp_wrappers_7.6.orig/hosts_access.c tcp_wrappers_7.6/hosts_access.c
--- tcp_wrappers_7.6.orig/hosts_access.c 2006-03-01 19:25:45.000000000 +0100
+++ tcp_wrappers_7.6/hosts_access.c 2006-03-01 19:23:58.000000000 +0100
@@ -82,6 +82,9 @@ int hosts_access_verbose = 0;
*/
int resident = (-1); /* -1, 0: unknown; +1: yes */
+#ifdef ACLEXEC
+int aclexec_matched = 0;
+#endif
/* Forward declarations. */
@@ -185,6 +188,12 @@ struct request_info *request;
if (sh_cmd) {
#ifdef PROCESS_OPTIONS
process_options(sh_cmd, request);
+# ifdef ACLEXEC
+ if (aclexec_matched) {
+ syslog(LOG_INFO, "aclexec returned %d", aclexec_matched);
+ match = NO;
+ }
+# endif
#else
char cmd[BUFSIZ];
shell_cmd(percent_x(cmd, sizeof(cmd), sh_cmd, request));
diff -ruNp tcp_wrappers_7.6.orig/options.c tcp_wrappers_7.6/options.c
--- tcp_wrappers_7.6.orig/options.c 1996-02-11 17:01:32.000000000 +0100
+++ tcp_wrappers_7.6/options.c 2006-03-01 19:24:25.000000000 +0100
@@ -47,6 +47,7 @@ static char sccsid[] = "@(#) options.c 1
#include <ctype.h>
#include <setjmp.h>
#include <string.h>
+#include <sys/wait.h>
#ifndef MAXPATHNAMELEN
#define MAXPATHNAMELEN BUFSIZ
@@ -76,6 +77,7 @@ static void group_option(); /* execute
static void umask_option(); /* execute "umask mask" option */
static void linger_option(); /* execute "linger time" option */
static void keepalive_option(); /* execute "keepalive" option */
+static void aclexec_option(); /* execute "aclexec command" option */
static void spawn_option(); /* execute "spawn command" option */
static void twist_option(); /* execute "twist command" option */
static void rfc931_option(); /* execute "rfc931" option */
@@ -113,6 +115,9 @@ static struct option option_table[] = {
"umask", umask_option, NEED_ARG,
"linger", linger_option, NEED_ARG,
"keepalive", keepalive_option, 0,
+#ifdef ACLEXEC
+ "aclexec", aclexec_option, NEED_ARG | EXPAND_ARG,
+#endif
"spawn", spawn_option, NEED_ARG | EXPAND_ARG,
"twist", twist_option, NEED_ARG | EXPAND_ARG | USE_LAST,
"rfc931", rfc931_option, OPT_ARG,
@@ -310,6 +315,54 @@ struct request_info *request;
shell_cmd(value);
}
+#ifdef ACLEXEC
+/* aclexec_option - spawn a shell command and check status */
+
+/* ARGSUSED */
+
+static void aclexec_option(value, request)
+char *value;
+struct request_info *request;
+{
+ int status, child_pid, wait_pid;
+ extern int aclexec_matched;
+
+ if (dry_run != 0)
+ return;
+
+ child_pid = fork();
+
+ /* Something went wrong: we MUST terminate the process. */
+ if (child_pid < 0) {
+ tcpd_warn("aclexec_option: /bin/sh: %m");
+ clean_exit(request);
+ }
+
+ if (child_pid == 0) {
+ execl("/bin/sh", "sh", "-c", value, (char *) 0);
+
+ /* Something went wrong. We MUST terminate the child process. */
+ tcpd_warn("execl /bin/sh: %m");
+ _exit(0);
+ }
+
+ while ((wait_pid = wait(&status)) != -1 && wait_pid != child_pid)
+ /* void */ ;
+
+ aclexec_matched = 1;
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ aclexec_matched = 0;
+ }
+
+ if (WIFSIGNALED(status))
+ tcpd_warn("process %d exited with signal %d", child_pid,
+ WTERMSIG(status));
+
+ return;
+}
+#endif
+
/* linger_option - set the socket linger time (Marc Boucher <marc@cam.org>) */
/* ARGSUSED */
diff -ruNp tcp_wrappers_7.6.orig/hosts_options.5 tcp_wrappers_7.6/hosts_options.5
--- tcp_wrappers_7.6.orig/hosts_options.5 2006-03-01 21:48:43.000000000 +0100
+++ tcp_wrappers_7.6/hosts_options.5 2006-03-01 21:47:39.000000000 +0100
@@ -52,6 +52,23 @@ ALL: ALL: ALLOW
.sp
Notice the leading dot on the domain name patterns.
.SH RUNNING OTHER COMMANDS
+.IP "aclexec shell_command"
+Execute, in a child process, the specified shell command, after
+performing the %<letter> expansions described in the hosts_access(5)
+manual page. The command is executed with stdin, stdout and stderr
+connected to the null device, so that it won't mess up the
+conversation with the client host. Example:
+.sp
+.nf
+.ti +3
+smtp : ALL : aclexec checkdnsbl %a
+.fi
+.sp
+executes, in a background child process, the shell command "checkdnsbl %a"
+after replacing %a by the address of the remote host.
+.sp
+The connection will be allowed or refused depending on whether the
+command returns a true or false exit status.
.IP "spawn shell_command"
Execute, in a child process, the specified shell command, after
performing the %<letter> expansions described in the hosts_access(5)
|