Ejemplo n.º 1
0
static void exec_cmd(int fdin, int fdout,
		     const char** argv,
		     const str* env,
		     const struct passwd* pw)
{
  selfpipe_close();
  dup2(fdin, 0);
  dup2(fdout, 1);
  dup2(fdout, 2);
  close(fdin);
  close(fdout);
  if (!testmode) {
    if (initgroups(pw->pw_name, pw->pw_gid) != 0)
      die1sys(111, "Could not initgroups");
    if (setgid(pw->pw_gid) != 0)
      die1sys(111, "Could not setgid");
    if (setuid(pw->pw_uid) != 0)
      die1sys(111, "Could not setuid");
  }
  if (chdir(pw->pw_dir) != 0)
    die1sys(111, "Could not change directory");
  if (env)
    if ((environ = envstr_make_array(env)) == 0)
      die_oom(111);
  execv(argv[0], (char**)argv);
  die3sys(111, "Could not execute '", argv[0], "'");
  exit(111);
}
Ejemplo n.º 2
0
int fork_inject(const char* sender)
{
  int p[2];

  debug6(1, "forking ", opt_qmail_inject, " -f '' -a -- '", sender, "' ", extra_rcpt);

  if(opt_nosend) {
    inject_pid = 0;
    return dup(1);
  }
  
  if (pipe(p) != 0)
    die1sys(111, "Could not create pipe");
  inject_pid = fork();
  switch(inject_pid) {
  case -1:
    die1sys(111, "Could not fork");
  case 0:
    wrap_chdir(qmail_home);
    close(p[1]);
    close(0);
    dup2(p[0], 0);
    close(p[0]);
    execl(opt_qmail_inject, opt_qmail_inject, "-f", "", "-a", "--", sender, extra_rcpt, NULL);
    die1sys(111, "Exec of qmail-inject failed");
  default:
    close(p[0]);
    return p[1];
  }
}
Ejemplo n.º 3
0
int main(int argc, char* argv[])
{
  struct connection conn;
  iopoll_fd fds[2];
  int selfpipe;
  int i;

  msg_debug_init();
  testmode = getenv("TESTMODE") != 0;

  if ((shell_argv = malloc((argc + 3) * sizeof *argv)) == 0)
    die_oom(111);
  for (i = 1; i < argc; ++i)
    shell_argv[i-1] = argv[i];
  for (; i < argc + 4; ++i)
    shell_argv[i-1] = 0;
  shell_argc = argc - 1;

  if ((path = getenv("PATH")) == 0)
    die1(111, "No PATH is set");
  if ((devnull = open("/dev/null", O_RDWR)) == -1)
    die1sys(111, "Could not open \"/dev/null\"");
  if (!nonblock_on(0))
    die1sys(111, "Could not set non-blocking status");
  if ((selfpipe = selfpipe_init()) == -1)
    die1sys(111, "Could not create self-pipe");
  init_slots();
  connection_init(&conn, 0, 0);
  fds[0].fd = 0;
  fds[0].events = IOPOLL_READ;
  fds[1].fd = selfpipe;
  fds[1].events = IOPOLL_READ;
  for (;;) {
    if (iopoll_restart(fds, 2, -1) == -1)
      die1sys(111, "Poll failed");
    if (fds[0].revents)
      if (connection_read(&conn, handle_packet) <= 0)
	break;
    if (fds[1].revents) {
      read(selfpipe, &i, 1);
      handle_child(WNOHANG);
    }
  }
  msg1("Waiting for remaining slots to complete");
  while (slots_used > 0)
    handle_child(0);
  return 0;
}
Ejemplo n.º 4
0
int main(int argc, char* argv[])
{
  const char* dir;
  int fd;
  struct stat s;
  char fdstr[32];
  
  if (argc < 2) die1(1, "usage: relay-ctrl-chdir program [arguments]\n");
  if ((dir = getenv("RELAY_CTRL_DIR")) == 0)
    die1(111, "$RELAY_CTRL_DIR is not set.");
  else if ((fd = open(dir, O_RDONLY)) == -1)
    die3sys(111, "Could not open dir '", dir, "'");
  else if (fstat(fd, &s) == -1)
    die1sys(111, "Could not stat opened file");
  else if (!S_ISDIR(s.st_mode))
    die3(111, "'", dir, "' is not a directory");
  else {
    fd = move_high(fd);
    utoa2(fd, fdstr);
    if (setenv("RELAY_CTRL_DIR_FD", fdstr, 1) == -1)
      die1(111, "Could not set environment variable");
  }
  execvp(argv[1], argv+1);
  die1(111, "execution of program failed!\n");
  return 111;
  argc = 0;
}
Ejemplo n.º 5
0
void touch_run_file(void)
{
  obuf out;
  if (!obuf_open(&out, opt_run_file, OBUF_CREATE|OBUF_TRUNCATE, 0666, 0) ||
      !obuf_putu(&out, now) ||
      !obuf_close(&out))
    die1sys(111, "Could not update run file");
}
Ejemplo n.º 6
0
void minifstat(int fd, struct ministat* s)
{
  struct stat st;
  if (fstat(fd, &st) != 0)
    die1sys(111, "Could not fstat");
  else
    copystat(s, &st);
}
Ejemplo n.º 7
0
void send_bounce(const char* sender, const char* filename,
		 const char* remotes, const char* locals, time_t age)
{
  int fd = fork_inject(sender);
  make_bounce_body(fd, sender, filename, remotes, locals, age);
  if (close(fd) != 0)
    die1sys(111, "Writing to qmail-inject failed");
  wait_inject();
}
Ejemplo n.º 8
0
int main(int argc, char* argv[])
{
  if (argc < 5) usage("Too few parameters");
  if (argc > 7) usage("Too many parameters");
  logacct = getpwnam(argv[1]);
  maindir = argv[2];
  logdir = argv[3];
  if (maindir[0] != '/' || logdir[0] != '/')
    die1(1, "Directory names must start with /.");
  cvmpath = argv[4];
  if (argc > 5) {
    ip = argv[5];
    if (argc > 6) dochroot = argv[6];
  }
  if (!logacct) die1(1, "Unknown logacct user name");

  umask(0);

  if (mkdir(maindir, 0755) == -1) die1sys(1, "Error creating main directory");
  if (chmod(maindir, 01755) == -1)
    die1sys(1, "Error setting permissions on main directory");
  
  if (mkdir(logdir, 0700) == -1) die1sys(1, "Error creating log directory");
  if (chown(logdir, logacct->pw_uid, logacct->pw_gid) == -1)
    die1sys(1, "Error setting owner on log directory");

  if (chdir(maindir) == -1) die1sys(1, "Error changing to main directory");
  if (mkdir("log", 0755) == -1)
    die1sys(1, "Error creating log service directory");
  if (mkdir("env", 0755) == -1)
    die1sys(1, "Error creating env directory");

  start_file("run", 0755);
  obuf_put5s(&conf_out,
	     "#!/bin/sh\n"
	     "exec 2>&1\n"
	     "umask 022\n"
	     "exec \\\n"
	     "tcpserver -DRHv -llocalhost ", ip, " 21 \\\n"
	     "envdir ", maindir, "/env \\\n");
  obuf_put7s(&conf_out,
	     "softlimit -m 2000000 \\\n",
	     conf_bin, "/twoftpd-auth \\\n",
	     cvmpath, " \\\n",
	     conf_bin, "/twoftpd-xfer");
  end_file();

  make_file("log/run", 0755,
	    "#!/bin/sh\n"
	    "exec \\\n"
	    "setuidgid ", logacct->pw_name, " \\\n"
	    "multilog t ", logdir, 0, 0, 0);
  
  if (dochroot) make_fileu("env/CHROOT", 1);
  
  return 0;
}
Ejemplo n.º 9
0
static void load_keys(const char* server)
{
  str path = {0,0,0};

  wrap_str(str_copy4s(&path, keydir, "/servers/", server, "."));
  if (!keylist_load_multi(&server_publics, path.s, 0) &&
      !keylist_load_multi(&server_publics, "server.", 0))
    die1sys(1, "Could not load server keys");

  if (!keylist_load_multi(&client_secrets, "", 0)) {
    wrap_str(str_copy2s(&path, keydir, "/"));
    if (!keylist_load_multi(&client_secrets, path.s, 0))
      die1sys(1, "Could not load sender keys");
  }

  if (!keylist_exchange_all(&shared_secrets, &server_publics, &client_secrets))
    die1(1, "No server keys matched any sender keys");
  
  str_free(&path);
}
Ejemplo n.º 10
0
void wait_inject(void)
{
  int status;
  if(inject_pid) {
    if(waitpid(inject_pid, &status, WUNTRACED) == -1)
      die1sys(111, "Could not wait for qmail-inject to exit");
    if(!WIFEXITED(status))
      die1(111, "qmail-inject crashed");
    if(WEXITSTATUS(status))
      die1(111, "qmail-inject exited with an error");
  }
}
Ejemplo n.º 11
0
void scan_queue(void)
{
  DIR* dir;
  direntry* entry;
  wrap_chdir(qmail_home);
  wrap_chdir("queue");
  if((dir = opendir("info")) == 0)
    die1sys(111, "Can't open queue directory");
  while((entry = readdir(dir)) != 0)
    if(entry->d_name[0] != '.')
      scan_dir(entry->d_name);
  closedir(dir);
}
Ejemplo n.º 12
0
static void prep_sender(void)
{
  static char hostname[256];
  char* p;
  
  if ((sender = getenv("SENDER")) == 0) {
    if (gethostname(hostname, sizeof hostname) != 0)
      die1sys(1, "gethostname failed");
    hostname[sizeof hostname - 1] = 0;
    if ((p = strchr(hostname, '.')) != 0)
      *p = 0;
    sender = hostname;
  }
}
Ejemplo n.º 13
0
static int poll_both(void)
{
  struct timeval timestamp;
  int ready;

  /* Sanity check to make sure no data is lost */
  if (inbuf.io.buflen > inbuf.io.bufstart) {
    stdin_ready = IOPOLL_READ;
    sock_ready = 0;
    return 1;
  }

  /* Calculate remaining timeout */
  gettimeofday(&timestamp, 0);
  if (poll_timestamp.tv_sec != 0) {
    poll_timeout -= (timestamp.tv_sec - poll_timestamp.tv_sec) * 1000 +
      (timestamp.tv_usec - poll_timestamp.tv_usec) / 1000;
    if (poll_timeout < 0) poll_timeout = 0;
  }
  poll_timestamp = timestamp;

  io[0].fd = stdin_eof ? -1 : 0;
  io[0].events = stdin_eof ? 0 : IOPOLL_READ;
  io[1].fd = sock;
  io[1].events = IOPOLL_READ;

  switch (ready = iopoll(io, 2, poll_timeout)) {
  case -1:
    if (errno == EAGAIN || errno == EINTR)
      exitasap = 1;
    else
      die1sys(1, "Poll failed!");
    return 0;
  case 0:
    poll_timeout = 0;
    return 0;
  default:
    if (stdin_error) {
      stdin_eof = 1;
      if (exitoneof || seq_next == seq_send)
	exitasap = 1;
      io[0].revents = 0;
    }
    return ready;
  }
}
Ejemplo n.º 14
0
void scan_dir(const char* dirnum)
{
  DIR* dir;
  direntry* entry;
  char buf1[100];
  strcpy(buf1, "info/");
  strcpy(buf1+5, dirnum);
  if((dir = opendir(buf1)) == 0)
    die1sys(111, "Can't open queue directory");
  while((entry = readdir(dir)) != 0) {
    if(entry->d_name[0] != '.') {
      char filename[100];
      strcpy(filename, dirnum);
      strcat(filename, "/");
      strcat(filename, entry->d_name);
      scan_info(filename);
    }
  }
  closedir(dir);
}
Ejemplo n.º 15
0
int cli_main(int argc, char* argv[])
{
  const char* server_name = 0;
  const char* env;

  msg_debug_init();
  encr_start();
  prep_sender();
  service = argv[0];
  if (argc > 1
      && argv[1][0] != '-'
      && argv[1][0] != '+') {
    server_name = argv[1];
    ++argv;
    --argc;
  }
  if (argc > 1)
    load_patterns(argv + 1);

  if (server_name == 0
      && (server_name = getenv("SERVER")) == 0)
    die1(1, "Server address not named on command line nor in $SERVER");
  if (!resolve_ipv4name(server_name, &ip))
    die3(1, "Could not resolve '", server_name, "'");

  brandom_init();
  if ((env = getenv("KEYDIR")) != 0)
    keydir = env;
  load_keys(server_name);

  if ((env = getenv("PORT")) != 0)
    port = strtoul(env, 0, 10);
  if (port == 0)
    port = 11014;
  if ((sock = socket_udp()) == -1)
    die1sys(1, "Could not create UDP socket");
  if (!socket_connect4(sock, &ip, port))
    die1sys(1, "Could not bind socket");
  if (!str_ready(&packet, 65535)
      || !str_ready(&rpacket, 4+4+8+256*5))
    die1(1, "Out of memory");

  getenvu("ACK_TIMEOUT", &ack_timeout);
  getenvu("CID_TIMEOUT", &cid_timeout);
  getenvu("RETRANSMITS", &retransmits);
  getenvu("READWAIT", &readwait);
  getenvu("STARTLINES", &startlines);
  if (getenv("EXITONEOF") != 0)
    exitoneof = 1;

  if (getenv("NOFILES") == 0 && getenv("NOFILE") == 0)
    buffer = buffer_file_init();
  else
    buffer = buffer_nofile_init();

  sig_all_catch(sigfn);
  exitasap = 0;

  mainloop();
  return 0;
}