Exemplo n.º 1
0
int main (int argc, const char * const *argv, const char * const *envp) {
  int opt;
  int wtmp =0;

  progname =*argv;

  while ((opt =getopt(argc, argv, "wV")) != opteof) {
    switch(opt) {
    case 'w':
      wtmp =1;
      break;
    case 'V':
      strerr_warn1("$Id: cb399098f794012a7f5e6a3a7090b2d53b86c08c $", 0);
    case '?':
      usage();
    }
  }
  argv +=optind;

  if (! argv || ! *argv) usage();
  if (utmp_logout(*argv) == -1)
    strerr_die4x(111, WARNING, "unable to logout line ", *argv,
                 " in utmp: no such entry");
  if (wtmp)
    if (wtmp_logout(*argv) == -1)
      strerr_die4sys(111, WARNING,
                     "unable to logout line ", *argv, " in wtmp: ");
  _exit(0);
}
Exemplo n.º 2
0
void snap_dump(char *filename, stralloc *sa)
{
  dAVLCursor c;
  dAVLNode *node;
  char strip[IP6_FMT];
  char strnum[FMT_ULONG];
  int fd;

  fd = open_trunc("filename");  
  if(fd == -1)
    strerr_warn1(ARGV0 "warning: unable to open for tcp.tmp for writing", &strerr_sys);
  
  buffer_init(&wb, write, fd, wbspace, sizeof wbspace);

  node = dAVLFirst(&c, t);
  while(node)
    {
      buffer_put(&wb, strnum, fmt_ulong(strnum, node->key));
      buffer_puts(&wb, ",");
      buffer_put(&wb, strip, ip4_fmt(strip, node->ip4));
      buffer_puts(&wb, ",");
      buffer_put(&wb, strip, ip6_fmt(strip, node->ip6));
      buffer_puts(&wb, ",LOC\n");
      
      node = dAVLNext(&c);
    }
 
  buffer_flush(&wb);
  close(fd);
}
Exemplo n.º 3
0
char *generate_answer(stralloc *answer, uint32 uid, 
		      char *lip, uint16 lport, char *rip, uint16 rport)
{
  char *problem = "ok";
  char *x;
  char buf[5];
  stralloc out = {0};
  stralloc tmp = {0};
  stralloc key = {0};

  /* get key from enviroment */
  x = env_get("KEY");
  if (!x)
    {
      problem = "$KEY not set";
      strerr_warn1("didentd warning: $KEY not set using 'snakeoilkey'", NULL);
      x = "snakeoilkey";
    }
  
  /* initialize rijndael with $KEY */
  stralloc_copys(&key, x);
  txtparse(&key);
  pad(&key, 32);
  rijndaelKeySched(6, 8, key.s);
    
  /* build answer */
  stralloc_cats(answer, " : USERID : OTHER : ");

  uint32_pack(buf, uid); stralloc_catb(&tmp, buf, 4);
  uint16_pack(buf, lport); stralloc_catb(&tmp, buf, 2);
  uint16_pack(buf, rport); stralloc_catb(&tmp, buf, 2);
  uint32_pack(buf, time(NULL)); stralloc_catb(&tmp, buf, 4);
  stralloc_catb(&tmp, lip, 4);
  stralloc_catb(&tmp, rip, 8);

  /* encrypt last part of answer with rijndael */
  rijndaelEncrypt(tmp.s);
  
  stralloc_readyplus(&out, 32);
  base64encode(out.s, tmp.s, 24);
  
  stralloc_catb(answer, out.s, 32); 
  stralloc_cats(answer, "\r\n");
  stralloc_0(answer);
  
  return problem;
}
Exemplo n.º 4
0
/* this is out work routine which is called by DJBs server code */
int respond(char *q, char qtype[2])
{
  int flaga;
  int flagaaaa;
  int flagloc;
  char ip[IP6_FMT];
  stralloc filename = { 0 };
  int fd;
  buffer b;
  char bspace[1024];
  static stralloc line;
  int match = 1;
  unsigned long linenum = 0;
  int data = 0;
  stralloc f[NUMFIELDS] = {{0}};

  /* check what the client is requesting */
  flaga = byte_equal(qtype,2,DNS_T_A);
  flagloc = byte_equal(qtype,2,DNS_T_LOC);
  flagaaaa = byte_equal(qtype,2,DNS_T_AAAA);
  if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagloc = flagaaaa = 1;
  
  /* find out in which file we should look */
  query2filename(q, &filename);

  buffer_put(buffer_2, filename.s, filename.len);
  buffer_puts(buffer_2, "\n");
  buffer_flush(buffer_2);

  fd = open_read(filename.s);
  if (fd == -1) 
    {
      strerr_warn3("unable to open file: ", filename.s, ": ", &strerr_sys);
      match = 0;
    }
  
  buffer_init(&b, read, fd, bspace, sizeof bspace);

  /* Work through the file and handout the data. */
   while(match) 
    {
      ++linenum;
      if(getln(&b, &line, &match, '\n') == -1)
	{
	  strerr_warn1("unable to read line: ", &strerr_sys);
	  break;
	}
  
      /* clean up line end */
      stralloc_cleanlineend(&line); 
      
      /* skip comments  & empty lines */
      if(line.s[0] == '#') continue;
      if(line.s[0] == 0) continue;
      
      /* seperate fields */
      fieldsep(f, NUMFIELDS, &line, ',');

      /* IPv4 */
      if(f[0].s[0] == '=')
	{
	  if (flaga) 
	    {
	      ip4_scan(f[2].s, ip);
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_A, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(ip, 4)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}

      /* IPv6 */
      if(f[0].s[0] == '6')
	{
	  if (flagaaaa) 
	    {
	      ip6_scan(f[0].s, ip);
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_AAAA, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(ip, 16)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}

      /* LOC */
      if(f[0].s[0] == 'L')
	{
	  if (flagloc) 
	    {
	      txtparse(&f[2]);
	      if(f[2].len <= 16)
		{		
		  buffer_puts(buffer_2, "filedns: warning: LOC record seems to short\n");
		  buffer_flush(buffer_2);
		}
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_LOC, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(f[2].s, 16)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}
    }
  
  /* Disclaimer ;-) */
  if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0;
  if (!response_addbytes("this is a response from an alpha quality dns-server", 51)) return 0;
  response_rfinish(RESPONSE_ADDITIONAL);
  if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0;
  if (!response_addbytes("filednes 0.00 - if problems arise contact [email protected]", 54)) return 0;
  response_rfinish(RESPONSE_ADDITIONAL);
  
  //  if (flaga || flagptr) 
  //    {
  //      if (dd(q,"",ip) == 4) 
  //	{
  //	  if (flaga) 
  //	    {
  //	      if (!response_rstart(q,DNS_T_A,"\0\12\0\0")) return 0;
  //	      if (!response_addbytes(ip,4)) return 0;
  //	      response_rfinish(RESPONSE_ANSWER);
  //	    }
  //	  return 1;
  //	}
  //      j = dd(q,"\7in-addr\4arpa",ip);
  //      if (j >= 0) 
  //	{
 
  if(data > 0) return 1;

  /* nothing found */
  buffer_puts(buffer_2, "notfound\n");
  buffer_flush(buffer_2);

  // XXX: this is somehow broken
  /* response 0-1 is transaction id */
  /* set response flags */
  /* clear authority bit */
  response[2] &= ~4;
  /* clear last 4 bits */
  response[3] &= ~15;
  /* flag not found */
  response[3] |= 3;
  
  /* response[4..5]:   nr of questions
   * response[6..7]:   nr of answers rr
   * response[8..9]:   nr of authority rr
   * response[10..11]: nr of additional rr
   */

  return 1;
}
Exemplo n.º 5
0
int main(int argc, char **argv) {
  unsigned int i, done;
  char *x;

  progname =*argv;
  for (i =str_len(*argv); i; --i) if ((*argv)[i -1] == '/') break;
  *argv +=i;
  optprogname =progname =*argv;
  service =argv;
  services =1;
  lsb =(str_diff(progname, "sv"));
  if ((x =env_get("SVDIR"))) varservice =x;
  if ((x =env_get("SVWAIT"))) scan_ulong(x, &wait);
  while ((i =getopt(argc, (const char* const*)argv, "w:vV")) != opteof) {
    switch(i) {
    case 'w': scan_ulong(optarg, &wait);
    case 'v': verbose =1; break;
    case 'V': strerr_warn1(VERSION, 0);
    case '?': usage();
    }
  }
  argv +=optind; argc -=optind;
  if (!(action =*argv++)) usage(); --argc;
  if (!lsb) { service =argv; services =argc; }
  if (!*service) usage();

  taia_now(&tnow); tstart =tnow;
  if ((curdir =open_read(".")) == -1)
    fatal("unable to open current directory");

  act =&control; acts ="s";
  if (verbose) cbk =&check;
  switch (*action) {
  case 'x': case 'e':
    acts ="x"; break;
  case 'X': case 'E':
    acts ="x"; kll =1; cbk =&check; break;
  case 'D':
    acts ="d"; kll =1; cbk =&check; break;
  case 'T':
    acts ="tc"; kll =1; cbk =&check; break;
  case 'c':
    if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =&check; break; }
  case 'u': case 'd': case 'o': case 't': case 'p': case 'h':
  case 'a': case 'i': case 'k': case 'q': case '1': case '2':
    action[1] =0; acts =action; break;
  case 's':
    if (!str_diff(action, "shutdown")) { acts ="x"; cbk =&check; break; }
    if (!str_diff(action, "start")) { acts ="u"; cbk =&check; break; }
    if (!str_diff(action, "stop")) { acts ="d"; cbk =&check; break; }
    if (lsb && str_diff(action, "status")) usage();
    act =&status; cbk =0; break;
  case 'r':
    if (!str_diff(action, "restart")) { acts ="tcu"; cbk =&check; break; }
    usage();
  case 'f':
    if (!str_diff(action, "force-reload"))
      { acts ="tc"; kll =1; cbk =&check; break; }
    if (!str_diff(action, "force-restart"))
      { acts ="tcu"; kll =1; cbk =&check; break; }
    if (!str_diff(action, "force-shutdown"))
      { acts ="x"; kll =1; cbk =&check; break; }
    if (!str_diff(action, "force-stop"))
      { acts ="d"; kll =1; cbk =&check; break; }
  default:
    usage();
  }

  servicex =service;
  for (i =0; i < services; ++i) {
    if ((**service != '/') && (**service != '.') && **service &&
        ((*service)[str_len(*service) -1] != '/')) {
      if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
        fail("unable to change to service directory");
        *service =0;
      }
    }
    else
      if (chdir(*service) == -1) {
        fail("unable to change to service directory");
        *service =0;
      }
    if (*service) if (act && (act(acts) == -1)) *service =0;
    if (fchdir(curdir) == -1) fatal("unable to change to original directory");
    service++;
  }

  if (*cbk)
    for (;;) {
      taia_sub(&tdiff, &tnow, &tstart);
      service =servicex; done =1;
      for (i =0; i < services; ++i, ++service) {
        if (!*service) continue;
        if ((**service != '/') && (**service != '.')) {
          if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
            fail("unable to change to service directory");
            *service =0;
          }
        }
        else
          if (chdir(*service) == -1) {
            fail("unable to change to service directory");
            *service =0;
          }
        if (*service) { if (cbk(acts) != 0) *service =0; else done =0; }
        if (*service && taia_approx(&tdiff) > wait) {
          kll ? outs(KILL) : outs(TIMEOUT);
          if (svstatus_get() > 0) { svstatus_print(*service); ++rc; }
          flush("\n");
          if (kll) control("k");
          *service =0;
        }
        if (fchdir(curdir) == -1)
          fatal("unable to change to original directory");
      }
      if (done) break;
      usleep(420000);
      taia_now(&tnow);
    }
  return(rc > 99 ? 99 : rc);
}
Exemplo n.º 6
0
int main(int argc, const char * const *argv) {
  int opt;
  unsigned long sec =600;
  int verbose =0;
  int doexit =0;
  int dokill =0;
  int wdir;
  int fd;
  char status[20];
  int r;
  unsigned long pid;
  struct tai start;
  struct tai now;
  
  progname =*argv;
  
  while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) {
    switch(opt) {
    case 't':
      scan_ulong(optarg, &sec);
      if ((sec < 1) || (sec > 6000)) usage();
      break;
    case 'x':
      doexit =1;
      break;
    case 'k':
      dokill =1;
      break;
    case 'v':
      verbose =1;
      break;
    case 'V':
      strerr_warn1(VERSION, 0);
    case '?':
      usage();
    }
  }
  argv +=optind;
  if (! argv || ! *argv) usage();

  if ((wdir =open_read(".")) == -1)
    fatal("unable to open current working directory");

  for (dir =argv; *dir; ++dir) {
    if (dir != argv)
      if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
    if (chdir(*dir) == -1) continue; /* bummer */
    if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */
    if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
      close(fd); continue; /* bummer */
    }
    close(fd);
  }
  dir =argv;

  tai_now(&start);
  while (*dir) {
    if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
    if (chdir(*dir) == -1) {
      warn(*dir, ": unable to change directory: ", &strerr_sys);
      continue;
    }
    if ((fd =open_write("supervise/ok")) == -1) {
      if (errno == error_nodevice) {
        if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0);
        dir++;
      }
      else
        warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
      continue;
    }
    close(fd);

    if ((fd =open_read("supervise/status")) == -1) {
      warn(*dir, "unable to open supervise/status: ", &strerr_sys);
      continue;
    }
    r =buffer_unixread(fd, status, 20);
    close(fd);
    if ((r < 18) || (r == 19)) { /* supervise compatibility */
      if (r == -1)
        warn(*dir, "unable to read supervise/status: ", &strerr_sys);
      else
        warn(*dir, ": unable to read supervise/status: bad format.", 0);
      continue;
    }
    pid =(unsigned char)status[15];
    pid <<=8; pid +=(unsigned char)status[14];
    pid <<=8; pid +=(unsigned char)status[13];
    pid <<=8; pid +=(unsigned char)status[12];

    if (! doexit && ! pid) {
      /* ok, service is down */
      if (verbose) strerr_warn3(INFO, *dir, ": down.", 0);
      dir++;
      continue;
    }

    if (status[17] != 'd') { /* catch previous failures */
      if ((fd =open_write("supervise/control")) == -1) {
        warn(*dir, ": unable to open supervise/control: ", &strerr_sys);
        continue;
      }
      if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
        warn(*dir, ": unable to write to supervise/control: ", &strerr_sys);
        close(fd);
        continue;
      }
      close(fd);
    }
  
    tai_now(&now);
    tai_sub(&now, &now, &start);
    if (tai_approx(&now) >= sec) {
      /* timeout */
      if (verbose) strerr_warn2(INFO, "timeout.", 0);
      if (dokill) {
        if (chdir(*dir) == -1) {
          warn(*dir, ": unable to change directory: ", &strerr_sys);
          continue;
        }
        if ((fd =open_write("supervise/control")) == -1) {
          if (errno == error_nodevice) {
            if (verbose)
              strerr_warn3(INFO, *dir, ": runsv not running.", 0);
            dir++;
          }
          else
            warn(*argv, ": unable to open supervise/control: ", &strerr_sys);
          continue;
        }
        if (write(fd, "k", 1) != 1)
          warn(*argv, ": unable to write to supervise/control: ", &strerr_sys);
        else
          strerr_warn3(INFO, *dir, ": killed.", 0);
        close(fd);
        dir++;
        if (! *dir) _exit(111);
        continue;
      }
      _exit(111);
    }
    sleep(1);
  }
  if (fchdir(wdir) == -1) 
    strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
  close(wdir);
  if (rc > 100) rc =100;
  _exit(rc);
}
Exemplo n.º 7
0
int main(int argc, const char * const *argv)
{
    int opt;
    int verbose =0;
    char status[18];
    int fd;
    int is;
    int r;
    int wdir;
    unsigned long pid;
    struct tai when;
    struct tai now;
    char sulong[FMT_ULONG];

    progname =*argv;

    while ((opt =getopt(argc, argv, "s:vV")) != opteof)
    {
        switch(opt)
        {
        case 's':
            scan_ulong(optarg, &sec);
            if ((sec < 1) || (sec > 600)) usage();
            break;
        case 'v':
            verbose =1;
            break;
        case 'V':
            strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0);
        case '?':
            usage();
        }
    }
    argv +=optind;
    if (! argv || ! *argv) usage();

    if ((wdir =open_read(".")) == -1)
        fatal("unable to open current working directory");

    dir =argv;
    while (*dir)
    {
        if (dir != argv)
            if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
        if (chdir(*dir) == -1)
        {
            warn(*dir, ": unable to change directory: ", &strerr_sys);
            continue;
        }
        if ((fd =open_write("supervise/ok")) == -1)
        {
            if (errno == error_nodevice)
                warn(*dir, ": runsv not running.", 0);
            else
                warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
            continue;
        }
        close(fd);

        if ((fd =open_read("supervise/status")) == -1)
        {
            warn(*dir, "unable to open supervise/status: ", &strerr_sys);
            continue;
        }
        r =buffer_unixread(fd, status, sizeof status);
        close(fd);
        if (r < sizeof status)
        {
            if (r == -1)
                warn(*dir, "unable to read supervise/status: ", &strerr_sys);
            else
                warn(*dir, ": unable to read supervise/status: bad format.", 0);
            continue;
        }

        pid =(unsigned char)status[15];
        pid <<=8;
        pid +=(unsigned char)status[14];
        pid <<=8;
        pid +=(unsigned char)status[13];
        pid <<=8;
        pid +=(unsigned char)status[12];
        if (! pid)
        {
            warn(*dir, ": is down.", 0);
            continue;
        }

        tai_unpack(status, &when);
        tai_now(&now);
        if (tai_less(&now, &when)) when =now;
        tai_sub(&when, &now, &when);
        is =tai_approx(&when);

        if (is >= sec)
        {
            /* ok */
            if (verbose)
            {
                sulong[fmt_ulong(sulong, is)] =0;
                strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0);
            }
            dir++;
            continue;
        }
        sleep(sec -is);
    }
    if (fchdir(wdir) == -1)
        strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
    close(wdir);
    if (rc > 100) rc =100;
    _exit(rc);
}
Exemplo n.º 8
0
int main(int argc, char **argv) {
  int opt;
  char *user =0;
  char *host;
  unsigned long port;
  int pid;
  int s;
  int conn;
  int delim;

  progname =*argv;
  phccmax =0;

#ifdef SSLSVD
  while ((opt =getopt(argc, (const char **)argv,
                      "c:C:i:x:u:l:Eb:hpt:vVU:/:Z:K:")) != opteof) {
#else
  while ((opt =getopt(argc, (const char **)argv,
                      "c:C:i:x:u:l:Eb:hpt:vV")) != opteof) {
#endif
    switch(opt) {
    case 'c': scan_ulong(optarg, &cmax); if (cmax < 1) usage(); break;
    case 'C':
      delim =scan_ulong(optarg, &phccmax);
      if (phccmax < 1) usage();
      if (optarg[delim] == ':') {
        if (ipsvd_fmt_msg(&msg, optarg +delim +1) == -1) die_nomem();
        if (! stralloc_0(&msg)) die_nomem();
        phccmsg =msg.s;
      }
      break;
    case 'i': if (instructs) usage(); instructs =optarg; break;
    case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break;
    case 'u': user =(char*)optarg; break;
    case 'l':
      if (! stralloc_copys(&local_hostname, optarg)) die_nomem();
      if (! stralloc_0(&local_hostname)) die_nomem();
      break;
    case 'E': ucspi =0; break;
    case 'b': scan_ulong(optarg, &backlog); break;
    case 'h': lookuphost =1; break;
    case 'p': lookuphost =1; paranoid =1; break;
    case 't': scan_ulong(optarg, &timeout); break;
    case 'v': ++verbose; break;
#ifdef SSLSVD
    case 'U': ssluser =(char*)optarg; break;
    case '/': root =(char*)optarg; break;
    case 'Z': cert =(char*)optarg; break;
    case 'K': key =(char*)optarg; break;
#endif
    case 'V': strerr_warn1(VERSION, 0);
    case '?': usage();
    }
  }
  argv +=optind;

  if (! argv || ! *argv) usage();
  host =*argv++;
  if (! argv || ! *argv) usage();
  local_port =*argv++;
  if (! argv || ! *argv) usage();
  prog =(const char **)argv;
  if (phccmax > cmax) phccmax =cmax;

  if (user)
    if (! uidgids_get(&ugid, user)) {
      if (errno)
        strerr_die4sys(111, FATAL, "unable to get user/group: ", user, ": ");
      strerr_die3x(100, FATAL, "unknown user/group: ", user);
    }
#ifdef SSLSVD
  svuser =user;
  client =0;
  if ((getuid() == 0) && (! ssluser))
    strerr_die2x(100, FATAL, "-U ssluser must be set when running as root");
  if (ssluser)
    if (! uidgids_get(&sslugid, ssluser)) {
      if (errno)
        strerr_die4sys(111, FATAL, "unable to get user/group: ", ssluser, ": ");
      strerr_die3x(100, FATAL, "unknown user/group: ", ssluser);
    }
  if (! cert) cert ="./cert.pem";
  if (! key) key =cert;
  if (matrixSslOpen() < 0) fatal("unable to initialize ssl");
  if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) {
    if (client) fatal("unable to read cert, key, or ca file");
    fatal("unable to read cert or key file");
  }
  if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0)
    strerr_die2x(111, FATAL, "unable to create ssl session");
#endif

  dns_random_init(seed);
  sig_block(sig_child);
  sig_catch(sig_child, sig_child_handler);
  sig_catch(sig_term, sig_term_handler);
  sig_ignore(sig_pipe);

  if (phccmax) if (ipsvd_phcc_init(cmax) == -1) die_nomem();

  if (str_equal(host, "")) host ="0.0.0.0";
  if (str_equal(host, "0")) host ="0.0.0.0";

  if (! ipsvd_scan_port(local_port, "tcp", &port))
    strerr_die3x(100, FATAL, "unknown port number or name: ", local_port);

  if (! stralloc_copys(&sa, host)) die_nomem();
  if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4))
    if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1)
      fatal2("unable to look up ip address", host);
  if (ips.len < 4)
    strerr_die3x(100, FATAL, "unable to look up ip address: ", host);
  ips.len =4;
  if (! stralloc_0(&ips)) die_nomem();
  local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0;

  if (! lookuphost) {
    if (! stralloc_copys(&remote_hostname, "")) die_nomem();
    if (! stralloc_0(&remote_hostname)) die_nomem();
  }

  if ((s =socket_tcp()) == -1) fatal("unable to create socket");
  if (socket_bind4_reuse(s, ips.s, port) == -1)
    fatal("unable to bind socket");
  if (listen(s, backlog) == -1) fatal("unable to listen");
  ndelay_off(s);

#ifdef SSLSVD
#else
  if (user) {
    /* drop permissions */
    if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups");
    if (setgid(*ugid.gid) == -1) fatal("unable to set gid");
    if (prot_uid(ugid.uid) == -1) fatal("unable to set uid");
  }
#endif
  close(0);

  if (verbose) {
    out(INFO); out("listening on "); outfix(local_ip); out(":");
    outfix(local_port);
#ifdef SSLSVD
#else
    if (user) {
      bufnum[fmt_ulong(bufnum, (unsigned long)ugid.uid)] =0;
      out(", uid "); out(bufnum);
      bufnum[fmt_ulong(bufnum, (unsigned long)ugid.gid)] =0;
      out(", gid "); out(bufnum);
    }
#endif
    flush(", starting.\n");
  }
  for (;;) {
    while (cnum >= cmax) sig_pause();
    socka_size =sizeof(socka);

    sig_unblock(sig_child);
    conn =accept(s, (struct sockaddr *)&socka, &socka_size);
    sig_block(sig_child);

    if (conn == -1) {
      if (errno != error_intr) warn("unable to accept connection");
      continue;
    }
    cnum++;

    if (verbose) connection_status();
    if (phccmax) phcc =ipsvd_phcc_add((char*)&socka.sin_addr);
    if ((pid =fork()) == -1) {
      warn2("drop connection", "unable to fork");
      close(conn);
      continue;
    }
    if (pid == 0) {
      /* child */
      close(s);
#ifdef SSLSVD
      if (*progname) *progname ='\\';
#endif
      connection_accept(conn);
    }
    if (phccmax) ipsvd_phcc_setpid(pid);
    close(conn);
  }
  _exit(0);
}
Exemplo n.º 9
0
int main(int argc, const char **argv) {
  int opt;
  int i;
  unsigned long ul;

  progname =argv[0];
  for (i =str_len(progname); i; --i)
    if (progname[i -1] == '/') {
      progname +=i;
      break;
    }
  if (progname[0] == 'd') ++progname;

  /* argv[0] */
  if (str_equal(progname, "setuidgid")) setuidgid(argc, argv);
  if (str_equal(progname, "envuidgid")) envuidgid(argc, argv);
  if (str_equal(progname, "envdir")) envdir(argc, argv);
  if (str_equal(progname, "pgrphack")) pgrphack(argc, argv);
  if (str_equal(progname, "setlock")) setlock(argc, argv);
  if (str_equal(progname, "softlimit")) softlimit(argc, argv);

  while ((opt =getopt(argc, argv, "u:U:b:e:m:d:o:p:f:c:r:t:/:n:l:L:vP012V"))
         != opteof)
    switch(opt) {
    case 'u': set_user =(char*)optarg; break;
    case 'U': env_user =(char*)optarg; break;
    case 'b': argv0 =(char*)optarg; break;
    case 'e': env_dir =optarg; break;
    case 'm':
      if (optarg[scan_ulong(optarg, &ul)]) usage();
      limits =limitl =limita =limitd =ul;
      break;
    case 'd': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitd =ul; break;
    case 'o': if (optarg[scan_ulong(optarg, &ul)]) usage(); limito =ul; break;
    case 'p': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitp =ul; break;
    case 'f': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitf =ul; break;
    case 'c': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitc =ul; break;
    case 'r': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitr =ul; break;
    case 't': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitt =ul; break;
    case '/': root =optarg; break;
    case 'n':
      switch (*optarg) {
        case '-':
          if (optarg[scan_ulong(++optarg, &ul)]) usage(); nicelvl =ul;
          nicelvl *=-1;
          break;
        case '+': ++optarg;
        default:
          if (optarg[scan_ulong(optarg, &ul)]) usage(); nicelvl =ul;
          break;
      }
      break;
    case 'l': if (lock) usage(); lock =optarg; lockdelay =1; break;
    case 'L': if (lock) usage(); lock =optarg; lockdelay =0; break;
    case 'v': verbose =1; break;
    case 'P': pgrp =1; break;
    case '0': nostdin =1; break;
    case '1': nostdout =1; break;
    case '2': nostderr =1; break;
    case 'V': strerr_warn1("$Id: f279d44141c981dd7535a12260efcf1ef7beed26 $", 0);
    case '?': usage();
    }
  argv +=optind;
  if (! argv || ! *argv) usage();

  if (pgrp) setsid();
  if (env_dir) edir(env_dir);
  if (root) {
    if (chdir(root) == -1) fatal2("unable to change directory", root);
    if (chroot(".") == -1) fatal("unable to change root directory");
  }
  if (nicelvl) {
    errno =0;
    if (nice(nicelvl) == -1) if (errno) fatal("unable to set nice level");
  }
  if (env_user) euidgid(env_user, 1);
  if (set_user) suidgid(set_user, 1);
  if (lock) slock(lock, lockdelay, 0);
  if (nostdin) if (close(0) == -1) fatal("unable to close stdin");
  if (nostdout) if (close(1) == -1) fatal("unable to close stdout");
  if (nostderr) if (close(2) == -1) fatal("unable to close stderr");
  slimit();

  progname =*argv;
  if (argv0) *argv =argv0;
  pathexec_env_run(progname, argv);
  fatal2("unable to run", *argv);
  return(0);
}