public static function setuidgid($user) { $uid = posix_getuid(); if ($uid !== 0) { throw new \RuntimeException("setuidgid is only root"); } $nam = posix_getpwnam($user); if (!$nam) { throw new \RuntimeException("unkonwn user \"{$user}\""); } $uid = $nam['uid']; $gid = $nam['gid']; if (!posix_setgid($gid)) { throw new \RuntimeException("unable setgid({$gid})"); } if (!posix_setegid($gid)) { throw new \RuntimeException("unable setegid({$gid})"); } if (!posix_setuid($uid)) { throw new \RuntimeException("unable setuid({$uid})"); } if (!posix_seteuid($uid)) { throw new \RuntimeException("unable seteuid({$uid})"); } }
/** * 此事件在worker进程启动时发生。这里创建的对象可以在worker进程生命周期内使用。 * * @param ISwoole $sw * @param int $worker_id */ function onWorkerStart($sw, $worker_id) { $this->ctx->pid = getmypid(); $user = posix_getpwnam($this->ctx->cfgs['default']['owner']['user']); posix_setuid($user['uid']); posix_setgid($user['gid']); $this->worker_id = $worker_id; }
/** * 设置进程运行账号 * @param [type] $user [description] */ public static function setUser($user) { $userInfo = posix_getpwnam($user); if (!$userInfo) { return; } posix_setgid($userInfo['gid']); posix_setuid($userInfo['uid']); }
public static function setUid($uid, $gid) { if (!posix_setgid($gid)) { // 必须先设置GID, 再设置UID throw new Exception("Unable to set GID: " . posix_strerror(posix_get_last_error())); } if (!posix_setuid($uid)) { throw new Exception("Unable to set UID: " . posix_strerror(posix_get_last_error())); } }
/** * Change the identity to a non-priv user */ function change_identity($uid, $gid) { if (!posix_setgid($gid)) { print "Unable to setgid to " . $gid . "!\n"; exit; } if (!posix_setuid($uid)) { print "Unable to setuid to " . $uid . "!\n"; exit; } }
/** * 改变进程的用户ID * @param $user */ static function changeUser($user) { if (!function_exists('posix_getpwnam')) { trigger_error(__METHOD__ . ": require posix extension."); return; } $user = posix_getpwnam($user); if ($user) { posix_setuid($user['uid']); posix_setgid($user['gid']); } }
function onStart($serv) { if (!defined('WEBROOT')) { define('WEBROOT', $this->config['server']['webroot']); } if (isset($this->config['server']['user'])) { $user = posix_getpwnam($this->config['server']['user']); if ($user) { posix_setuid($user['uid']); posix_setgid($user['gid']); } } $this->log(self::SOFTWARE . ". running. on {$this->server->host}:{$this->server->port}"); }
/** * 构造方法 */ public function __construct($setting) { $this->config = $setting['config']; $this->cronPath = $setting['cron_path']; if (isset($setting['group'])) { $groupinfo = posix_getpwnam($setting['group']); posix_setgid($groupinfo['gid']); } if (isset($setting['user'])) { $userinfo = posix_getgrnam($setting['user']); posix_setuid($groupinfo['uid']); } include __DIR__ . '/ParseCrontab.php'; include __DIR__ . '/ParseInterval.php'; }
protected function dropPrivileges(array $server) { if (!array_key_exists('user', $server) and !array_key_exists('group', $server)) { // nothing to do return; } if (posix_getuid() != 0) { echo "\n[Warning] Can't change uid/gid because aip is not run by superuser\n"; return; } if (isset($server['user'])) { posix_setuid(self::getUserId($server['user'])); } if (isset($server['group'])) { posix_setgid(self::getGroupId($server['group'])); } }
function run($work) { if (1 === posix_getppid()) { return; } if ($this->user) { if (!posix_setgid($this->user['gid']) || !posix_setuid($this->user['uid'])) { throw new \RuntimeException("Unable to switch to user '{$this->user['name']}'"); } } Utility::fork(function () use($work) { if (-1 === posix_setsid()) { throw new \RuntimeException('Unable to set setsid()'); } if (false === chdir('/')) { throw new \RuntimeException('Unable to chdir(\'/\')'); } umask(0); Utility::fork($work); }); }
/** * @return bool */ private function changeUser() { $user = $this->container->getConfig()->get('command.user'); // Bypass cache commands as we need the sudoer user to run the commands if (null !== $user && (!isset($_SERVER['argv'][1]) || $_SERVER['argv'][1] !== 'flushall') && (!isset($_SERVER['argv'][1]) || $_SERVER['argv'][1] !== 'redis:flushall') && (!isset($_SERVER['argv'][1]) || $_SERVER['argv'][1] !== 'apc:flushall')) { $name = $user; $user = posix_getpwnam($user); posix_setgid($user['gid']); posix_setuid($user['uid']); if (posix_geteuid() !== (int) $user['uid']) { $output = new ConsoleOutput(); $formatter = new FormatterHelper(); $output->writeln('', true); $errorMessages = array('', ' [Error] ', ' Could not change user to ' . $name . ' ', ''); $formattedBlock = $formatter->formatBlock($errorMessages, 'error'); $output->writeln($formattedBlock); $output->writeln('', true); return false; } } return true; }
/** * Function to prepare a node before starging it * * @param Node $n The Node * @param Int $id Node ID * @param Int $t Tenant ID * @param Array $nets Array of networks * @return int 0 Means ok */ function prepareNode($n, $id, $t, $nets) { $user = '******' . $t; // Get UID from username $cmd = 'id -u ' . $user . ' 2>&1'; exec($cmd, $o, $rc); $uid = $o[0]; // Creating TAP interfaces foreach ($n->getEthernets() as $interface_id => $interface) { $tap_name = 'vunl' . $t . '_' . $id . '_' . $interface_id; if (isset($nets[$interface->getNetworkId()]) && $nets[$interface->getNetworkId()]->isCloud()) { // Network is a Cloud $net_name = $nets[$interface->getNetworkId()]->getNType(); } else { $net_name = 'vnet' . $t . '_' . $interface->getNetworkId(); } // Remove interface $rc = delTap($tap_name); if ($rc !== 0) { // Failed to delete TAP interface return $rc; } // Add interface $rc = addTap($tap_name, $user); if ($rc !== 0) { // Failed to add TAP interface return $rc; } if ($interface->getNetworkId() !== 0) { // Connect interface to network $rc = connectInterface($net_name, $tap_name); if ($rc !== 0) { // Failed to connect interface to network return $rc; } } } // Preparing image // Dropping privileges posix_setsid(); posix_setgid(32768); if ($n->getNType() == 'iol' && !posix_setuid($uid)) { error_log('ERROR: ' . $GLOBALS['messages'][80036]); return 80036; } if (!is_file($n->getRunningPath() . '/.prepared') && !is_file($n->getRunningPath() . '/.lock')) { // Node is not prepared/locked if (!is_dir($n->getRunningPath()) && !mkdir($n->getRunningPath(), 0775, True)) { // Cannot create running directory error_log('ERROR: ' . $GLOBALS['messages'][80037]); return 80037; } if ($n->getConfig() == 'Saved' && $n->getConfigData() != '') { // Node should use saved startup-config if (!dumpConfig($n->getConfigData(), $n->getRunningPath() . '/startup-config')) { // Cannot dump config to startup-config file error_log('WARNING: ' . $GLOBALS['messages'][80067]); } } switch ($n->getNType()) { default: // Invalid node_type error_log('ERROR: ' . $GLOBALS['messages'][80038]); return 80038; case 'iol': // Check license if (!is_file('/opt/unetlab/addons/iol/bin/iourc')) { // IOL license not found error_log('ERROR: ' . $GLOBALS['messages'][80039]); return 80039; } if (!file_exists($n->getRunningPath() . '/iourc') && !symlink('/opt/unetlab/addons/iol/bin/iourc', $n->getRunningPath() . '/iourc')) { // Cannot link IOL license error_log('ERROR: ' . $GLOBALS['messages'][80040]); return 80040; } break; case 'docker': if (!is_file('/usr/bin/docker')) { // docker.io is not installed error_log('ERROR: ' . $GLOBALS['messages'][80082]); return 80082; } $cmd = 'docker inspect --format="{{ .State.Running }}" ' . $n->getUuid(); exec($cmd, $o, $rc); if ($rc != 0) { // Must create docker.io container $cmd = 'docker create -ti --net=none --name=' . $n->getUuid() . ' -h ' . $n->getName() . ' ' . $n->getImage(); exec($cmd, $o, $rc); if ($rc != 0) { // Failed to create container error_log('ERROR: ' . $GLOBALS['messages'][80083]); return 80083; } } break; case 'dynamips': // Nothing to do break; case 'qemu': $image = '/opt/unetlab/addons/qemu/' . $n->getImage(); if (!touch($n->getRunningPath() . '/.lock')) { // Cannot lock directory error_log('ERROR: ' . $GLOBALS['messages'][80041]); return 80041; } // Copy files from template foreach (scandir($image) as $filename) { if (preg_match('/^[a-zA-Z0-9]+.qcow2$/', $filename)) { // TODO should check if file exists $cmd = '/opt/qemu/bin/qemu-img create -b "' . $image . '/' . $filename . '" -f qcow2 "' . $n->getRunningPath() . '/' . $filename . '"'; exec($cmd, $o, $rc); if ($rc !== 0) { // Cannot make linked clone error_log('ERROR: ' . $GLOBALS['messages'][80045]); error_log(implode("\n", $o)); return 80045; } } } if (!unlink($n->getRunningPath() . '/.lock')) { // Cannot unlock directory error_log('ERROR: ' . $GLOBALS['messages'][80042]); return 80042; } break; } // Mark the node as prepared if (!touch($n->getRunningPath() . '/.prepared')) { // Cannot write on directory error_log('ERROR: ' . $GLOBALS['messages'][80044]); return 80044; } } return 0; }
/** * Causes this pseudo-thread to begin parallel execution. * * This method first checks of all the Shared Memory Segment. If okay, it * forks the child process, attaches signal handler and returns immediatly. * The status is set to running, and a PID is assigned. The result is that * two pseudo-threads are running concurrently: the current thread (which * returns from the call to the start() method) and the other thread (which * executes its run() method). * * @throws ZendX_Console_Process_Exception When SHM segments can't be created * @throws ZendX_Console_Process_Exception When process forking fails * @return void */ public function start() { if (!$this->_ipcIsOkay) { require_once 'ZendX/Console/Process/Exception.php'; throw new ZendX_Console_Process_Exception('Unable to create SHM segments for process communications'); } // @see http://www.php.net/manual/en/function.pcntl-fork.php#41150 @ob_end_flush(); pcntl_signal(SIGCHLD, SIG_IGN); $pid = @pcntl_fork(); if ($pid === -1) { require_once 'ZendX/Console/Process/Exception.php'; throw new ZendX_Console_Process_Exception('Forking process failed'); } else { if ($pid === 0) { // This is the child $this->_isChild = true; // Sleep a second to avoid problems sleep(1); // Install the signal handler pcntl_signal(SIGUSR1, array($this, '_sigHandler')); // If requested, change process identity if ($this->_guid !== null) { posix_setgid($this->_guid); } if ($this->_puid !== null) { posix_setuid($this->_puid); } // Run the child try { $this->_run(); } catch (Exception $e) { // We have to catch any exceptions and clean up the process, // else we will have a memory leak. } // Destroy the child after _run() execution. Required to avoid // unuseful child processes after execution exit(0); } else { // Else this is the parent $this->_isChild = false; $this->_isRunning = true; $this->_pid = $pid; } } }
/** * Check and chdir to $_workDir * * @return void */ private function ___init_userGroup() { $this->_debug("-----> " . __CLASS__ . '::' . __FUNCTION__ . '()', 9); // Get current uid and gid $uid_cur = posix_getuid(); $gid_cur = posix_getgid(); // If not root, skip the rest of this procedure if ($uid_cur != 0) { $this->_log("Skipping the setUid/setGid part, because we are not root"); return; } // Get desired uid/gid $r = posix_getpwnam($this->_user); if ($r === false) { throw new A2o_AppSrv_Exception("Unable to get uid for user: {$this->_user}"); } $userData = $r; $r = posix_getgrnam($this->_group); if ($r === false) { throw new A2o_AppSrv_Exception("Unable to get gid for group: {$this->_group}"); } $groupData = $r; $uid_desired = $userData['uid']; $gid_desired = $groupData['gid']; // Change effective uid/gid if required if ($gid_cur != $gid_desired) { $r = posix_setgid($gid_desired); if ($r === false) { throw new A2o_AppSrv_Exception("Unable to setgid: {$gid_cur} -> {$gid_desired}"); } $this->_debug("Group (GID) changed to {$this->_group} ({$gid_desired})"); } if ($uid_cur != $uid_desired) { $r = posix_setuid($uid_desired); if ($r === false) { throw new A2o_AppSrv_Exception("Unable to setuid: {$uid_cur} -> {$uid_desired}"); } $this->_debug("User (UID) changed to {$this->_user} ({$uid_desired})"); } $this->_debug("Setuid/setgid complete"); }
/** * 尝试设置运行当前进程的用户 * @return void */ protected static function setProcessUser($user_name) { if (empty($user_name) || posix_getuid() !== 0) { return; } $user_info = posix_getpwnam($user_name); if ($user_info['uid'] != posix_getuid() || $user_info['gid'] != posix_getgid()) { if (!posix_setgid($user_info['gid']) || !posix_setuid($user_info['uid'])) { self::log('Notice : Can not run woker as ' . $user_name . " , You shuld be root\n", true); } } }
function changeUser() { $username = common_config('daemon', 'user'); if ($username) { $user_info = posix_getpwnam($username); if (!$user_info) { common_log(LOG_WARNING, 'Ignoring unknown user for daemon: ' . $username); } else { common_log(LOG_INFO, "Setting user to " . $username); posix_setuid($user_info['uid']); } } $groupname = common_config('daemon', 'group'); if ($groupname) { $group_info = posix_getgrnam($groupname); if (!$group_info) { common_log(LOG_WARNING, 'Ignoring unknown group for daemon: ' . $groupname); } else { common_log(LOG_INFO, "Setting group to " . $groupname); posix_setgid($group_info['gid']); } } }
/** * @throws Exception */ private function changeUser() { $user = $this->getConfig()->getUser(); if ($user) { $user = posix_getpwnam($user); if (posix_geteuid() !== (int) $user['uid']) { posix_setgid($user['gid']); posix_setuid($user['uid']); if (posix_geteuid() !== (int) $user['uid']) { $message = "Unable to change user to {$user['uid']}"; if (null !== $this->logger) { $this->logger->error($message); } throw new Exception($message); } } } }
/** * set owner(user,group) of process * * @return */ public function setOwner($name) { $set = false; if (empty($name)) { return true; } $user = posix_getpwnam($name); if ($user) { $uid = $user['uid']; $gid = $user['gid']; $set = posix_setuid($uid); posix_setgid($gid); } if (!$set) { $this->_log("cannot change owner ({$name})\n"); } return $set; }
/** * Changes the current user to the web user * * @return boolean */ private function changeProcessToWebUser() { $userInfo = posix_getpwnam($this->config->app->webUser); $uidWeb = $userInfo['uid']; $gidWeb = $userInfo['gid']; // If the current user is the web user then success $uid = posix_getuid(); $gid = posix_getgid(); if ($uid === $uidWeb && $gid === $gidWeb) { return true; } // If the user is not root then there is no chance to succeed. if ($uid !== 0) { throw new \Exception("Error: The process real group id could not be changed."); } // If the user is root then attempt to change to the web user and group if (posix_setgid($gidWeb) !== true) { throw new \Exception("Error: The process real group id could not be changed."); } if (posix_setuid($uidWeb) !== true) { throw new \Exception("Error: The process real user id could not be changed."); } $uid = posix_getuid(); $gid = posix_getgid(); if ($uid !== $uidWeb || $gid !== $gidWeb) { throw new \Exeption("Error: Somehow the user was not changed to the web user."); } return true; }
/** * Method to change the identity of the daemon process and resources. * * @return boolean True if identity successfully changed * * @since 11.1 * @see posix_setuid() */ protected function changeIdentity() { // Get the group and user ids to set for the daemon. $uid = (int) $this->config->get('application_uid', 0); $gid = (int) $this->config->get('application_gid', 0); // Get the application process id file path. $file = $this->config->get('application_pid_file'); // Change the user id for the process id file if necessary. if ($uid && fileowner($file) != $uid && !@chown($file, $uid)) { JLog::add('Unable to change user ownership of the process id file.', JLog::ERROR); return false; } // Change the group id for the process id file if necessary. if ($gid && filegroup($file) != $gid && !@chgrp($file, $gid)) { JLog::add('Unable to change group ownership of the process id file.', JLog::ERROR); return false; } // Set the correct home directory for the process. if ($uid && ($info = posix_getpwuid($uid)) && is_dir($info['dir'])) { system('export HOME="' . $info['dir'] . '"'); } // Change the user id for the process necessary. if ($uid && posix_getuid($file) != $uid && !@posix_setuid($uid)) { JLog::add('Unable to change user ownership of the proccess.', JLog::ERROR); return false; } // Change the group id for the process necessary. if ($gid && posix_getgid($file) != $gid && !@posix_setgid($gid)) { JLog::add('Unable to change group ownership of the proccess.', JLog::ERROR); return false; } // Get the user and group information based on uid and gid. $user = posix_getpwuid($uid); $group = posix_getgrgid($gid); JLog::add('Changed daemon identity to ' . $user['name'] . ':' . $group['name'], JLog::INFO); return true; }
/** * Runs the server. Loads the listener using XPClass::forName() * so that the class is loaded within the thread's process space * and will be recompiled whenever the thread is restarted. * * @throws lang.XPException in case initializing the server fails * @throws lang.SystemException in case setuid fails */ public function run() { try { with($class = XPClass::forName('peer.ftp.server.FtpProtocol'), $cl = ClassLoader::getDefault()); // Add listener $this->server->setProtocol($proto = $class->newInstance($storage = Proxy::newProxyInstance($cl, array(XPClass::forName('peer.ftp.server.storage.Storage')), $this->storageHandler), Proxy::newProxyInstance($cl, array(XPClass::forName('security.auth.Authenticator')), $this->authenticatorHandler))); // Copy interceptors to connection listener $proto->interceptors = $this->interceptors; // Enable debugging if ($this->cat) { $proto->setTrace($this->cat); $this->server instanceof Traceable && $this->server->setTrace($this->cat); } // Try to start the server $this->server->init(); } catch (Throwable $e) { $this->server->shutdown(); throw $e; } // Check if we should run child processes // with another uid/pid if (isset($this->processGroup)) { $group = posix_getgrnam($this->processGroup); $this->cat && $this->cat->debugf('Setting group to: %s (GID: %d)', $group['name'], $group['uid']); if (!posix_setgid($group['gid'])) { throw new SystemException('Could not set GID'); } } if (isset($this->processOwner)) { $user = posix_getpwnam($this->processOwner); $this->cat && $this->cat->debugf('Setting user to: %s (UID: %d)', $user['name'], $user['uid']); if (!posix_setuid($user['uid'])) { throw new SystemException('Could not set UID'); } } $this->server->service(); }
/** * Set unix user and group for current process. * @return void */ public function setUserAndGroup() { // Get uid. $user_info = posix_getpwnam($this->user); if (!$user_info) { return self::log("Waring: User {$this->user} not exsits", true); } $uid = $user_info['uid']; // Get gid. if ($this->group) { $group_info = posix_getgrnam($this->group); if (!$group_info) { return self::log("Waring: Group {$this->group} not exsits", true); } $gid = $group_info['gid']; } else { $gid = $user_info['gid']; } // Set uid and gid. if ($uid != posix_getuid() || $gid != posix_getgid()) { if (!posix_setgid($gid) || !posix_initgroups($user_info['name'], $gid) || !posix_setuid($uid)) { self::log("Waring: change gid or uid fail.", true); } } }
/** * Setup settings on start. * @return void */ protected function prepareSystemEnv() { proc_nice(Daemon::$config->workerpriority->value); register_shutdown_function(function () { $this->shutdown(true); }); $this->setTitle(Daemon::$runName . ': worker process' . (Daemon::$config->pidfile->value !== Daemon::$config->defaultpidfile->value ? ' (' . Daemon::$config->pidfile->value . ')' : '')); if (isset(Daemon::$config->group->value)) { $sg = posix_getgrnam(Daemon::$config->group->value); } if (isset(Daemon::$config->user->value)) { $su = posix_getpwnam(Daemon::$config->user->value); } $flushCache = false; if (Daemon::$config->chroot->value !== '/') { if (posix_getuid() != 0) { Daemon::log('You must have the root privileges to change root.'); exit(0); } elseif (!chroot(Daemon::$config->chroot->value)) { Daemon::log('Couldn\'t change root to \'' . Daemon::$config->chroot->value . '\'.'); exit(0); } $flushCache = true; } if (isset(Daemon::$config->group->value)) { if ($sg === FALSE) { Daemon::log('Couldn\'t change group to \'' . Daemon::$config->group->value . '\'. You must replace config-variable \'group\' with existing group.'); exit(0); } elseif ($sg['gid'] != posix_getgid() && !posix_setgid($sg['gid'])) { Daemon::log('Couldn\'t change group to \'' . Daemon::$config->group->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } $flushCache = true; } if (isset(Daemon::$config->user->value)) { if ($su === FALSE) { Daemon::log('Couldn\'t change user to \'' . Daemon::$config->user->value . '\', user not found. You must replace config-variable \'user\' with existing username.'); exit(0); } elseif ($su['uid'] != posix_getuid() && !posix_setuid($su['uid'])) { Daemon::log('Couldn\'t change user to \'' . Daemon::$config->user->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } $flushCache = true; } if ($flushCache) { clearstatcache(true); } if (Daemon::$config->cwd->value !== '.') { if (!@chdir(Daemon::$config->cwd->value)) { Daemon::log('Couldn\'t change directory to \'' . Daemon::$config->cwd->value . '.'); } clearstatcache(true); } }
/** * @param integer $userId * @return self * @throws \Exception */ public function setUserId(int $userId) : self { $userId = (int) $userId; if (!posix_setuid($userId)) { throw new \Exception(sprintf('Could not set user id to %d', $userId)); } $this->userId = posix_getuid(); return $this; }
/** * Change identity of process & resources if needed. * * @param integer $gid Group identifier (number) * @param integer $uid User identifier (number) * * @return boolean */ protected function _changeIdentity($gid = 0, $uid = 0) { // What files need to be chowned? $chownFiles = array(); if ($this->_isValidPidLocation($this->opt('appPidLocation'), true)) { $chownFiles[] = dirname($this->opt('appPidLocation')); } $chownFiles[] = $this->opt('appPidLocation'); if (!is_object($this->opt('usePEARLogInstance'))) { $chownFiles[] = $this->opt('logLocation'); } // Chown pid- & log file // We have to change owner in case of identity change. // This way we can modify the files even after we're not root anymore foreach ($chownFiles as $filePath) { // Change File GID $doGid = filegroup($filePath) != $gid ? $gid : false; if (false !== $doGid && !@chgrp($filePath, intval($gid))) { return $this->err('Unable to change group of file %s to %s', $filePath, $gid); } // Change File UID $doUid = fileowner($filePath) != $uid ? $uid : false; if (false !== $doUid && !@chown($filePath, intval($uid))) { return $this->err('Unable to change user of file %s to %s', $filePath, $uid); } // Export correct homedir if (($info = posix_getpwuid($uid)) && is_dir($info['dir'])) { system('export HOME="' . $info['dir'] . '"'); } } // Change Process GID $doGid = posix_getgid() !== $gid ? $gid : false; if (false !== $doGid && !@posix_setgid($gid)) { return $this->err('Unable to change group of process to %s', $gid); } // Change Process UID $doUid = posix_getuid() !== $uid ? $uid : false; if (false !== $doUid && !@posix_setuid($uid)) { return $this->err('Unable to change user of process to %s', $uid); } $group = posix_getgrgid($gid); $user = posix_getpwuid($uid); return $this->info('Changed identify to %s:%s', $group['name'], $user['name']); }
public function run() { proc_nice(Daemon::$settings['workerpriority']); Daemon::$worker = $this; $this->microsleep = Daemon::$settings['microsleep']; $this->autoReloadLast = time(); $this->reloadDelay = Daemon::$parsedSettings['mpmdelay'] + 2; $this->setStatus(4); Thread::setproctitle(Daemon::$runName . ': worker process' . (Daemon::$settings['pidfile'] !== Daemon::$settings['defaultpidfile'] ? ' (' . Daemon::$settings['pidfile'] . ')' : '')); register_shutdown_function(array($this, 'shutdown')); if (Daemon::$settings['autogc'] > 0) { gc_enable(); } else { gc_disable(); } if (isset(Daemon::$settings['group'])) { $sg = posix_getgrnam(Daemon::$settings['group']); } if (isset(Daemon::$settings['user'])) { $su = posix_getpwnam(Daemon::$settings['user']); } if (Daemon::$settings['chroot'] !== '/') { if (posix_getuid() != 0) { Daemon::log('You must have the root privileges to change root.'); exit(0); } elseif (!chroot(Daemon::$settings['chroot'])) { Daemon::log('Couldn\'t change root to \'' . Daemon::$settings['chroot'] . '\'.'); exit(0); } } if (isset(Daemon::$settings['group'])) { if ($sg === FALSE) { Daemon::log('Couldn\'t change group to \'' . Daemon::$settings['group'] . '\'. You must replace config-variable \'group\' with existing group.'); exit(0); } elseif ($sg['gid'] != posix_getgid() && !posix_setgid($sg['gid'])) { Daemon::log('Couldn\'t change group to \'' . Daemon::$settings['group'] . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } } if (isset(Daemon::$settings['user'])) { if ($su === FALSE) { Daemon::log('Couldn\'t change user to \'' . Daemon::$settings['user'] . '\', user not found. You must replace config-variable \'user\' with existing username.'); exit(0); } elseif ($su['uid'] != posix_getuid() && !posix_setuid($su['uid'])) { Daemon::log('Couldn\'t change user to \'' . Daemon::$settings['user'] . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } } if (Daemon::$settings['cwd'] !== '.') { if (!@chdir(Daemon::$settings['cwd'])) { Daemon::log('WORKER ' . $this->pid . '] Couldn\'t change directory to \'' . Daemon::$settings['cwd'] . '.'); } } $this->setStatus(6); $this->eventBase = event_base_new(); Daemon::$appResolver->preload(); foreach (Daemon::$appInstances as $app) { foreach ($app as $appInstance) { if (!$appInstance->ready) { $this->ready = TRUE; $appInstance->onReady(); } } } $this->setStatus(1); $ev = event_new(); event_set($ev, STDIN, EV_TIMEOUT, function () { }, array()); event_base_set($ev, $this->eventBase); $this->timeoutEvent = $ev; while (TRUE) { pcntl_signal_dispatch(); if (($s = $this->checkState()) !== TRUE) { $this->closeSockets(); if (sizeof($this->queue) === 0) { return $s; } } event_add($this->timeoutEvent, $this->microsleep); event_base_loop($this->eventBase, EVLOOP_ONCE); do { for ($i = 0, $s = sizeof($this->eventsToAdd); $i < $s; ++$i) { event_add($this->eventsToAdd[$i]); unset($this->eventsToAdd[$i]); } $this->readPool(); $processed = $this->runQueue(); } while ($processed || $this->readPoolState || $this->eventsToAdd); } }
/** * 设置运行的用户 * * @param string $name * * @return bool */ private static function setUser($name) { $result = false; if (empty($name)) { return true; } $user = posix_getpwnam($name); if ($user) { $uid = $user['uid']; $gid = $user['gid']; $result = posix_setuid($uid); posix_setgid($gid); } return $result; }
private function startChildProcess() { $pid = pcntl_fork(); $callback = $this->getNotRunningCallback(); if ($pid == -1) { } elseif ($pid) { $this->childProcesses[$callback][] = $pid; } else { posix_setuid($this->user); posix_setgid($this->group); $this->childProcesses = []; if (function_exists('cli_set_process_title')) { \cli_set_process_title('php-' . $this->processName . ': ' . $callback); } $this->callbacks[$callback](); usleep(2 * self::DELAY); exit; } }
/** * 设置运行用户 * @param string $worker_user * @return void */ protected static function setProcUser($worker_user) { $user_info = posix_getpwnam($worker_user); if ($user_info['uid'] != posix_getuid() || $user_info['gid'] != posix_getgid()) { // 尝试设置gid uid if (!posix_setgid($user_info['gid']) || !posix_setuid($user_info['uid'])) { self::notice('Notice : Can not run woker as ' . $worker_user . " , You shuld be root\n", true); } } }
/** * Change identity of process & resources if needed. * * @param integer $gid Group identifier (number) * @param integer $uid User identifier (number) * * @return boolean */ protected static function _changeIdentity($gid = 0, $uid = 0) { // What files need to be chowned? $chownFiles = array(); if (self::_isValidPidLocation(self::getOption("appPidLocation"), true)) { $chownFiles[] = dirname(self::getOption("appPidLocation")); } $chownFiles[] = self::getOption("appPidLocation"); $chownFiles[] = self::getOption("logLocation"); // Chown pid- & log file // We have to change owner in case of identity change. // This way we can modify the files even after we're not root anymore foreach ($chownFiles as $filePath) { // Change File GID $doGid = fileowner($filePath) != $gid ? $gid : false; if (false !== $doGid && !@chgrp($filePath, $gid)) { self::log(self::LOG_ERR, "" . self::getOption("appName") . " " . "daemon was unable " . "to change group of file: " . $filePath . " " . "to: " . $gid, __FILE__, __CLASS__, __FUNCTION__, __LINE__); return false; } // Change File UID $doUid = fileowner($filePath) != $uid ? $uid : false; if (false !== $doUid && !@chown($filePath, $uid)) { self::log(self::LOG_ERR, "" . self::getOption("appName") . " " . "daemon was unable " . "to change user of file: " . $filePath . " " . "to: " . $uid, __FILE__, __CLASS__, __FUNCTION__, __LINE__); return false; } } // Change Process GID $doGid = posix_getgid() !== $gid ? $gid : false; if (false !== $doGid && !@posix_setgid($gid)) { self::log(self::LOG_ERR, "" . self::getOption("appName") . " " . "daemon was unable " . "to change group of process " . "to: " . $gid, __FILE__, __CLASS__, __FUNCTION__, __LINE__); return false; } // Change Process UID $doUid = posix_getuid() !== $uid ? $uid : false; if (false !== $doUid && !@posix_setuid($uid)) { self::log(self::LOG_ERR, "" . self::getOption("appName") . " " . "daemon was unable " . "to change user of process " . "to: " . $uid, __FILE__, __CLASS__, __FUNCTION__, __LINE__); return false; } return true; }