All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exec.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /*
18  * $Id: fd495658da941b48252a0f9604904d782b2ca309 $
19  *
20  * @file exec.c
21  * @brief Execute external programs.
22  *
23  * @copyright 2000-2004,2006 The FreeRADIUS server project
24  */
25 
26 RCSID("$Id: fd495658da941b48252a0f9604904d782b2ca309 $")
27 
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/rad_assert.h>
30 
31 #include <sys/file.h>
32 
33 #include <fcntl.h>
34 #include <ctype.h>
35 
36 #ifdef HAVE_SYS_WAIT_H
37 # include <sys/wait.h>
38 #endif
39 #ifndef WEXITSTATUS
40 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
41 #endif
42 #ifndef WIFEXITED
43 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
44 #endif
45 
46 #define MAX_ARGV (256)
47 
49 
50 #define USEC 1000000
51 static void tv_sub(struct timeval *end, struct timeval *start,
52  struct timeval *elapsed)
53 {
54  elapsed->tv_sec = end->tv_sec - start->tv_sec;
55  if (elapsed->tv_sec > 0) {
56  elapsed->tv_sec--;
57  elapsed->tv_usec = USEC;
58  } else {
59  elapsed->tv_usec = 0;
60  }
61  elapsed->tv_usec += end->tv_usec;
62  elapsed->tv_usec -= start->tv_usec;
63 
64  if (elapsed->tv_usec >= USEC) {
65  elapsed->tv_usec -= USEC;
66  elapsed->tv_sec++;
67  }
68 }
69 
70 /** Start a process
71  *
72  * @param cmd Command to execute. This is parsed into argv[] parts, then each individual argv
73  * part is xlat'ed.
74  * @param request Current reuqest
75  * @param exec_wait set to true to read from or write to child.
76  * @param[in,out] input_fd pointer to int, receives the stdin file descriptor. Set to NULL
77  * and the child will have /dev/null on stdin.
78  * @param[in,out] output_fd pinter to int, receives the stdout file descriptor. Set to NULL
79  * and child will have /dev/null on stdout.
80  * @param input_pairs list of value pairs - these will be put into the environment variables
81  * of the child.
82  * @param shell_escape values before passing them as arguments.
83  * @return
84  * - PID of the child process.
85  * - -1 on failure.
86  */
87 pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
88  int *input_fd, int *output_fd,
89  VALUE_PAIR *input_pairs, bool shell_escape)
90 {
91 #ifndef __MINGW32__
92  char *p;
93  VALUE_PAIR *vp;
94  int n;
95  int to_child[2] = {-1, -1};
96  int from_child[2] = {-1, -1};
97  pid_t pid;
98 #endif
99  int argc;
100  int i;
101  char const **argv_p;
102  char *argv[MAX_ARGV], **argv_start = argv;
103  char argv_buf[4096];
104 #define MAX_ENVP 1024
105  char *envp[MAX_ENVP];
106  size_t envlen = 0;
107  TALLOC_CTX *input_ctx = NULL;
108 
109  /*
110  * Stupid array decomposition...
111  *
112  * If we do memcpy(&argv_p, &argv, sizeof(argv_p)) src ends up being a char **
113  * pointing to the value of the first element.
114  */
115  memcpy(&argv_p, &argv_start, sizeof(argv_p));
116  argc = rad_expand_xlat(request, cmd, MAX_ARGV, argv_p, true, sizeof(argv_buf), argv_buf);
117  if (argc <= 0) {
118  ERROR("Invalid command '%s'", cmd);
119  return -1;
120  }
121 
122  if (DEBUG_ENABLED3) {
123  for (i = 0; i < argc; i++) DEBUG3("arg[%d] %s", i, argv[i]);
124  }
125 
126 #ifndef __MINGW32__
127  /*
128  * Open a pipe for child/parent communication, if necessary.
129  */
130  if (exec_wait) {
131  if (input_fd) {
132  if (pipe(to_child) != 0) {
133  ERROR("Couldn't open pipe to child: %s", fr_syserror(errno));
134  return -1;
135  }
136  }
137  if (output_fd) {
138  if (pipe(from_child) != 0) {
139  ERROR("Couldn't open pipe from child: %s", fr_syserror(errno));
140  /* safe because these either need closing or are == -1 */
141  close(to_child[0]);
142  close(to_child[1]);
143  return -1;
144  }
145  }
146  }
147 
148  envp[0] = NULL;
149 
150  if (input_pairs) {
151  vp_cursor_t cursor;
152  char buffer[1024];
153 
154  input_ctx = talloc_new(request);
155 
156  /*
157  * Set up the environment variables in the
158  * parent, so we don't call libc functions that
159  * hold mutexes. They might be locked when we fork,
160  * and will remain locked in the child.
161  */
162  for (vp = fr_cursor_init(&cursor, &input_pairs);
163  vp && (envlen < ((sizeof(envp) / sizeof(*envp)) - 1));
164  vp = fr_cursor_next(&cursor)) {
165  /*
166  * Hmm... maybe we shouldn't pass the
167  * user's password in an environment
168  * variable...
169  */
170  snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
171  if (shell_escape) {
172  for (p = buffer; *p != '='; p++) {
173  if (*p == '-') {
174  *p = '_';
175  } else if (isalpha((int) *p)) {
176  *p = toupper(*p);
177  }
178  }
179  }
180 
181  n = strlen(buffer);
182  fr_pair_value_snprint(buffer + n, sizeof(buffer) - n, vp, shell_escape ? '"' : 0);
183 
184  DEBUG3("export %s", buffer);
185  envp[envlen++] = talloc_strdup(input_ctx, buffer);
186  }
187 
188  fr_cursor_init(&cursor, radius_list(request, PAIR_LIST_CONTROL));
189  while ((envlen < ((sizeof(envp) / sizeof(*envp)) - 1)) &&
190  (vp = fr_cursor_next_by_num(&cursor, 0, PW_EXEC_EXPORT, TAG_ANY))) {
191  DEBUG3("export %s", vp->vp_strvalue);
192  memcpy(&envp[envlen++], &vp->vp_strvalue, sizeof(*envp));
193  }
194 
195  /*
196  * NULL terminate for execve
197  */
198  envp[envlen] = NULL;
199  }
200 
201  if (exec_wait) {
202  pid = rad_fork(); /* remember PID */
203  } else {
204  pid = fork(); /* don't wait */
205  }
206 
207  if (pid == 0) {
208  int devnull;
209 
210  /*
211  * Child process.
212  *
213  * We try to be fail-safe here. So if ANYTHING
214  * goes wrong, we exit with status 1.
215  */
216 
217  /*
218  * Open STDIN to /dev/null
219  */
220  devnull = open("/dev/null", O_RDWR);
221  if (devnull < 0) {
222  ERROR("Failed opening /dev/null: %s\n", fr_syserror(errno));
223 
224  /*
225  * Where the status code is interpreted as a module rcode
226  * one is subtracted from it, to allow 0 to equal success
227  *
228  * 2 is RLM_MODULE_FAIL + 1
229  */
230  exit(2);
231  }
232 
233  /*
234  * Only massage the pipe handles if the parent
235  * has created them.
236  */
237  if (exec_wait) {
238  if (input_fd) {
239  close(to_child[1]);
240  dup2(to_child[0], STDIN_FILENO);
241  } else {
242  dup2(devnull, STDIN_FILENO);
243  }
244 
245  if (output_fd) {
246  close(from_child[0]);
247  dup2(from_child[1], STDOUT_FILENO);
248  } else {
249  dup2(devnull, STDOUT_FILENO);
250  }
251 
252  } else { /* no pipe, STDOUT should be /dev/null */
253  dup2(devnull, STDIN_FILENO);
254  dup2(devnull, STDOUT_FILENO);
255  }
256 
257  /*
258  * If we're not debugging, then we can't do
259  * anything with the error messages, so we throw
260  * them away.
261  *
262  * If we are debugging, then we want the error
263  * messages to go to the STDERR of the server.
264  */
265  if (rad_debug_lvl == 0) {
266  dup2(devnull, STDERR_FILENO);
267  }
268  close(devnull);
269 
270  /*
271  * The server may have MANY FD's open. We don't
272  * want to leave dangling FD's for the child process
273  * to play funky games with, so we close them.
274  */
275  closefrom(3);
276 
277  /*
278  * I swear the signature for execve is wrong and should
279  * take 'char const * const argv[]'.
280  *
281  * Note: execve(), unlike system(), treats all the space
282  * delimited arguments as literals, so there's no need
283  * to perform additional escaping.
284  */
285  execve(argv[0], argv, envp);
286  printf("Failed to execute \"%s\": %s", argv[0], fr_syserror(errno)); /* fork output will be captured */
287 
288  /*
289  * Where the status code is interpreted as a module rcode
290  * one is subtracted from it, to allow 0 to equal success
291  *
292  * 2 is RLM_MODULE_FAIL + 1
293  */
294  exit(2);
295  }
296 
297  /*
298  * Free child environment variables
299  */
300  talloc_free(input_ctx);
301 
302  /*
303  * Parent process.
304  */
305  if (pid < 0) {
306  ERROR("Couldn't fork %s: %s", argv[0], fr_syserror(errno));
307  if (exec_wait) {
308  /* safe because these either need closing or are == -1 */
309  close(to_child[0]);
310  close(to_child[1]);
311  close(from_child[0]);
312  close(from_child[1]);
313  }
314  return -1;
315  }
316 
317  /*
318  * We're not waiting, exit, and ignore any child's status.
319  */
320  if (exec_wait) {
321  /*
322  * Close the ends of the pipe(s) the child is using
323  * return the ends of the pipe(s) our caller wants
324  *
325  */
326  if (input_fd) {
327  *input_fd = to_child[1];
328  close(to_child[0]);
329  }
330  if (output_fd) {
331  *output_fd = from_child[0];
332  close(from_child[1]);
333  }
334  }
335 
336  return pid;
337 #else
338  if (exec_wait) {
339  ERROR("Wait is not supported");
340  return -1;
341  }
342 
343  {
344  /*
345  * The _spawn and _exec families of functions are
346  * found in Windows compiler libraries for
347  * portability from UNIX. There is a variety of
348  * functions, including the ability to pass
349  * either a list or array of parameters, to
350  * search in the PATH or otherwise, and whether
351  * or not to pass an environment (a set of
352  * environment variables). Using _spawn, you can
353  * also specify whether you want the new process
354  * to close your program (_P_OVERLAY), to wait
355  * until the new process is finished (_P_WAIT) or
356  * for the two to run concurrently (_P_NOWAIT).
357 
358  * _spawn and _exec are useful for instances in
359  * which you have simple requirements for running
360  * the program, don't want the overhead of the
361  * Windows header file, or are interested
362  * primarily in portability.
363  */
364 
365  /*
366  * FIXME: check return code... what is it?
367  */
368  _spawnve(_P_NOWAIT, argv[0], argv, envp);
369  }
370 
371  return 0;
372 #endif
373 }
374 
375 /** Read from the child process.
376  *
377  * @param fd file descriptor to read from.
378  * @param pid pid of child, will be reaped if it dies.
379  * @param timeout amount of time to wait, in seconds.
380  * @param answer buffer to write into.
381  * @param left length of buffer.
382  * @return
383  * - -1 on failure.
384  * - Length of output.
385  */
386 int radius_readfrom_program(int fd, pid_t pid, int timeout,
387  char *answer, int left)
388 {
389  int done = 0;
390 #ifndef __MINGW32__
391  int status;
392  struct timeval start;
393 #ifdef O_NONBLOCK
394  bool nonblock = true;
395 #endif
396 
397 #ifdef O_NONBLOCK
398  /*
399  * Try to set it non-blocking.
400  */
401  do {
402  int flags;
403 
404  if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
405  nonblock = false;
406  break;
407  }
408 
409  flags |= O_NONBLOCK;
410  if( fcntl(fd, F_SETFL, flags) < 0) {
411  nonblock = false;
412  break;
413  }
414  } while (0);
415 #endif
416 
417 
418  /*
419  * Read from the pipe until we doesn't get any more or
420  * until the message is full.
421  */
422  gettimeofday(&start, NULL);
423  while (1) {
424  int rcode;
425  fd_set fds;
426  struct timeval when, elapsed, wake;
427 
428  FD_ZERO(&fds);
429  FD_SET(fd, &fds);
430 
431  gettimeofday(&when, NULL);
432  tv_sub(&when, &start, &elapsed);
433  if (elapsed.tv_sec >= timeout) goto too_long;
434 
435  when.tv_sec = timeout;
436  when.tv_usec = 0;
437  tv_sub(&when, &elapsed, &wake);
438 
439  rcode = select(fd + 1, &fds, NULL, NULL, &wake);
440  if (rcode == 0) {
441  too_long:
442  DEBUG("Child PID %u is taking too much time: forcing failure and killing child.", pid);
443  kill(pid, SIGTERM);
444  close(fd); /* should give SIGPIPE to child, too */
445 
446  /*
447  * Clean up the child entry.
448  */
449  rad_waitpid(pid, &status);
450  return -1;
451  }
452  if (rcode < 0) {
453  if (errno == EINTR) continue;
454  break;
455  }
456 
457 #ifdef O_NONBLOCK
458  /*
459  * Read as many bytes as possible. The kernel
460  * will return the number of bytes available.
461  */
462  if (nonblock) {
463  status = read(fd, answer + done, left);
464  } else
465 #endif
466  /*
467  * There's at least 1 byte ready: read it.
468  */
469  status = read(fd, answer + done, 1);
470 
471  /*
472  * Nothing more to read: stop.
473  */
474  if (status == 0) {
475  break;
476  }
477 
478  /*
479  * Error: See if we have to continue.
480  */
481  if (status < 0) {
482  /*
483  * We were interrupted: continue reading.
484  */
485  if (errno == EINTR) {
486  continue;
487  }
488 
489  /*
490  * There was another error. Most likely
491  * The child process has finished, and
492  * exited.
493  */
494  break;
495  }
496 
497  done += status;
498  left -= status;
499  if (left <= 0) break;
500  }
501 #endif /* __MINGW32__ */
502 
503  /* Strip trailing new lines */
504  while ((done > 0) && (answer[done - 1] == '\n')) {
505  answer[--done] = '\0';
506  }
507 
508  return done;
509 }
510 
511 /** Execute a program.
512  *
513  * @param[in,out] ctx to allocate new VALUE_PAIR (s) in.
514  * @param[out] out buffer to append plaintext (non valuepair) output.
515  * @param[in] outlen length of out buffer.
516  * @param[out] output_pairs list of value pairs - Data on child's stdout will be parsed and
517  * added into this list of value pairs.
518  * @param[in] request Current request (may be NULL).
519  * @param[in] cmd Command to execute. This is parsed into argv[] parts, then each individual argv
520  * part is xlat'ed.
521  * @param[in] input_pairs list of value pairs - these will be available in the environment of the
522  * child.
523  * @param[in] exec_wait set to 1 if you want to read from or write to child.
524  * @param[in] shell_escape values before passing them as arguments.
525  * @param[in] timeout amount of time to wait, in seconds.
526  * @return
527  * - 0 if exec_wait==0.
528  * - exit code if exec_wait!=0.
529  * - -1 on failure.
530  */
531 int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, VALUE_PAIR **output_pairs,
532  REQUEST *request, char const *cmd, VALUE_PAIR *input_pairs,
533  bool exec_wait, bool shell_escape, int timeout)
534 
535 {
536  pid_t pid;
537  int from_child;
538 #ifndef __MINGW32__
539  char *p;
540  pid_t child_pid;
541  int comma = 0;
542  int status, ret = 0;
543  ssize_t len;
544  char answer[4096];
545 #endif
546 
547  RDEBUG2("Executing: %s:", cmd);
548 
549  if (out) *out = '\0';
550 
551  pid = radius_start_program(cmd, request, exec_wait, NULL, &from_child, input_pairs, shell_escape);
552  if (pid < 0) {
553  return -1;
554  }
555 
556  if (!exec_wait) {
557  return 0;
558  }
559 
560 #ifndef __MINGW32__
561  len = radius_readfrom_program(from_child, pid, timeout, answer, sizeof(answer));
562  if (len < 0) {
563  /*
564  * Failure - radius_readfrom_program will
565  * have called close(from_child) for us
566  */
567  RERROR("Failed to read from child output");
568  return -1;
569 
570  }
571  answer[len] = '\0';
572 
573  /*
574  * Make sure that the writer can't block while writing to
575  * a pipe that no one is reading from anymore.
576  */
577  close(from_child);
578 
579  if (len == 0) {
580  goto wait;
581  }
582 
583  /*
584  * Parse the output, if any.
585  */
586  if (output_pairs) {
587  /*
588  * HACK: Replace '\n' with ',' so that
589  * fr_pair_list_afrom_str() can parse the buffer in
590  * one go (the proper way would be to
591  * fix fr_pair_list_afrom_str(), but oh well).
592  */
593  for (p = answer; *p; p++) {
594  if (*p == '\n') {
595  *p = comma ? ' ' : ',';
596  p++;
597  comma = 0;
598  }
599  if (*p == ',') {
600  comma++;
601  }
602  }
603 
604  /*
605  * Replace any trailing comma by a NUL.
606  */
607  if (answer[len - 1] == ',') {
608  answer[--len] = '\0';
609  }
610 
611  if (fr_pair_list_afrom_str(ctx, answer, output_pairs) == T_INVALID) {
612  RERROR("Failed parsing output from: %s: %s", cmd, fr_strerror());
613  strlcpy(out, answer, len);
614  ret = -1;
615  }
616  /*
617  * We've not been told to extract output pairs,
618  * just copy the programs output to the out
619  * buffer.
620  */
621 
622  } else if (out) {
623  strlcpy(out, answer, outlen);
624  }
625 
626  /*
627  * Call rad_waitpid (should map to waitpid on non-threaded
628  * or single-server systems).
629  */
630 wait:
631  child_pid = rad_waitpid(pid, &status);
632  if (child_pid == 0) {
633  RERROR("Timeout waiting for child");
634 
635  return -2;
636  }
637 
638  if (child_pid == pid) {
639  if (WIFEXITED(status)) {
640  status = WEXITSTATUS(status);
641  if ((status != 0) || (ret < 0)) {
642  RERROR("Program returned code (%d) and output '%s'", status, answer);
643  } else {
644  RDEBUG2("Program returned code (%d) and output '%s'", status, answer);
645  }
646 
647  return ret < 0 ? ret : status;
648  }
649  }
650 
651  RERROR("Abnormal child exit: %s", fr_syserror(errno));
652 #endif /* __MINGW32__ */
653 
654  return -1;
655 }
656 
657 static void time_free(void *data)
658 {
659  free(data);
660 }
661 
662 /** Set the global trigger section exec_trigger will search in
663  *
664  * @note Triggers are used by the connection pool, which is used in the server library
665  * which may not have the mainconfig available. Additionally, utilities may want
666  * to set their own root config sections.
667  *
668  * @param cs to use as global trigger section
669  */
671 {
672  exec_trigger_main = cs;
673  exec_trigger_subcs = cf_section_sub_find(cs, "trigger");
674 }
675 
676 /** Execute a trigger - call an executable to process an event
677  *
678  * @param request The current request.
679  * @param cs to search for triggers in. If not NULL, only the portion after the last '.'
680  * in name is used for the trigger. If cs is NULL, the entire name is used to find
681  * the trigger in the global trigger section.
682  * @param name the path relative to the global trigger section ending in the trigger name
683  * e.g. module.ldap.pool.start.
684  * @param quench whether to rate limit triggers.
685  */
686 void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench)
687 {
688  CONF_SECTION *subcs;
689  CONF_ITEM *ci;
690  CONF_PAIR *cp;
691  char const *attr;
692  char const *value;
693  VALUE_PAIR *vp;
694  bool alloc = false;
695 
696  /*
697  * Use global "trigger" section if no local config is given.
698  */
699  if (!cs) {
700  cs = exec_trigger_main;
701  attr = name;
702  } else {
703  /*
704  * Try to use pair name, rather than reference.
705  */
706  attr = strrchr(name, '.');
707  if (attr) {
708  attr++;
709  } else {
710  attr = name;
711  }
712  }
713 
714  /*
715  * Find local "trigger" subsection. If it isn't found,
716  * try using the global "trigger" section, and reset the
717  * reference to the full path, rather than the sub-path.
718  */
719  subcs = cf_section_sub_find(cs, "trigger");
720  if (!subcs && exec_trigger_main && (cs != exec_trigger_main)) {
721  subcs = exec_trigger_subcs;
722  attr = name;
723  }
724  if (!subcs) return;
725 
726  ci = cf_reference_item(subcs, exec_trigger_main, attr);
727  if (!ci) {
728  ERROR("No such item in trigger section: %s", attr);
729  return;
730  }
731 
732  if (!cf_item_is_pair(ci)) {
733  ERROR("Trigger is not a configuration variable: %s", attr);
734  return;
735  }
736 
737  cp = cf_item_to_pair(ci);
738  if (!cp) return;
739 
740  value = cf_pair_value(cp);
741  if (!value) {
742  ERROR("Trigger has no value: %s", name);
743  return;
744  }
745 
746  /*
747  * May be called for Status-Server packets.
748  */
749  vp = NULL;
750  if (request && request->packet) vp = request->packet->vps;
751 
752  /*
753  * Perform periodic quenching.
754  */
755  if (quench) {
756  time_t *last_time;
757 
758  last_time = cf_data_find(cs, value);
759  if (!last_time) {
760  last_time = rad_malloc(sizeof(*last_time));
761  *last_time = 0;
762 
763  if (cf_data_add(cs, value, last_time, time_free) < 0) {
764  free(last_time);
765  last_time = NULL;
766  }
767  }
768 
769  /*
770  * Send the quenched traps at most once per second.
771  */
772  if (last_time) {
773  time_t now = time(NULL);
774  if (*last_time == now) return;
775 
776  *last_time = now;
777  }
778  }
779 
780  /*
781  * radius_exec_program always needs a request.
782  */
783  if (!request) {
784  request = request_alloc(NULL);
785  alloc = true;
786  }
787 
788  DEBUG("Trigger %s -> %s", name, value);
789 
790  radius_exec_program(request, NULL, 0, NULL, request, value, vp, false, true, EXEC_TIMEOUT);
791 
792  if (alloc) talloc_free(request);
793 }
void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench)
Execute a trigger - call an executable to process an event.
Definition: exec.c:686
#define DEBUG3(fmt,...)
Definition: log.h:177
#define RERROR(fmt,...)
Definition: log.h:207
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
Definition: log.h:171
VALUE_PAIR * fr_cursor_next_by_num(vp_cursor_t *cursor, unsigned int vendor, unsigned int attr, int8_t tag)
Iterate over a collection of VALUE_PAIRs of a given type in the pairlist.
Definition: cursor.c:200
void * rad_malloc(size_t size)
Definition: util.c:411
int closefrom(int fd)
Definition: misc.c:378
VALUE_PAIR ** radius_list(REQUEST *request, pair_lists_t list)
Resolve attribute pair_lists_t value to an attribute list.
Definition: tmpl.c:195
static char const * name
#define WEXITSTATUS(stat_val)
Definition: exec.c:40
#define MAX_ARGV
Definition: exec.c:46
void size_t fr_pair_value_snprint(char *out, size_t outlen, VALUE_PAIR const *vp, char quote)
Print the value of an attribute to a string.
Definition: pair.c:2107
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
Definition: libradius.h:162
VALUE_PAIR * fr_cursor_init(vp_cursor_t *cursor, VALUE_PAIR *const *node)
Setup a cursor to iterate over attribute pairs.
Definition: cursor.c:60
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:686
#define rad_waitpid(a, b)
Definition: radiusd.h:564
static float timeout
Definition: radclient.c:43
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
Definition: pair.h:144
char const * cf_pair_value(CONF_PAIR const *pair)
Definition: conffile.c:3506
#define rad_fork(n)
Definition: radiusd.h:563
void exec_trigger_set_conf(CONF_SECTION *cs)
Set the global trigger section exec_trigger will search in.
Definition: exec.c:670
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
#define DEBUG(fmt,...)
Definition: log.h:175
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: conffile.c:181
static bool done
Definition: radclient.c:53
static CONF_SECTION * exec_trigger_subcs
Definition: exec.c:48
#define USEC
Definition: exec.c:50
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, VALUE_PAIR **output_pairs, REQUEST *request, char const *cmd, VALUE_PAIR *input_pairs, bool exec_wait, bool shell_escape, int timeout)
Execute a program.
Definition: exec.c:531
bool cf_item_is_pair(CONF_ITEM const *item)
Definition: conffile.c:3928
int cf_data_add(CONF_SECTION *, char const *, void *, void(*)(void *))
Definition: conffile.c:4018
Configuration AVP similar to a VALUE_PAIR.
Definition: conffile.c:82
#define WIFEXITED(stat_val)
Definition: exec.c:43
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
Definition: conffile.c:3708
#define RDEBUG2(fmt,...)
Definition: log.h:244
uint8_t data[]
Definition: eap_pwd.h:625
#define TAG_ANY
Definition: pair.h:191
log_lvl_t rad_debug_lvl
Global debugging level.
Definition: log.c:49
VALUE_PAIR * fr_cursor_next(vp_cursor_t *cursor)
Advanced the cursor to the next VALUE_PAIR.
Definition: cursor.c:263
RADIUS_PACKET * packet
Incoming request.
Definition: radiusd.h:221
static void time_free(void *data)
Definition: exec.c:657
static CONF_SECTION * exec_trigger_main
Definition: exec.c:48
pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait, int *input_fd, int *output_fd, VALUE_PAIR *input_pairs, bool shell_escape)
Start a process.
Definition: exec.c:87
static void tv_sub(struct timeval *end, struct timeval *start, struct timeval *elapsed)
Definition: exec.c:51
int radius_readfrom_program(int fd, pid_t pid, int timeout, char *answer, int left)
Read from the child process.
Definition: exec.c:386
#define EXEC_TIMEOUT
Definition: radiusd.h:329
int rad_expand_xlat(REQUEST *request, char const *cmd, int max_argc, char const *argv[], bool can_fail, size_t argv_buflen, char *argv_buf)
Split string into words and expand each one.
Definition: util.c:658
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:38
Attributes that change the behaviour of modules.
Definition: tmpl.h:85
void * cf_data_find(CONF_SECTION const *, char const *)
Definition: conffile.c:3981
FR_TOKEN fr_pair_list_afrom_str(TALLOC_CTX *ctx, char const *buffer, VALUE_PAIR **head)
Read one line of attribute/value pairs into a list.
Definition: pair.c:1261
#define RCSID(id)
Definition: build.h:135
#define ERROR(fmt,...)
Definition: log.h:145
REQUEST * request_alloc(TALLOC_CTX *ctx)
Create a new REQUEST data structure.
Definition: request.c:85
#define MAX_ENVP
CONF_ITEM * cf_reference_item(CONF_SECTION const *parentcs, CONF_SECTION *outercs, char const *ptr)
Definition: conffile.c:906