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]); }
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; }
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); }
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 }
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); }
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(); }
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); }
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); }