LCOV - code coverage report
Current view: top level - src/server - child.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 4 85 4.7 %
Date: 2017-08-09 Functions: 1 3 33.3 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../cmd.h"
       6             : #include "../cntr.h"
       7             : #include "../conf.h"
       8             : #include "../cstat.h"
       9             : #include "../handy.h"
      10             : #include "../iobuf.h"
      11             : #include "../log.h"
      12             : #include "../prepend.h"
      13             : #include "../run_script.h"
      14             : #include "extra_comms.h"
      15             : #include "monitor/status_server.h"
      16             : #include "run_action.h"
      17             : #include "child.h"
      18             : 
      19             : static struct asfd *wasfd=NULL;
      20             : 
      21      218120 : int write_status(enum cntr_status cntr_status,
      22             :         const char *path, struct cntr *cntr)
      23             : {
      24      218120 :         time_t now=0;
      25      218120 :         time_t diff=0;
      26             :         static time_t lasttime=0;
      27             :         static size_t l=0;
      28             :         static struct iobuf *wbuf=NULL;
      29             : 
      30      218120 :         if(!wasfd) return 0;
      31           0 :         if(!cntr || !cntr->bno)
      32             :                 return 0;
      33             : 
      34             :         // Only update every 2 seconds.
      35           0 :         now=time(NULL);
      36           0 :         diff=now-lasttime;
      37           0 :         if(diff<2)
      38             :         {
      39             :                 // Might as well do this in case they fiddled their
      40             :                 // clock back in time.
      41           0 :                 if(diff<0) lasttime=now;
      42             :                 return 0;
      43             :         }
      44           0 :         lasttime=now;
      45             : 
      46             :         // Only get a new string if we did not manage to write the previous
      47             :         // one.
      48           0 :         if(!l)
      49             :         {
      50           0 :                 cntr->cntr_status=cntr_status;
      51           0 :                 if(!(l=cntr_to_str(cntr, path))) goto error;
      52           0 :                 if(!wbuf && !(wbuf=iobuf_alloc())) goto error;
      53           0 :                 iobuf_set(wbuf, CMD_APPEND, cntr->str, l);
      54             :         }
      55             : 
      56           0 :         switch(wasfd->append_all_to_write_buffer(wasfd, wbuf))
      57             :         {
      58             :                 case APPEND_OK:
      59           0 :                         l=0; // Fall through.
      60             :                 case APPEND_BLOCKED:
      61             :                         return 0;
      62             :                 default:
      63             :                         break;
      64             :         }
      65             : error:
      66           0 :         iobuf_free(&wbuf);
      67           0 :         return -1;
      68             : }
      69             : 
      70           0 : static int run_server_script(struct asfd *asfd,
      71             :         const char *pre_or_post,
      72             :         const char *script, struct strlist *script_arg,
      73             :         uint8_t notify, struct conf **cconfs, int backup_ret, int timer_ret)
      74             : {
      75           0 :         int a=0;
      76           0 :         int ret=0;
      77           0 :         char *logbuf=NULL;
      78             :         const char *args[12];
      79           0 :         struct iobuf *rbuf=asfd->rbuf;
      80           0 :         const char *cname=get_string(cconfs[OPT_CNAME]);
      81             : 
      82           0 :         args[a++]=script;
      83           0 :         args[a++]=pre_or_post;
      84           0 :         args[a++]=rbuf->buf?rbuf->buf:"", // Action requested by client.
      85           0 :         args[a++]=cname;
      86           0 :         args[a++]=backup_ret?"1":"0", // Indicate success or failure.
      87             :         // Indicate whether the timer script said OK or not.
      88           0 :         args[a++]=timer_ret?"1":"0",
      89           0 :         args[a++]=NULL;
      90             : 
      91             :         // Do not have a client storage directory, so capture the
      92             :         // output in a buffer to pass to the notification script.
      93           0 :         if(run_script_to_buf(asfd, args, script_arg, cconfs, 1, 1, 0, &logbuf))
      94             :         {
      95             :                 char msg[256];
      96             :                 snprintf(msg, sizeof(msg),
      97             :                         "server %s script %s returned an error",
      98             :                         pre_or_post, script);
      99           0 :                 log_and_send(asfd, msg);
     100           0 :                 ret=-1;
     101           0 :                 if(!notify) goto end;
     102             : 
     103           0 :                 a=0;
     104           0 :                 args[a++]=get_string(cconfs[OPT_N_FAILURE_SCRIPT]);
     105           0 :                 args[a++]=cname;
     106             :                 // magic - set basedir blank and the
     107             :                 // notify script will know to get the content
     108             :                 // from the next argument (usually storagedir)
     109           0 :                 args[a++]=""; // usually basedir
     110           0 :                 args[a++]=logbuf?logbuf:""; //usually storagedir
     111           0 :                 args[a++]=""; // usually file
     112           0 :                 args[a++]=""; // usually brv
     113           0 :                 args[a++]=""; // usually warnings
     114           0 :                 args[a++]=NULL;
     115           0 :                 run_script(asfd, args, get_strlist(cconfs[OPT_N_FAILURE_ARG]),
     116             :                         cconfs, 1, 1, 0);
     117             :         }
     118             : end:
     119           0 :         free_w(&logbuf);
     120           0 :         return ret;
     121             : }
     122             : 
     123           0 : int child(struct async *as, int is_status_server,
     124             :         int status_wfd, struct conf **confs, struct conf **cconfs)
     125             : {
     126           0 :         int ret=-1;
     127           0 :         int srestore=0;
     128           0 :         int timer_ret=0;
     129           0 :         char *incexc=NULL;
     130             :         const char *confs_user;
     131             :         const char *cconfs_user;
     132             :         const char *confs_group;
     133             :         const char *cconfs_group;
     134             :         const char *s_script_pre;
     135             :         const char *s_script_post;
     136             : 
     137             :         // If we are not a status server, we are a normal child - set up the
     138             :         // parent socket to write status to.
     139           0 :         if(status_wfd>0)
     140             :         {
     141           0 :                 if(!(wasfd=setup_asfd(as, "child status pipe", &status_wfd,
     142             :                         /*port*/-1)))
     143             :                                 goto end;
     144           0 :                 wasfd->attempt_reads=0;
     145             :         }
     146             : 
     147             :         /* Has to be before the chuser/chgrp stuff to allow clients to switch
     148             :            to different clients when both clients have different user/group
     149             :            settings. */
     150           0 :         if(extra_comms(as, &incexc, &srestore, confs, cconfs))
     151             :         {
     152           0 :                 log_and_send(as->asfd, "running extra comms failed on server");
     153           0 :                 goto end;
     154             :         }
     155             : 
     156             :         // Needs to happen after extra_comms, in case extra_comms resets them.
     157           0 :         confs_user=get_string(confs[OPT_USER]);
     158           0 :         cconfs_user=get_string(cconfs[OPT_USER]);
     159           0 :         confs_group=get_string(confs[OPT_GROUP]);
     160           0 :         cconfs_group=get_string(cconfs[OPT_GROUP]);
     161             : 
     162             :         /* Now that the client conf is loaded, we might want to chuser or
     163             :            chgrp.
     164             :            The main process could have already done this, so we don't want
     165             :            to try doing it again if cconfs has the same values, because it
     166             :            will fail. */
     167           0 :         if( (!confs_user  || (cconfs_user && strcmp(confs_user, cconfs_user)))
     168           0 :           ||(!confs_group ||(cconfs_group && strcmp(confs_group,cconfs_group))))
     169             :         {
     170           0 :                 if(chuser_and_or_chgrp(cconfs_user, cconfs_group))
     171             :                 {
     172           0 :                         log_and_send(as->asfd,
     173             :                                 "chuser_and_or_chgrp failed on server");
     174           0 :                         goto end;
     175             :                 }
     176             :         }
     177             : 
     178           0 :         if(as->asfd->read(as->asfd)) goto end;
     179             : 
     180             :         // If this is a status server, run the status server.
     181           0 :         if(is_status_server)
     182             :         {
     183           0 :                 ret=status_server(as, cconfs);
     184           0 :                 goto end;
     185             :         }
     186             : 
     187           0 :         ret=0;
     188             : 
     189           0 :         s_script_pre=get_string(cconfs[OPT_S_SCRIPT_PRE]);
     190           0 :         s_script_post=get_string(cconfs[OPT_S_SCRIPT_POST]);
     191             : 
     192             :         // FIX THIS: Make the script components part of a struct, and just
     193             :         // pass in the correct struct. Same below.
     194           0 :         if(s_script_pre)
     195           0 :                 ret=run_server_script(as->asfd, "pre",
     196             :                         s_script_pre,
     197             :                         get_strlist(cconfs[OPT_S_SCRIPT_PRE_ARG]),
     198           0 :                         get_int(cconfs[OPT_S_SCRIPT_PRE_NOTIFY]),
     199             :                         cconfs, ret, timer_ret);
     200             : 
     201           0 :         if(!ret)
     202           0 :                 ret=run_action_server(as, incexc, srestore, &timer_ret, cconfs);
     203             : 
     204           0 :         if((!ret || get_int(cconfs[OPT_S_SCRIPT_POST_RUN_ON_FAIL]))
     205           0 :           && s_script_post)
     206           0 :                 ret=run_server_script(as->asfd, "post",
     207             :                         s_script_post,
     208             :                         get_strlist(cconfs[OPT_S_SCRIPT_POST_ARG]),
     209           0 :                         get_int(cconfs[OPT_S_SCRIPT_POST_NOTIFY]),
     210             :                         cconfs, ret, timer_ret);
     211             : 
     212             : end:
     213           0 :         return ret;
     214             : }

Generated by: LCOV version 1.10