nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

qmail-start.c (3221B)


      1 #include <sys/stat.h>
      2 #include "fd.h"
      3 #include "prot.h"
      4 #include "exit.h"
      5 #include "fork.h"
      6 #include "noreturn.h"
      7 #include "uidgid.h"
      8 #include "auto_uids.h"
      9 #include "auto_users.h"
     10 
     11 char *(qsargs[]) = { "qmail-send", 0 };
     12 char *(qcargs[]) = { "qmail-clean", 0 };
     13 char *(qlargs[]) = { "qmail-lspawn", "./Mailbox", 0 };
     14 char *(qrargs[]) = { "qmail-rspawn", 0 };
     15 
     16 void _noreturn_ die() { _exit(111); }
     17 
     18 int pi0[2];
     19 int pi1[2];
     20 int pi2[2];
     21 int pi3[2];
     22 int pi4[2];
     23 int pi5[2];
     24 int pi6[2];
     25 
     26 uid_t auto_uidl;
     27 uid_t auto_uidq;
     28 uid_t auto_uidr;
     29 uid_t auto_uids;
     30 
     31 gid_t auto_gidn;
     32 gid_t auto_gidq;
     33 
     34 void close23456() { close(2); close(3); close(4); close(5); close(6); }
     35 
     36 void closepipes() {
     37   close(pi1[0]); close(pi1[1]); close(pi2[0]); close(pi2[1]);
     38   close(pi3[0]); close(pi3[1]); close(pi4[0]); close(pi4[1]);
     39   close(pi5[0]); close(pi5[1]); close(pi6[0]); close(pi6[1]);
     40 }
     41 
     42 int main(int argc, char **argv)
     43 {
     44   if (chdir("/") == -1) die();
     45   umask(077);
     46 
     47   auto_uidl = inituid(auto_userl);
     48   auto_uidq = inituid(auto_userq);
     49   auto_uidr = inituid(auto_userr);
     50   auto_uids = inituid(auto_users);
     51 
     52   auto_gidn = initgid(auto_groupn);
     53   auto_gidq = initgid(auto_groupq);
     54 
     55   if (prot_gid(auto_gidq) == -1) die();
     56 
     57   if (fd_copy(2,0) == -1) die();
     58   if (fd_copy(3,0) == -1) die();
     59   if (fd_copy(4,0) == -1) die();
     60   if (fd_copy(5,0) == -1) die();
     61   if (fd_copy(6,0) == -1) die();
     62 
     63   if (argv[1]) {
     64     qlargs[1] = argv[1];
     65     ++argv;
     66   }
     67 
     68   // logger
     69   if (argv[1]) {
     70     if (pipe(pi0) == -1) die();
     71     switch(fork()) {
     72       case -1:
     73 	die();
     74       case 0:
     75         if (prot_gid(auto_gidn) == -1) die();
     76         if (prot_uid(auto_uidl) == -1) die();
     77         close(pi0[1]);
     78         if (fd_move(0,pi0[0]) == -1) die();
     79         close23456();
     80         execvp(argv[1],argv + 1);
     81 	die();
     82     }
     83     close(pi0[0]);
     84     if (fd_move(1,pi0[1]) == -1) die();
     85   }
     86 
     87   if (pipe(pi1) == -1) die();
     88   if (pipe(pi2) == -1) die();
     89   if (pipe(pi3) == -1) die();
     90   if (pipe(pi4) == -1) die();
     91   if (pipe(pi5) == -1) die();
     92   if (pipe(pi6) == -1) die();
     93 
     94   // channelspawn: local
     95   switch(fork()) {
     96     case -1: die();
     97     case 0:
     98       if (fd_copy(0,pi1[0]) == -1) die();
     99       if (fd_copy(1,pi2[1]) == -1) die();
    100       close23456();
    101       closepipes();
    102       execvp(*qlargs,qlargs);
    103       die();
    104   }
    105 
    106   // channelspawn: remote
    107   switch(fork()) {
    108     case -1: die();
    109     case 0:
    110       if (prot_uid(auto_uidr) == -1) die();
    111       if (fd_copy(0,pi3[0]) == -1) die();
    112       if (fd_copy(1,pi4[1]) == -1) die();
    113       close23456();
    114       closepipes();
    115       execvp(*qrargs,qrargs);
    116       die();
    117   }
    118 
    119   // cleanup
    120   switch(fork()) {
    121     case -1: die();
    122     case 0:
    123       if (prot_uid(auto_uidq) == -1) die();
    124       if (fd_copy(0,pi5[0]) == -1) die();
    125       if (fd_copy(1,pi6[1]) == -1) die();
    126       close23456();
    127       closepipes();
    128       execvp(*qcargs,qcargs);
    129       die();
    130   }
    131 
    132   // exec into qmsend
    133   if (prot_uid(auto_uids) == -1) die();
    134   if (fd_copy(0,1) == -1) die();
    135   if (fd_copy(1,pi1[1]) == -1) die();
    136   if (fd_copy(2,pi2[0]) == -1) die();
    137   if (fd_copy(3,pi3[1]) == -1) die();
    138   if (fd_copy(4,pi4[0]) == -1) die();
    139   if (fd_copy(5,pi5[1]) == -1) die();
    140   if (fd_copy(6,pi6[0]) == -1) die();
    141   closepipes();
    142   execvp(*qsargs,qsargs);
    143   die();
    144 }