--- tftpd/remap.c.orig 2008-06-12 12:13:30.000000000 -0400 +++ tftpd/remap.c 2008-06-12 12:11:28.000000000 -0400 @@ -19,21 +19,24 @@ #include #include #include - +#include #include "tftpd.h" #include "remap.h" +#include + #define DEADMAN_MAX_STEPS 1024 /* Timeout after this many steps */ #define MAXLINE 16384 /* Truncate a line at this many bytes */ -#define RULE_REWRITE 0x01 /* This is a rewrite rule */ -#define RULE_GLOBAL 0x02 /* Global rule (repeat until no match) */ -#define RULE_EXIT 0x04 /* Exit after matching this rule */ -#define RULE_RESTART 0x08 /* Restart at the top after matching this rule */ -#define RULE_ABORT 0x10 /* Terminate processing with an error */ -#define RULE_GETONLY 0x20 /* Applicable to GET only */ -#define RULE_PUTONLY 0x40 /* Applicable to PUT only */ -#define RULE_INVERSE 0x80 /* Execute if regex *doesn't* match */ +#define RULE_REWRITE 0x001 /* This is a rewrite rule */ +#define RULE_GLOBAL 0x002 /* Global rule (repeat until no match) */ +#define RULE_EXIT 0x004 /* Exit after matching this rule */ +#define RULE_RESTART 0x008 /* Restart at the top after matching this rule */ +#define RULE_ABORT 0x010 /* Terminate processing with an error */ +#define RULE_GETONLY 0x020 /* Applicable to GET only */ +#define RULE_PUTONLY 0x040 /* Applicable to PUT only */ +#define RULE_INVERSE 0x080 /* Execute if regex *doesn't* match */ +#define RULE_EXECUTE 0x100 /* run command */ struct rule { struct rule *next; @@ -211,6 +214,9 @@ case 'a': r->rule_flags |= RULE_ABORT; break; + case 'x': + r->rule_flags |= RULE_EXECUTE; + break; case 'i': rxflags |= REG_ICASE; break; @@ -327,9 +333,9 @@ const struct rule *ruleptr = rules; regmatch_t pmatch[10]; int len; + pid_t execPID; int was_match = 0; int deadman = DEADMAN_MAX_STEPS; - /* Default error */ *errmsg = "Remap table failure"; @@ -396,6 +402,24 @@ ruleptr->nrule, current); } } + if ( ruleptr->rule_flags & RULE_EXECUTE ) + { + execPID = fork(); + if(execPID == 0) + { + syslog(LOG_INFO, "execute rule match, running: %s %s", ruleptr->pattern, current); + execl(ruleptr->pattern, ruleptr->pattern, current, NULL); + } + else + { + syslog(LOG_INFO, "Created process %d", execPID); + } + syslog(LOG_INFO, "waiting for process %d to exit", execPID); + waitpid(execPID, NULL, 0); + syslog(LOG_INFO, "Process %d to exited", execPID); + } + + } else { break; /* No match, terminate unconditionally */ }