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