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