123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- diff -urN dhcp-3.0.2.orig/common/conflex.c dhcp-3.0.2/common/conflex.c
- --- dhcp-3.0.2.orig/common/conflex.c 2004-11-24 10:39:15.000000000 -0700
- +++ dhcp-3.0.2/common/conflex.c 2005-02-24 12:32:12.000000000 -0700
- @@ -676,6 +676,8 @@
- return EVAL;
- if (!strcasecmp (atom + 1, "ncapsulate"))
- return ENCAPSULATE;
- + if (!strcasecmp (atom + 1, "xecute"))
- + return EXECUTE;
- break;
- case 'f':
- if (!strcasecmp (atom + 1, "atal"))
- diff -urN dhcp-3.0.2.orig/common/dhcp-eval.5 dhcp-3.0.2/common/dhcp-eval.5
- --- dhcp-3.0.2.orig/common/dhcp-eval.5 2005-01-19 13:00:52.000000000 -0700
- +++ dhcp-3.0.2/common/dhcp-eval.5 2005-02-24 12:32:12.000000000 -0700
- @@ -409,7 +409,32 @@
- Rebind - DHCP client is in the REBINDING state - it has an IP address,
- and is trying to contact any server to renew it. The next message to
- be sent will be a DHCPREQUEST, which will be broadcast.
- -.RE
- +.PP
- +.B execute (\fIcommand-path\fB, \fIdata-expr1\fB ... \fIdata-exprN\fB)\fR
- +.PP
- +External command execution is possibly through execute expressions. Execute
- +takes a variable number of arguments, where the first is the command
- +name (full path or only the name of the executable) and following zero
- +or more are data-expressions which values will be passed as external
- +arguments. It returns the return code of the external command.
- +.PP
- +Execute is synchronous, and the program will block until the external
- +command being run has finished. Please note that lengthy program
- +execution (for example, in an "on commit" in the dhcpd) may result in
- +bad performance and timed out clients. Try keeping the execution times
- +short.
- +.PP
- +Passing user-supplied data might be dangerous. Check input buffers
- +and make sure the external command handles all kinds of "unusual"
- +characters (shell special characters in sh-scripts etc) correctly.
- +.PP
- +It is possible to use the execute expression in any context, not only
- +on events. If you put it in a regular scope in the configuration file
- +you will execute that command every time a scope is evaluated.
- +.PP
- +The execute expression is only available if you have defined ENABLE_EXECUTE
- +in site.h before compilation.
- +RE
- .SH REFERENCE: LOGGING
- Logging statements may be used to send information to the standard logging
- channels. A logging statement includes an optional priority (\fBfatal\fR,
- diff -urN dhcp-3.0.2.orig/common/parse.c dhcp-3.0.2/common/parse.c
- --- dhcp-3.0.2.orig/common/parse.c 2004-09-30 14:38:31.000000000 -0600
- +++ dhcp-3.0.2/common/parse.c 2005-02-24 12:32:12.000000000 -0700
- @@ -3639,7 +3639,56 @@
- return 0;
- }
- break;
- -
- + #ifdef ENABLE_EXECUTE
- + case EXECUTE:
- + token = next_token (&val, (unsigned *)0, cfile);
- +
- + if (!expression_allocate (expr, MDL))
- + log_fatal ("can't allocate expression.");
- +
- + token = next_token (&val, (unsigned *)0, cfile);
- + if (token != LPAREN) {
- + parse_warn (cfile, "left parenthesis expected.");
- + skip_to_semi (cfile);
- + *lose = 1;
- + return 0;
- + }
- + token = next_token (&val, (unsigned *)0, cfile);
- + (*expr) -> data.funcall.name =
- + dmalloc (strlen (val) + 1, MDL);
- + if (!(*expr)->data.funcall.name)
- + log_fatal ("can't allocate command name");
- + strcpy ((*expr) -> data.funcall.name, val);
- + token = next_token (&val, (unsigned *)0, cfile);
- + ep = &((*expr) -> data.funcall.arglist);
- + while (token == COMMA) {
- + if (!expression_allocate (ep, MDL))
- + log_fatal ("can't allocate expression");
- + if (!parse_data_expression (&(*ep) -> data.arg.val,
- + cfile, lose)) {
- + skip_to_semi (cfile);
- + *lose = 1;
- + return 0;
- + }
- + ep = &((*ep) -> data.arg.next);
- + token = next_token (&val, (unsigned *)0, cfile);
- + }
- + (*expr) -> op = expr_execute;
- + if (token != RPAREN) {
- + parse_warn (cfile, "right parenthesis expected.");
- + skip_to_semi (cfile);
- + *lose = 1;
- + return 0;
- + }
- + break;
- + #else
- + case EXECUTE:
- + parse_warn (cfile, "define ENABLE_EXECUTE in site.h to enable execute expressions.");
- + skip_to_semi (cfile);
- + *lose = 1;
- + return 0;
- + break;
- + #endif
- case ENCODE_INT:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- diff -urN dhcp-3.0.2.orig/common/print.c dhcp-3.0.2/common/print.c
- --- dhcp-3.0.2.orig/common/print.c 2004-06-17 14:54:39.000000000 -0600
- +++ dhcp-3.0.2/common/print.c 2005-02-24 12:32:12.000000000 -0700
- @@ -459,6 +459,7 @@
- {
- unsigned rv, left;
- const char *s;
- + struct expression* next_arg;
-
- switch (expr -> op) {
- case expr_none:
- @@ -483,7 +484,8 @@
- return rv;
- }
- break;
- -
- +
- +
- case expr_equal:
- if (len > 6) {
- rv = 4;
- @@ -1024,6 +1026,29 @@
- buf [rv++] = 0;
- return rv;
- }
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + rv = 11 + strlen (expr -> data.funcall.name);
- + if (len > rv + 2) {
- + sprintf (buf,
- + "(execute \"%s\"",
- + expr -> data.funcall.name);
- + for(next_arg = expr -> data.funcall.arglist;
- + next_arg;
- + next_arg = next_arg -> data.arg.next) {
- + if (len > rv + 3)
- + buf [rv++] = ' ';
- + rv += print_subexpression (next_arg ->
- + data.arg.val,
- + buf + rv,
- + len - rv - 2);
- + }
- + buf [rv++] = ')';
- + buf [rv] = 0;
- + return rv;
- + }
- + break;
- + #endif
- }
- return 0;
- }
- diff -urN dhcp-3.0.2.orig/common/tree.c dhcp-3.0.2/common/tree.c
- --- dhcp-3.0.2.orig/common/tree.c 2004-11-24 10:39:16.000000000 -0700
- +++ dhcp-3.0.2/common/tree.c 2005-02-24 12:32:12.000000000 -0700
- @@ -50,6 +50,113 @@
- int resolver_inited = 0;
- #endif
-
- +#ifdef ENABLE_EXECUTE
- +static unsigned long execute (char** args)
- +{
- +pid_t p = fork();
- +if (p > 0) {
- +int status;
- +waitpid (p, &status, 0);
- +return WEXITSTATUS(status);
- +}
- +else if(p == 0) {
- +execvp (args[0], args);
- +log_error ("Unable to execute %s: %s", args[0],
- +strerror(errno));
- +_exit(127);
- +} else {
- +log_fatal ("unable to fork");
- +}
- +return 1; /* never reached */
- +}
- +
- +#define CAPACITY_INCREMENT 8
- +static void append_to_ary (char*** ary_ptr, int* ary_size, int* ary_capacity,
- +char* new_element)
- +{
- +(*ary_size)++;
- +if (*ary_size > *ary_capacity) {
- +char** new_ary;
- +int new_ary_capacity = *ary_capacity + CAPACITY_INCREMENT;
- +new_ary = dmalloc(new_ary_capacity*sizeof(char *), MDL);
- +if (!new_ary)
- +log_fatal ("no memory for array.");
- +if (*ary_ptr != NULL) {
- +memcpy (new_ary, *ary_ptr,
- +(*ary_capacity)*sizeof(char *));
- +dfree (*ary_ptr, MDL);
- +}
- +*ary_ptr = new_ary;
- +*ary_capacity = new_ary_capacity;
- +}
- +(*ary_ptr)[*ary_size-1] = new_element;
- +}
- +
- +static char* data_string_to_char_string (struct data_string* d)
- +{
- +char* str = dmalloc (d->len+1, MDL);
- +if (!str)
- +log_fatal ("no memory for string.");
- +/* FIXME: should one use d -> buffer -> data or d -> data? are
- +they equivalent? */
- +strncpy (str, d -> data, d -> len);
- +str[d->len] = '\0';
- +return str;
- +}
- +
- +static int evaluate_execute (unsigned long* result, struct packet *packet,
- +struct lease *lease,
- +struct client_state *client_state,
- +struct option_state *in_options,
- +struct option_state *cfg_options,
- +struct binding_scope **scope,
- +struct expression* expr)
- +{
- +int status;
- +int cmd_status;
- +int i;
- +struct data_string ds;
- +struct expression* next_arg;
- +char** arg_ary = NULL;
- +int arg_ary_size = 0;
- +int arg_ary_capacity = 0;
- +append_to_ary (&arg_ary, &arg_ary_size, &arg_ary_capacity,
- + expr -> data.funcall.name);
- +for(next_arg = expr -> data.funcall.arglist;
- +next_arg;
- +next_arg = next_arg -> data.arg.next) {
- +memset (&ds, 0, sizeof ds);
- +status = (evaluate_data_expression
- +(&ds, packet,
- +lease, client_state, in_options,
- +cfg_options, scope,
- +next_arg -> data.arg.val,
- +MDL));
- +if (!status) {
- +if (arg_ary) {
- +for (i=1; i<arg_ary_size; i++)
- +dfree (arg_ary[i], MDL);
- +dfree(arg_ary, MDL);
- +}
- +return 0;
- +}
- +append_to_ary (&arg_ary, &arg_ary_size, &arg_ary_capacity,
- + data_string_to_char_string(&ds));
- +data_string_forget (&ds, MDL);
- +}
- +#if defined (DEBUG_EXPRESSIONS)
- +log_debug ("exec: execute");
- +#endif
- +append_to_ary (&arg_ary, &arg_ary_size, &arg_ary_capacity, NULL);
- +*result = execute (arg_ary);
- +for (i=1; i<arg_ary_size-1; i++)
- +dfree (arg_ary[i], MDL);
- +dfree(arg_ary, MDL);
- +return 1;
- +}
- +#endif
- +
- +
- pair cons (car, cdr)
- caddr_t car;
- pair cdr;
- @@ -861,6 +968,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- @@ -1224,6 +1334,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- @@ -2087,6 +2200,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- @@ -2595,7 +2711,12 @@
- #endif
- return 0;
- }
- -
- +#ifdef ENABLE_EXECUTE
- + case expr_execute:
- + return evaluate_execute (result, packet, lease,
- + client_state, in_options,
- + cfg_options, scope, expr);
- +#endif
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- @@ -3008,6 +3129,9 @@
- return (expr -> op == expr_extract_int8 ||
- expr -> op == expr_extract_int16 ||
- expr -> op == expr_extract_int32 ||
- + #ifdef ENABLE_EXECUTE
- + expr -> op == expr_execute ||
- + #endif
- expr -> op == expr_const_int ||
- expr -> op == expr_lease_time ||
- expr -> op == expr_dns_transaction ||
- @@ -3043,6 +3167,9 @@
- expr -> op == expr_extract_int8 ||
- expr -> op == expr_extract_int16 ||
- expr -> op == expr_extract_int32 ||
- + #ifdef ENABLE_EXECUTE
- + expr -> op == expr_execute ||
- + #endif
- expr -> op == expr_dns_transaction);
- }
-
- @@ -3069,6 +3196,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- @@ -3165,6 +3295,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- @@ -3225,6 +3358,8 @@
- int firstp;
- {
- struct expression *e;
- + struct expression* next_arg;
- +
- const char *s;
- char obuf [65];
- int scol;
- @@ -3696,7 +3831,27 @@
- expr -> data.variable);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
- -
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + col = token_print_indent (file, col, indent, "", "","execute");
- + col = token_print_indent (file, col, indent, " ", "","(");
- + scol = col;
- + /* FIXME: use token_print_indent_concat() here? */
- + col = token_print_indent (file, col, scol, "", "","\"");
- + col = token_print_indent (file, col, scol, "", "",expr -> data.funcall.name);
- + col = token_print_indent (file, col, scol, "", "","\"");
- + for(next_arg = expr -> data.funcall.arglist;
- + next_arg;
- + next_arg = next_arg -> data.arg.next) {
- + col = token_print_indent (file, col, scol, "", " ",",");
- + col = write_expression (file,
- + next_arg -> data.arg.val,
- + col, scol, 0);
- + }
- + col = token_print_indent (file, col, indent, "", "",")");
- +
- + break;
- +#endif
- default:
- log_fatal ("invalid expression type in print_expression: %d",
- expr -> op);
- @@ -3915,6 +4070,9 @@
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- + #ifdef ENABLE_EXECUTE
- + case expr_execute:
- + #endif
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- diff -urN dhcp-3.0.2.orig/includes/dhctoken.h dhcp-3.0.2/includes/dhctoken.h
- --- dhcp-3.0.2.orig/includes/dhctoken.h 2004-09-21 13:25:38.000000000 -0600
- +++ dhcp-3.0.2/includes/dhctoken.h 2005-02-24 12:33:21.000000000 -0700
- @@ -308,7 +308,8 @@
- DOMAIN_NAME = 613,
- DO_FORWARD_UPDATE = 614,
- KNOWN_CLIENTS = 615,
- - ATSFP = 616
- + ATSFP = 616,
- + EXECUTE = 616
- };
-
- #define is_identifier(x) ((x) >= FIRST_TOKEN && \
- diff -urN dhcp-3.0.2.orig/includes/site.h dhcp-3.0.2/includes/site.h
- --- dhcp-3.0.2.orig/includes/site.h 2002-03-12 11:33:39.000000000 -0700
- +++ dhcp-3.0.2/includes/site.h 2005-02-24 12:32:12.000000000 -0700
- @@ -167,6 +167,12 @@
-
- /* #define DHCPD_LOG_FACILITY LOG_DAEMON */
-
- +/* Define this if you want to be able to execute external commands
- + during conditional evaluation. */
- +
- +/* #define ENABLE_EXECUTE */
- +
- +
- /* Define this if you aren't debugging and you want to save memory
- (potentially a _lot_ of memory) by allocating leases in chunks rather
- than one at a time. */
- diff -urN dhcp-3.0.2.orig/includes/tree.h dhcp-3.0.2/includes/tree.h
- --- dhcp-3.0.2.orig/includes/tree.h 2004-06-10 11:59:31.000000000 -0600
- +++ dhcp-3.0.2/includes/tree.h 2005-02-24 12:32:12.000000000 -0700
- @@ -150,6 +150,9 @@
- expr_hardware,
- expr_packet,
- expr_const_data,
- + #ifdef ENABLE_EXECUTE
- + expr_execute,
- + #endif
- expr_extract_int8,
- expr_extract_int16,
- expr_extract_int32,
|