int chpst_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	INIT_G();

	if (applet_name[3] == 'd') envdir(argc, argv);
	if (applet_name[1] == 'o') softlimit(argc, argv);
	if (applet_name[0] == 's') setuidgid(argc, argv);
	if (applet_name[0] == 'e') envuidgid(argc, argv);
	// otherwise we are chpst

	{
		char *m,*d,*o,*p,*f,*c,*r,*t,*n;
		getopt32(argv, "+u:U:e:m:d:o:p:f:c:r:t:/:n:vP012",
				&set_user,&env_user,&env_dir,
				&m,&d,&o,&p,&f,&c,&r,&t,&root,&n);
		// if (option_mask32 & 0x1) // -u
		// if (option_mask32 & 0x2) // -U
		// if (option_mask32 & 0x4) // -e
		if (option_mask32 & 0x8) limits = limitl = limita = limitd = xatoul(m); // -m
		if (option_mask32 & 0x10) limitd = xatoul(d); // -d
		if (option_mask32 & 0x20) limito = xatoul(o); // -o
		if (option_mask32 & 0x40) limitp = xatoul(p); // -p
		if (option_mask32 & 0x80) limitf = xatoul(f); // -f
		if (option_mask32 & 0x100) limitc = xatoul(c); // -c
		if (option_mask32 & 0x200) limitr = xatoul(r); // -r
		if (option_mask32 & 0x400) limitt = xatoul(t); // -t
		// if (option_mask32 & 0x800) // -/
		if (option_mask32 & 0x1000) nicelvl = xatoi(n); // -n
		// The below consts should match #defines at top!
		//if (option_mask32 & 0x2000) OPT_verbose = 1; // -v
		//if (option_mask32 & 0x4000) OPT_pgrp = 1; // -P
		//if (option_mask32 & 0x8000) OPT_nostdin = 1; // -0
		//if (option_mask32 & 0x10000) OPT_nostdout = 1; // -1
		//if (option_mask32 & 0x20000) OPT_nostderr = 1; // -2
	}
	argv += optind;
	if (!argv || !*argv) bb_show_usage();

	if (OPT_pgrp) setsid();
	if (env_dir) edir(env_dir);
	if (root) {
		xchdir(root);
		xchroot(".");
	}
	slimit();
	if (nicelvl) {
		errno = 0;
		if (nice(nicelvl) == -1)
			bb_perror_msg_and_die("nice");
	}
	if (env_user) euidgid(env_user);
	if (set_user) suidgid(set_user);
	if (OPT_nostdin) close(0);
	if (OPT_nostdout) close(1);
	if (OPT_nostderr) close(2);
	BB_EXECVP(argv[0], argv);
	bb_perror_msg_and_die("exec %s", argv[0]);
}
Beispiel #2
0
static void startchild(char **argv, const char *userarg, const char *grouparg)
{
pid_t p;
int pipefd[2];
int tmp;

	signal(SIGTERM, sigterm);
	signal(SIGHUP, sighup);

	/* Make sure the pipefds are at least 3 and 4. If we have an open
	   stderr then keep it around for debugging purposes. */
	close(0);
	checkfd(open("/dev/null", O_RDWR), 0);
	close(1);
	checkfd(dup(0), 1);
	if ((tmp = dup(0)) > 2) close(tmp);

	if (pipe(pipefd) < 0)
	{
		perror("pipe");
		exit(1);
	}
	p = fork();
	if (p < 0)
	{
		perror("fork");
		exit(1);
	}
	if (p == 0)
	{

		close(pipefd[0]);
		close(2);
		checkfd(dup(pipefd[1]), 2);
		close(pipefd[1]);
		setuidgid(userarg, grouparg);
		execvp(argv[0], argv);
		perror("exec");
		exit(1);
	}

	// We can close stderr now

	close(2);
	checkfd(dup(0), 2);


	close(pipefd[1]);
	close(0);
	checkfd(dup(pipefd[0]), 0);
	close(pipefd[0]);
	child_pid = p;
}
Beispiel #3
0
void make_sockets(void)
{
  int i;
  for(i = 0; i < num_sockets; i++) {
    struct sockaddr_in sa;
    if((sockets[i] = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
      die("Could not create socket");
    make_sockaddr_in(socket_names[i*2], socket_names[i*2+1], &sa);
    if(bind(sockets[i], (struct sockaddr*)&sa, sizeof sa))
      die("Could not bind socket to address");
  }
  setuidgid(opt_uid, opt_gid);
}
Beispiel #4
0
void Anope::Fork()
{
#ifndef _WIN32
	kill(getppid(), SIGUSR2);

	freopen("/dev/null", "r", stdin);
	freopen("/dev/null", "w", stdout);
	freopen("/dev/null", "w", stderr);

	setpgid(0, 0);

	setuidgid();
#else
	FreeConsole();
#endif
}
Beispiel #5
0
void make_sockets(void)
{
    int i;
    umask(opt_umask);
    for(i = 0; i < num_sockets; i++)
        if((sockets[i] = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
            die("Could not create socket");
    for(i = 0; i < num_sockets; i++) {
        struct sockaddr_un sa;
        sa.sun_family = AF_UNIX;
        strcpy(sa.sun_path, socket_names[i]);
        unlink(socket_names[i]);
        if(bind(sockets[i], (struct sockaddr*)&sa, sizeof sa))
            die("Could not bind socket to path");
    }
    setuidgid(opt_uid, opt_gid);
}
Beispiel #6
0
void Anope::Init(int ac, char **av)
{
	/* Set file creation mask and group ID. */
#if defined(DEFUMASK) && HAVE_UMASK
	umask(DEFUMASK);
#endif

	/* Parse command line arguments */
	ParseCommandLineArguments(ac, av);

	if (GetCommandLineArgument("version", 'v'))
	{
		Log(LOG_TERMINAL) << "Anope-" << Anope::Version() << " -- " << Anope::VersionBuildString();
		throw CoreException();
	}

	if (GetCommandLineArgument("help", 'h'))
	{
		Log(LOG_TERMINAL) << "Anope-" << Anope::Version() << " -- " << Anope::VersionBuildString();
		Log(LOG_TERMINAL) << "Anope IRC Services (http://www.anope.org)";
		Log(LOG_TERMINAL) << "Usage ./" << Anope::ServicesBin << " [options] ...";
		Log(LOG_TERMINAL) << "-c, --config=filename.conf";
		Log(LOG_TERMINAL) << "    --confdir=conf file direcory";
		Log(LOG_TERMINAL) << "    --dbdir=database directory";
		Log(LOG_TERMINAL) << "-d, --debug[=level]";
		Log(LOG_TERMINAL) << "-h, --help";
		Log(LOG_TERMINAL) << "    --localedir=locale directory";
		Log(LOG_TERMINAL) << "    --logdir=logs directory";
		Log(LOG_TERMINAL) << "    --modulesdir=modules directory";
		Log(LOG_TERMINAL) << "-e, --noexpire";
		Log(LOG_TERMINAL) << "-n, --nofork";
		Log(LOG_TERMINAL) << "    --nothird";
		Log(LOG_TERMINAL) << "    --protocoldebug";
		Log(LOG_TERMINAL) << "-r, --readonly";
		Log(LOG_TERMINAL) << "-s, --support";
		Log(LOG_TERMINAL) << "-v, --version";
		Log(LOG_TERMINAL) << "";
		Log(LOG_TERMINAL) << "Further support is available from http://www.anope.org";
		Log(LOG_TERMINAL) << "Or visit us on IRC at irc.anope.org #anope";
		throw CoreException();
	}

	if (GetCommandLineArgument("nofork", 'n'))
		Anope::NoFork = true;

	if (GetCommandLineArgument("support", 's'))
	{
		Anope::NoFork = Anope::NoThird = true;
		++Anope::Debug;
	}

	if (GetCommandLineArgument("readonly", 'r'))
		Anope::ReadOnly = true;

	if (GetCommandLineArgument("nothird"))
		Anope::NoThird = true;

	if (GetCommandLineArgument("noexpire", 'e'))
		Anope::NoExpire = true;

	if (GetCommandLineArgument("protocoldebug"))
		Anope::ProtocolDebug = true;

	Anope::string arg;
	if (GetCommandLineArgument("debug", 'd', arg))
	{
		if (!arg.empty())
		{
			int level = arg.is_number_only() ? convertTo<int>(arg) : -1;
			if (level > 0)
				Anope::Debug = level;
			else
				throw CoreException("Invalid option given to --debug");
		}
		else
			++Anope::Debug;
	}

	if (GetCommandLineArgument("config", 'c', arg))
	{
		if (arg.empty())
			throw CoreException("The --config option requires a file name");
		ServicesConf = Configuration::File(arg, false);
	}

	if (GetCommandLineArgument("confdir", 0, arg))
	{
		if (arg.empty())
			throw CoreException("The --confdir option requires a path");
		Anope::ConfigDir = arg;
	}

	if (GetCommandLineArgument("dbdir", 0, arg))
	{
		if (arg.empty())
			throw CoreException("The --dbdir option requires a path");
		Anope::DataDir = arg;
	}

	if (GetCommandLineArgument("localedir", 0, arg))
	{
		if (arg.empty())
			throw CoreException("The --localedir option requires a path");
		Anope::LocaleDir = arg;
	}

	if (GetCommandLineArgument("modulesdir", 0, arg))
	{
		if (arg.empty())
			throw CoreException("The --modulesdir option requires a path");
		Anope::ModuleDir = arg;
	}

	if (GetCommandLineArgument("logdir", 0, arg))
	{
		if (arg.empty())
			throw CoreException("The --logdir option requires a path");
		Anope::LogDir = arg;
	}

	/* Chdir to Services data directory. */
	if (chdir(Anope::ServicesDir.c_str()) < 0)
	{
		throw CoreException("Unable to chdir to " + Anope::ServicesDir + ": " + Anope::LastError());
	}

	Log(LOG_TERMINAL) << "Anope " << Anope::Version() << ", " << Anope::VersionBuildString();

#ifdef _WIN32
	if (!SupportedWindowsVersion())
		throw CoreException(GetWindowsVersion() + " is not a supported version of Windows");
#else
	/* If we're root, issue a warning now */
	if (!getuid() && !getgid())
	{
		/* If we are configured to setuid later, don't issue a warning */
		Configuration::Block *options = Config->GetBlock("options");
		if (options->Get<Anope::string>("user").empty())
		{
			std::cerr << "WARNING: You are currently running Anope as the root superuser. Anope does not" << std::endl;
			std::cerr << "         require root privileges to run, and it is discouraged that you run Anope" << std::endl;
			std::cerr << "         as the root superuser." << std::endl;
			sleep(3);
		}
	}
#endif

#ifdef _WIN32
	Log(LOG_TERMINAL) << "Using configuration file " << Anope::ConfigDir << "\\" << ServicesConf.GetName();
#else
	Log(LOG_TERMINAL) << "Using configuration file " << Anope::ConfigDir << "/" << ServicesConf.GetName();

	/* Fork to background */
	if (!Anope::NoFork)
	{
		/* Install these before fork() - it is possible for the child to
		 * connect and kill() the parent before it is able to install the
		 * handler.
		 */
		struct sigaction sa, old_sigusr2, old_sigchld;

		sa.sa_flags = 0;
		sigemptyset(&sa.sa_mask);
		sa.sa_handler = parent_signal_handler;

		sigaction(SIGUSR2, &sa, &old_sigusr2);
		sigaction(SIGCHLD, &sa, &old_sigchld);

		int i = fork();
		if (i > 0)
		{
			sigset_t mask;

			sigemptyset(&mask);
			sigsuspend(&mask);

			exit(Anope::ReturnValue);
		}
		else if (i == -1)
		{
			Log() << "Error, unable to fork: " << Anope::LastError();
			Anope::NoFork = true;
		}

		/* Child doesn't need these */
		sigaction(SIGUSR2, &old_sigusr2, NULL);
		sigaction(SIGCHLD, &old_sigchld, NULL);
	}

#endif

	/* Initialize the socket engine. Note that some engines can not survive a fork(), so this must be here. */
	SocketEngine::Init();

	ServiceManager::Init();
	EventManager::Init();

	new BotInfoType();
	new XLineType(nullptr);
	new OperBlockType();

	/* Read configuration file; exit if there are problems. */
	try
	{
		Config = new Configuration::Conf();
	}
	catch (const ConfigException &ex)
	{
		Log(LOG_TERMINAL) << ex.GetReason();
		Log(LOG_TERMINAL) << "*** Support resources: Read through the anope.conf self-contained";
		Log(LOG_TERMINAL) << "*** documentation. Read the documentation files found in the 'docs'";
		Log(LOG_TERMINAL) << "*** folder. Visit our portal located at http://www.anope.org/. Join";
		Log(LOG_TERMINAL) << "*** our support channel on /server irc.anope.org channel #anope.";
		throw CoreException("Configuration file failed to validate");
	}

	/* Create me */
	Configuration::Block *block = Config->GetBlock("serverinfo");
	Me = new Server(NULL, block->Get<Anope::string>("name"), 0, block->Get<Anope::string>("description"), block->Get<Anope::string>("id"));
	for (std::pair<Anope::string, User *> p : UserListByNick)
	{
		User *u = p.second;
		if (u->type != UserType::BOT)
			continue;

		ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
		bi->server = Me;
		++Me->users;
	}

	/* Announce ourselves to the logfile. */
	Log() << "Anope " << Anope::Version() << " starting up" << (Anope::Debug || Anope::ReadOnly ? " (options:" : "") << (Anope::Debug ? " debug" : "") << (Anope::ReadOnly ? " readonly" : "") << (Anope::Debug || Anope::ReadOnly ? ")" : "");

	InitSignals();

	/* Initialize multi-language support */
	Language::InitLanguages();

	/* Initialize random number generator */
	block = Config->GetBlock("options");
	srand(block->Get<unsigned>("seed") ^ time(NULL));

	ModeManager::Apply(nullptr);

	/* load modules */
	Log() << "Loading modules...";
	for (int i = 0; i < Config->CountBlock("module"); ++i)
		ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<Anope::string>("name"), NULL);

#ifndef _WIN32
	/* We won't background later, so we should setuid now */
	if (Anope::NoFork)
		setuidgid();
#endif

	Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
	if (protocol == NULL)
		throw CoreException("You must load a protocol module!");

	/* Write our PID to the PID file. */
	write_pidfile();

	Log() << "Using IRCd protocol " << protocol->name;

	/* Auto assign sid if applicable */
	if (IRCD->RequiresID)
	{
		Anope::string sid = IRCD->SID_Retrieve();
		if (Me->GetSID() == Me->GetName())
			Me->SetSID(sid);
		for (std::pair<Anope::string, User *> p : UserListByNick)
		{
			User *u = p.second;
			if (u->type != UserType::BOT)
				continue;

			ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
			bi->GenerateUID();
		}
	}

	/* Load up databases */
	Log() << "Loading databases...";
	EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::LoadDatabase::OnLoadDatabase);;
	static_cast<void>(MOD_RESULT);
	Log() << "Databases loaded";

	for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
		it->second->Sync();
}
Beispiel #7
0
int main(int argc, char **argv)
{
int facility = LOG_DEST;
int daemon = 0;
int lockfd = -1;
const char *userarg = 0;
const char *grouparg = 0;
int droproot=0;

	if (argc == 2 && argv[1][0] != '-')
	{
		/* backwards-compatibility mode */
		close(1);
		close(2);
		checkfd(open("/dev/null", O_WRONLY), 1);
		checkfd(open("/dev/null", O_WRONLY), 2);
		do_logger(argv[1], facility, stdin);
		exit(0);
	}

	if (argc <= 1)
	{
		fprintf(stderr,

			"Usage: courierlogger [-name=name] [-pid=pidfile] [-facility=type]\n"
			"       [-start|-stop|-restart] [cmd [args...]]\n"
		);
		exit(1);
	}

	argv++, argc--;
	while (argc > 0 && argv[0][0]=='-')
	{
		if (strncmp(argv[0],"-pid=",5) == 0 && argv[0][5])
		{
			pidarg=&argv[0][5];
			lockfilename=malloc(strlen(pidarg)+sizeof(".lock"));
			if (!lockfilename)
			{
				perror("malloc");
				exit(1);
			}
			strcat(strcpy(lockfilename, pidarg), ".lock");
		}
		else
		if (strncmp(argv[0],"-name=",6) == 0 && argv[0][6])
			namearg=&argv[0][6];
		else if (strncmp(argv[0],"-user="******"-group=",7) == 0)
			grouparg=argv[0]+7;
		else if (strcmp(argv[0], "-droproot") == 0)
			droproot=1;
		else
		if (strncmp(argv[0],"-facility=",10) == 0)
		{
		struct lognames *p = facilitynames;

			while (p->name && strcmp(p->name, &argv[0][10]))
				p++;
			if (p->name == 0)
			{
				fprintf(stderr, "Unknown facility name '%s'\n",
					&argv[0][10]);
				exit(1);
			}
			facility = p->value;
		}
		else
		if (strcmp(argv[0],"-start") == 0)
			daemon = 1;
		else
		if (strcmp(argv[0],"-stop") == 0)
			daemon = 2;
		else
		if (strcmp(argv[0],"-restart") == 0)
			daemon = 3;
		else
		if (strcmp(argv[0],"-respawn") == 0)
			respawn = 1;
		else
		{
			fprintf(stderr, "Unknown option '%s'\n", argv[0]);
			exit(1);
		}
		argv++, argc--;
	}

	if (daemon && !pidarg)
	{
		fprintf(stderr, "-pid argument required\n");
		exit(1);
	}

	if (!daemon && pidarg)
		daemon = 1; /* -start implied */

	if (!namearg && daemon != 2 && daemon != 3)
	{
		/* choose a default name based on the program we're running */
		if (argc <= 0 || !argv[0] || !argv[0][0])
		{
			fprintf(stderr, "-name option required for standalone logger\n");
			exit(1);
		}
		namearg = strrchr(argv[0],'/');
		namearg = namearg ? namearg+1 : argv[0];
	}

	switch (daemon)
	{
	case 1: /* start */
		if (argc <= 0 || !argv[0] || !argv[0][0])
		{
			fprintf(stderr, "-start must be followed by a command to execute\n");
			exit(1);
		}
		lockfd=ll_daemon_start(lockfilename);
		if (lockfd < 0)
		{
			perror("ll_daemon_start");
			exit(1);
		}
		startchild(argv, droproot ? userarg:NULL,
			   droproot ? grouparg:NULL);
		ll_daemon_started(pidarg, lockfd);
		break;
	case 2: /* stop */
		exit(ll_daemon_stop(lockfilename, pidarg));
	case 3: /* restart */
		exit(ll_daemon_restart(lockfilename, pidarg));
	default: /* run in foreground, with or without a child process */

		if (argc > 0)
			startchild(argv, droproot ? userarg:NULL,
				   droproot ? grouparg:NULL);
	}

	setuidgid(userarg, grouparg);

	while (1)
	{
	int waitstat;
	pid_t p2;
	FILE *f = fdopen(0, "r");

		do_logger(namearg, facility, f);
		fclose(f);
		if (child_pid < 0) break;
		while ((p2=wait(&waitstat)) != child_pid &&
			(p2 != -1 || errno != ECHILD))
			;
		if (hup_restart)
			hup_restart = 0;
		else if (respawn)
			sleep (5);
		else
			break;
		startchild(argv, NULL, NULL);
	}
	exit(0);
}
Beispiel #8
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);
}