1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *   bpipe.c bi-directional pipe
21  *
22  *    Kern Sibbald, November MMII
23  *
24  */
25 
26 
27 #include "bacula.h"
28 #include "jcr.h"
29 
30 #ifdef HAVE_GETRLIMIT
31 #include <sys/resource.h>
32 #else
33 /* If not available, use a wrapper that will not use it */
34 #define getrlimit(a,b) -1
35 #endif
36 
37 int execvp_errors[] = {
38         EACCES,
39         ENOEXEC,
40         EFAULT,
41         EINTR,
42         E2BIG,
43         ENAMETOOLONG,
44         ENOMEM,
45 #ifndef HAVE_WIN32
46         ETXTBSY,
47 #endif
48         ENOENT
49 };
50 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
51 
52 
53 #define MAX_ARGV 100
54 
55 #define MODE_READ 1
56 #define MODE_WRITE 2
57 #define MODE_SHELL 4
58 #define MODE_STDERR 8
59 
60 #if !defined(HAVE_WIN32)
61 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
62 static void set_keepalive(int sockfd);
63 
build_sh_argc_argv(char * cmd,int * bargc,char * bargv[],int max_arg)64 void build_sh_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg)
65 {
66    bargv[0] = (char *)"/bin/sh";
67    bargv[1] = (char *)"-c";
68    bargv[2] = cmd;
69    bargv[3] = NULL;
70    *bargc = 3;
71 }
72 
73 /*
74  * Run an external program. Optionally wait a specified number
75  *   of seconds. Program killed if wait exceeded. We open
76  *   a bi-directional pipe so that the user can read from and
77  *   write to the program.
78  */
open_bpipe(char * prog,int wait,const char * mode,char * envp[])79 BPIPE *open_bpipe(char *prog, int wait, const char *mode, char *envp[])
80 {
81    char *bargv[MAX_ARGV];
82    int bargc, i;
83    int readp[2], writep[2], errp[2];
84    POOLMEM *tprog;
85    int mode_map = 0;
86    BPIPE *bpipe;
87    int save_errno;
88    struct rlimit rl;
89    int64_t rlimitResult=0;
90 
91    if (!prog || !*prog) {
92       /* execve(3) A component of the file does not name an existing file or file is an empty string. */
93       errno = ENOENT;
94       return NULL;
95    }
96 
97    bpipe = (BPIPE *)malloc(sizeof(BPIPE));
98    memset(bpipe, 0, sizeof(BPIPE));
99    if (strchr(mode,'r')) mode_map|=MODE_READ;
100    if (strchr(mode,'w')) mode_map|=MODE_WRITE;
101    if (strchr(mode,'s')) mode_map|=MODE_SHELL;
102    if (strchr(mode,'e')) mode_map|=MODE_STDERR;
103 
104    /* Build arguments for running program. */
105    tprog = get_pool_memory(PM_FNAME);
106    pm_strcpy(tprog, prog);
107    if (mode_map & MODE_SHELL) {
108       build_sh_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
109    } else {
110       build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
111    }
112 
113    /* Unable to parse the command, avoid segfault after the fork() */
114    if (bargc == 0 || bargv[0] == NULL) {
115       free_pool_memory(tprog);
116       free(bpipe);
117       /* execve(3) A component of the file does not name an existing file or file is an empty string. */
118       errno = ENOENT;
119       return NULL;
120    }
121 
122 #ifdef  xxxxxx
123    printf("argc=%d\n", bargc);
124    for (i=0; i<bargc; i++) {
125       printf("argc=%d argv=%s:\n", i, bargv[i]);
126    }
127 #endif
128 
129    /* Each pipe is one way, write one end, read the other, so we need two */
130    if ((mode_map & MODE_WRITE) && pipe(writep) == -1) {
131       save_errno = errno;
132       free(bpipe);
133       free_pool_memory(tprog);
134       errno = save_errno;
135       return NULL;
136    }
137    if ((mode_map & MODE_READ) && pipe(readp) == -1) {
138       save_errno = errno;
139       if (mode_map & MODE_WRITE) {
140          close(writep[0]);
141          close(writep[1]);
142       }
143       free(bpipe);
144       free_pool_memory(tprog);
145       errno = save_errno;
146       return NULL;
147    }
148    if ((mode_map & MODE_STDERR) && pipe(errp) == -1) {
149       save_errno = errno;
150       if (mode_map & MODE_WRITE) {
151          close(writep[0]);
152          close(writep[1]);
153       }
154       if (mode_map & MODE_READ) {
155          close(readp[0]);
156          close(readp[1]);
157       }
158       free(bpipe);
159       free_pool_memory(tprog);
160       errno = save_errno;
161       return NULL;
162    }
163 
164    /* Many systems doesn't have the correct system call
165     * to determine the FD list to close.
166     */
167 #if !defined(HAVE_FCNTL_F_CLOSEM) && !defined(HAVE_CLOSEFROM)
168    if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
169       rlimitResult = sysconf(_SC_OPEN_MAX);
170    } else {
171       rlimitResult = rl.rlim_max;
172    }
173 #endif
174 
175    /* Start worker process */
176    switch (bpipe->worker_pid = fork()) {
177    case -1:                           /* error */
178       save_errno = errno;
179       if (mode_map & MODE_WRITE) {
180          close(writep[0]);
181          close(writep[1]);
182       }
183       if (mode_map & MODE_READ) {
184          close(readp[0]);
185          close(readp[1]);
186       }
187       if (mode_map & MODE_STDERR) {
188          close(errp[0]);
189          close(errp[1]);
190       }
191       free(bpipe);
192       free_pool_memory(tprog);
193       errno = save_errno;
194       return NULL;
195 
196    case 0:                            /* child */
197       if (mode_map & MODE_WRITE) {
198          close(writep[1]);
199          dup2(writep[0], 0);          /* Dup our write to his stdin */
200       }
201       if (mode_map & MODE_READ) {
202          close(readp[0]);             /* Close unused child fds */
203          dup2(readp[1], 1);           /* dup our read to his stdout */
204          if (mode_map & MODE_STDERR) {  /*   and handle stderr */
205             close(errp[0]);
206             dup2(errp[1], 2);
207          } else {
208             dup2(readp[1], 2);
209          }
210       }
211 
212 #if HAVE_FCNTL_F_CLOSEM
213       fcntl(3, F_CLOSEM);
214 #elif HAVE_CLOSEFROM
215       closefrom(3);
216 #else
217       for (i=rlimitResult; i >= 3; i--) {
218          close(i);
219       }
220 #endif
221 
222       /* Setup the environment if requested, we do not use execvpe()
223        * because it's not wildly available
224        * TODO: Implement envp to windows version of bpipe
225        */
226       setup_env(envp);
227 
228       execvp(bargv[0], bargv);        /* call the program */
229       /* Convert errno into an exit code for later analysis */
230       for (i=0; i< num_execvp_errors; i++) {
231          if (execvp_errors[i] == errno) {
232             _exit(200 + i);            /* exit code => errno */
233          }
234       }
235       /* Do not flush stdio */
236       _exit(255);                      /* unknown errno */
237 
238    default:                           /* parent */
239       break;
240    }
241    free_pool_memory(tprog);
242    if (mode_map & MODE_READ) {
243       close(readp[1]);                /* close unused parent fds */
244       set_keepalive(readp[0]);
245       bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
246    }
247    if (mode_map & MODE_STDERR) {
248       close(errp[1]);                /* close unused parent fds */
249       set_keepalive(errp[0]);
250       bpipe->efd = fdopen(errp[0], "r"); /* open file descriptor */
251    }
252    if (mode_map & MODE_WRITE) {
253       close(writep[0]);
254       set_keepalive(writep[1]);
255       bpipe->wfd = fdopen(writep[1], "w");
256    }
257    bpipe->worker_stime = time(NULL);
258    bpipe->wait = wait;
259    if (wait > 0) {
260       bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
261    }
262    return bpipe;
263 }
264 
265 /* Close the write pipe only
266  * BE careful ! return 1 if ok */
close_wpipe(BPIPE * bpipe)267 int close_wpipe(BPIPE *bpipe)
268 {
269    int stat = 1;
270 
271    if (bpipe->wfd) {
272       fflush(bpipe->wfd);
273       if (fclose(bpipe->wfd) != 0) {
274          stat = 0;
275       }
276       bpipe->wfd = NULL;
277    }
278    return stat;
279 }
280 
281 /* Close the stderror pipe only */
close_epipe(BPIPE * bpipe)282 int close_epipe(BPIPE *bpipe)
283 {
284    int stat = 1;
285 
286    if (bpipe->efd) {
287       if (fclose(bpipe->efd) != 0) {
288          stat = 0;
289       }
290       bpipe->efd = NULL;
291    }
292    return stat;
293 }
294 
295 /*
296  * Close both pipes and free resources
297  *
298  *  Returns: 0 on success
299  *           berrno on failure
300  */
close_bpipe(BPIPE * bpipe)301 int close_bpipe(BPIPE *bpipe)
302 {
303    int chldstatus = 0;
304    int stat = 0;
305    int wait_option;
306    int remaining_wait;
307    pid_t wpid = 0;
308 
309 
310    /* Close pipes */
311    if (bpipe->rfd) {
312       fclose(bpipe->rfd);
313       bpipe->rfd = NULL;
314    }
315    if (bpipe->wfd) {
316       fclose(bpipe->wfd);
317       bpipe->wfd = NULL;
318    }
319    if (bpipe->efd) {
320       fclose(bpipe->efd);
321       bpipe->efd = NULL;
322    }
323 
324    if (bpipe->wait == 0) {
325       wait_option = 0;                /* wait indefinitely */
326    } else {
327       wait_option = WNOHANG;          /* don't hang */
328    }
329    remaining_wait = bpipe->wait;
330 
331    /* wait for worker child to exit */
332    for ( ;; ) {
333       Dmsg2(100, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
334       do {
335          wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
336       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
337       if (wpid == bpipe->worker_pid || wpid == -1) {
338          berrno be;
339          stat = errno;
340          Dmsg3(100, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
341             wpid==-1?be.bstrerror():"none");
342          break;
343       }
344       Dmsg3(100, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
345             wpid==-1?strerror(errno):"none");
346       if (remaining_wait > 0) {
347          bmicrosleep(1, 0);           /* wait one second */
348          remaining_wait--;
349       } else {
350          stat = ETIME;                /* set error status */
351          wpid = -1;
352          break;                       /* don't wait any longer */
353       }
354    }
355    if (wpid > 0) {
356       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
357          stat = WEXITSTATUS(chldstatus);
358          if (stat != 0) {
359             Dmsg1(100, "Non-zero status %d returned from child.\n", stat);
360             stat |= b_errno_exit;        /* exit status returned */
361          }
362          Dmsg1(100, "child status=%d\n", stat & ~b_errno_exit);
363       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
364 #ifndef HAVE_WIN32
365          stat = WTERMSIG(chldstatus);
366 #else
367          stat = 1;                    /* fake child status */
368 #endif
369          Dmsg1(100, "Child died from signal %d\n", stat);
370          stat |= b_errno_signal;      /* exit signal returned */
371       }
372    }
373    if (bpipe->timer_id) {
374       stop_child_timer(bpipe->timer_id);
375    }
376    free(bpipe);
377    Dmsg2(100, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
378    return stat;
379 }
380 
381 /*
382  * Build argc and argv from a string
383  */
build_argc_argv(char * cmd,int * bargc,char * bargv[],int max_argv)384 static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
385 {
386    int i;
387    char *p, *q, quote;
388    int argc = 0;
389 
390    argc = 0;
391    for (i=0; i<max_argv; i++)
392       bargv[i] = NULL;
393 
394    p = cmd;
395    quote = 0;
396    while  (*p && (*p == ' ' || *p == '\t'))
397       p++;
398    if (*p == '\"' || *p == '\'') {
399       quote = *p;
400       p++;
401    }
402    if (*p) {
403       while (*p && argc < MAX_ARGV) {
404          q = p;
405          if (quote) {
406             while (*q && *q != quote)
407             q++;
408             quote = 0;
409          } else {
410             while (*q && *q != ' ')
411             q++;
412          }
413          if (*q)
414             *(q++) = '\0';
415          bargv[argc++] = p;
416          p = q;
417          while (*p && (*p == ' ' || *p == '\t'))
418             p++;
419          if (*p == '\"' || *p == '\'') {
420             quote = *p;
421             p++;
422          }
423       }
424    }
425    *bargc = argc;
426 }
427 
428 #
set_keepalive(int sockfd)429 static void set_keepalive(int sockfd)
430 {
431    /*
432     * Keep socket from timing out from inactivity
433     *  Ignore all errors
434     */
435    int turnon = 1;
436    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon));
437 #if defined(TCP_KEEPIDLE)
438    int opt = 240 /* 2 minuites in half-second intervals recommended by IBM */
439    setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt));
440 #endif
441 }
442 
443 #endif /* HAVE_WIN32 */
444 
445 /*
446  * Run an external program. Optionally wait a specified number
447  *   of seconds. Program killed if wait exceeded. Optionally
448  *   return the output from the program (normally a single line).
449  *
450  *   If the watchdog kills the program, fgets returns, and ferror is set
451  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
452  *
453  * Contrary to my normal calling conventions, this program
454  *
455  *  Returns: 0 on success
456  *           non-zero on error == berrno status
457  */
run_program(char * prog,int wait,POOLMEM * & results)458 int run_program(char *prog, int wait, POOLMEM *&results)
459 {
460    BPIPE *bpipe;
461    int stat1, stat2;
462    char *mode;
463 
464    mode = (char *)"r";
465    bpipe = open_bpipe(prog, wait, mode);
466    if (!bpipe) {
467       return ENOENT;
468    }
469    results[0] = 0;
470    int len = sizeof_pool_memory(results) - 1;
471    fgets(results, len, bpipe->rfd);
472    results[len] = 0;
473    if (feof(bpipe->rfd)) {
474       stat1 = 0;
475    } else {
476       stat1 = ferror(bpipe->rfd);
477    }
478    if (stat1 < 0) {
479       berrno be;
480       Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno));
481    } else if (stat1 != 0) {
482       Dmsg1(100, "Run program fgets stat=%d\n", stat1);
483       if (bpipe->timer_id) {
484          Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
485          /* NB: I'm not sure it is really useful for run_program. Without the
486           * following lines run_program would not detect if the program was killed
487           * by the watchdog. */
488          if (bpipe->timer_id->killed) {
489             stat1 = ETIME;
490             pm_strcpy(results, _("Program killed by Bacula (timeout)\n"));
491          }
492       }
493    }
494    stat2 = close_bpipe(bpipe);
495    stat1 = stat2 != 0 ? stat2 : stat1;
496    Dmsg1(100, "Run program returning %d\n", stat1);
497    return stat1;
498 }
499 
500 /*
501  * Run an external program. Optionally wait a specified number
502  *   of seconds. Program killed if wait exceeded (it is done by the
503  *   watchdog, as fgets is a blocking function).
504  *
505  *   If the watchdog kills the program, fgets returns, and ferror is set
506  *   to 1 (=>SUCCESS), so we check if the watchdog killed the program.
507  *
508  *   Return the full output from the program (not only the first line).
509  *
510  * Contrary to my normal calling conventions, this program
511  *
512  *  Returns: 0 on success
513  *           non-zero on error == berrno status
514  *
515  */
run_program_full_output(char * prog,int wait,POOLMEM * & results,char * env[])516 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
517 {
518    BPIPE *bpipe;
519    int stat1, stat2;
520    char *mode;
521    POOLMEM* tmp;
522    char *buf;
523    const int bufsize = 32000;
524 
525 
526    Dsm_check(200);
527 
528    tmp = get_pool_memory(PM_MESSAGE);
529    buf = (char *)malloc(bufsize+1);
530 
531    results[0] = 0;
532    mode = (char *)"r";
533    bpipe = open_bpipe(prog, wait, mode, env);
534    if (!bpipe) {
535       stat1 = ENOENT;
536       goto bail_out;
537    }
538 
539    Dsm_check(200);
540    tmp[0] = 0;
541    while (1) {
542       buf[0] = 0;
543       fgets(buf, bufsize, bpipe->rfd);
544       buf[bufsize] = 0;
545       pm_strcat(tmp, buf);
546       if (feof(bpipe->rfd)) {
547          stat1 = 0;
548          Dmsg1(100, "Run program fgets stat=%d\n", stat1);
549          break;
550       } else {
551          stat1 = ferror(bpipe->rfd);
552       }
553       if (stat1 < 0) {
554          berrno be;
555          Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror());
556          break;
557       } else if (stat1 != 0) {
558          Dmsg1(200, "Run program fgets stat=%d\n", stat1);
559          if (bpipe->timer_id && bpipe->timer_id->killed) {
560             Dmsg1(100, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed);
561             break;
562          }
563       }
564    }
565    /*
566     * We always check whether the timer killed the program. We would see
567     * an eof even when it does so we just have to trust the killed flag
568     * and set the timer values to avoid edge cases where the program ends
569     * just as the timer kills it.
570     */
571    if (bpipe->timer_id && bpipe->timer_id->killed) {
572       Dmsg1(100, "Run program fgets killed=%d\n", bpipe->timer_id->killed);
573       pm_strcpy(tmp, _("Program killed by Bacula (timeout)\n"));
574       stat1 = ETIME;
575    }
576    pm_strcpy(results, tmp);
577    Dmsg3(200, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results);
578    stat2 = close_bpipe(bpipe);
579    stat1 = stat2 != 0 ? stat2 : stat1;
580 
581    Dmsg1(100, "Run program returning %d\n", stat1);
582 bail_out:
583    free_pool_memory(tmp);
584    free(buf);
585    return stat1;
586 }
587