protected function execute(InputInterface $input, OutputInterface $output, $quiet = false) { if (posix_geteuid() != 0) { $output->writeln("<error>" . _("You need to be root to run this command") . "</error>"); exit(1); } $this->quiet = $quiet; if (!$this->quiet) { $output->writeln(_("Setting Permissions") . "..."); } $freepbx_conf = \freepbx_conf::create(); $conf = $freepbx_conf->get_conf_settings(); foreach ($conf as $key => $val) { ${$key} = $val['value']; } /* * These are files Framework is responsible for This list can be * reduced by moving responsibility to other modules as a hook * where appropriate. * * Types: * file: Set permissions/ownership on a single item * dir: Set permissions/ownership on a single directory * rdir: Set permissions/ownership on a single directory then recursively on * files within less the execute bit. If the dir is 755, child files will be 644, * child directories will be set the same as the parent. * execdir: Same as rdir but the execute bit is not stripped. */ $sessdir = session_save_path(); $sessdir = !empty($session) ? $session : '/var/lib/php/session'; $args = array(); if ($input) { $args = $input->getArgument('args'); $this->moduleName = !empty($this->moduleName) ? $this->moduleName : strtolower($args[0]); } // Always update hooks before running a Chown \FreePBX::Hooks()->updateBMOHooks(); if (!empty($this->moduleName) && $this->moduleName != 'framework') { $mod = $this->moduleName; $this->modfiles[$mod][] = array('type' => 'rdir', 'path' => $AMPWEBROOT . '/admin/modules/' . $mod, 'perms' => 0755); $hooks = $this->fwcChownFiles(); $current = isset($hooks[ucfirst($mod)]) ? $hooks[ucfirst($mod)] : false; if (is_array($current)) { $this->modfiles[$mod] = array_merge_recursive($this->modfiles[$mod], $current); } } else { $webuser = \FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER'); $web = posix_getpwnam($webuser); if (!$web) { throw new \Exception(sprintf(_("I tried to find out about %s, but the system doesn't think that user exists"), $webuser)); } $home = trim($web['dir']); if (is_dir($home)) { $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $home, 'perms' => 0755); // SSH folder needs non-world-readable permissions (otherwise ssh complains, and refuses to work) $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => "{$home}/.ssh", 'perms' => 0700); } $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $sessdir, 'perms' => 0744); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/amportal.conf', 'perms' => 0640); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/freepbx.conf', 'perms' => 0640); $this->modfiles['framework'][] = array('type' => 'dir', 'path' => $ASTRUNDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => \FreePBX::GPG()->getGpgLocation(), 'perms' => 0755); //we may wish to declare these manually or through some automated fashion $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTETCDIR, 'perms' => 0750); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $ASTVARLIBDIR . '/.ssh/id_rsa', 'perms' => 0600); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTLOGDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTSPOOLDIR, 'perms' => 0755); //I have added these below individually, $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBXDBUGFILE, 'perms' => 0644); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBX_LOG_FILE, 'perms' => 0644); //We may wish to declare files individually rather than touching everything $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/' . $MOHDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/sounds', 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/obdc.ini', 'perms' => 0644); //we were doing a recursive on this which I think is not needed. //Changed to just be the directory //^ Needs to be the whole shebang, doesnt work otherwise $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $AMPWEBROOT, 'perms' => 0755); //Anything in bin and agi-bin should be exec'd //Should be after everything except but before hooks //So that we dont get overwritten by ampwebroot $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $AMPBIN, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTAGIDIR, 'perms' => 0755); //Merge static files and hook files, then act on them as a single unit $fwcCF = $this->fwcChownFiles(); if (!empty($this->modfiles) && !empty($fwcCF)) { $this->modfiles = array_merge_recursive($this->modfiles, $fwcCF); } } $ampowner = $AMPASTERISKWEBUSER; /* Address concerns carried over from amportal in FREEPBX-8268. If the apache user is different * than the Asterisk user we provide permissions that allow both. */ $ampgroup = $AMPASTERISKWEBUSER != $AMPASTERISKUSER ? $AMPASTERISKGROUP : $AMPASTERISKWEBGROUP; foreach ($this->modfiles as $moduleName => $modfilelist) { foreach ($modfilelist as $file) { if (!isset($file['path']) || !isset($file['perms']) || !file_exists($file['path'])) { continue; } //Handle custom ownership (optional) $owner = isset($file['owner']) ? $file['owner'] : $ampowner; $group = isset($file['group']) ? $file['group'] : $ampgroup; //Set warning for bad permissions and move on $this->padPermissions($file['path'], $file['perms']); $file['type'] = isset($file['type']) ? $file['type'] : 'file'; switch ($file['type']) { case 'file': case 'dir': $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } break; case 'rdir': $fileperms = $this->stripExecute($file['perms']); $files = $this->recursiveDirList($file['path']); $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } foreach ($files as $f) { if (is_dir($f)) { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } else { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $fileperms)); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } } break; case 'execdir': $files = $this->recursiveDirList($file['path']); $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } foreach ($files as $f) { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } break; } } } $actioncount = count($this->actions); if (!$this->quiet) { $progress = new ProgressBar($output, $actioncount); $progress->setRedrawFrequency(100); $progress->start(); } foreach ($this->actions as $action) { $action = json_decode($action, true); //Ignore call files, Asterisk may process/delete them before we get to them. if (pathinfo($action[0], PATHINFO_EXTENSION) == 'call') { continue; } $this->singleChown($action[0], $action[1], $action[2]); $this->singlePerms($action[0], $action[3]); if (!$this->quiet) { $progress->advance(); } } if (!$this->quiet) { $progress->finish(); $output->writeln(""); $output->writeln("Finished setting permissions"); foreach ($this->errors as $error) { $output->writeln("<error>" . $error . "</error>"); } foreach ($this->infos as $error) { $output->writeln("<info>" . $error . "</info>"); } } }
protected function execute(InputInterface $input, OutputInterface $output, $quiet = false) { $this->output = $output; if (posix_geteuid() != 0) { $output->writeln("<error>" . _("You need to be root to run this command") . "</error>"); exit(1); } $this->quiet = $quiet; $etcdir = \FreePBX::Config()->get('ASTETCDIR'); if (!$this->quiet) { if (!file_exists($etcdir . '/freepbx_chown.conf')) { $output->writeln("<info>" . sprintf(_("Taking too long? Customize the chown command, See %s"), "http://wiki.freepbx.org/display/FOP/FreePBX+Chown+Conf") . "</info>"); } $output->writeln(_("Setting Permissions") . "..."); } $freepbx_conf = \freepbx_conf::create(); $conf = $freepbx_conf->get_conf_settings(); foreach ($conf as $key => $val) { ${$key} = $val['value']; } /* * These are files Framework is responsible for This list can be * reduced by moving responsibility to other modules as a hook * where appropriate. * * Types: * file: Set permissions/ownership on a single item * dir: Set permissions/ownership on a single directory * rdir: Set permissions/ownership on a single directory then recursively on * files within less the execute bit. If the dir is 755, child files will be 644, * child directories will be set the same as the parent. * execdir: Same as rdir but the execute bit is not stripped. */ $sessdir = session_save_path(); $sessdir = !empty($sessdir) ? $sessdir : '/var/lib/php/session'; $args = array(); if ($input) { $args = $input->getArgument('args'); $mname = isset($args[0]) ? $args[0] : ''; $this->moduleName = !empty($this->moduleName) ? $this->moduleName : strtolower($mname); } // Always update hooks before running a Chown \FreePBX::Hooks()->updateBMOHooks(); if (!empty($this->moduleName) && $this->moduleName != 'framework') { $mod = $this->moduleName; $this->modfiles[$mod][] = array('type' => 'rdir', 'path' => $AMPWEBROOT . '/admin/modules/' . $mod, 'perms' => 0755); $hooks = $this->fwcChownFiles(); $current = isset($hooks[ucfirst($mod)]) ? $hooks[ucfirst($mod)] : false; if (is_array($current)) { $this->modfiles[$mod] = array_merge_recursive($this->modfiles[$mod], $current); } } else { $webuser = \FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER'); $web = posix_getpwnam($webuser); if (!$web) { throw new \Exception(sprintf(_("I tried to find out about %s, but the system doesn't think that user exists"), $webuser)); } $home = trim($web['dir']); if (is_dir($home)) { $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $home, 'perms' => 0755); // SSH folder needs non-world-readable permissions (otherwise ssh complains, and refuses to work) $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => "{$home}/.ssh", 'perms' => 0700); } $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $sessdir, 'perms' => 0744, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/amportal.conf', 'perms' => 0640, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/freepbx.conf', 'perms' => 0640, 'always' => true); $this->modfiles['framework'][] = array('type' => 'dir', 'path' => $ASTRUNDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => \FreePBX::GPG()->getGpgLocation(), 'perms' => 0755, 'always' => true); //we may wish to declare these manually or through some automated fashion $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTETCDIR, 'perms' => 0750, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $ASTVARLIBDIR . '/.ssh/id_rsa', 'perms' => 0600); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTLOGDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTSPOOLDIR, 'perms' => 0755); //I have added these below individually, $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBXDBUGFILE, 'perms' => 0644); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBX_LOG_FILE, 'perms' => 0644); //We may wish to declare files individually rather than touching everything $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/' . $MOHDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/sounds', 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/obdc.ini', 'perms' => 0644); //we were doing a recursive on this which I think is not needed. //Changed to just be the directory //^ Needs to be the whole shebang, doesnt work otherwise $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $AMPWEBROOT, 'perms' => 0755); //Anything in bin and agi-bin should be exec'd //Should be after everything except but before hooks //So that we dont get overwritten by ampwebroot $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $AMPBIN, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTAGIDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTVARLIBDIR . "/bin", 'perms' => 0755, 'always' => true); //Merge static files and hook files, then act on them as a single unit $fwcCF = $this->fwcChownFiles(); if (!empty($this->modfiles) && !empty($fwcCF)) { foreach ($fwcCF as $key => $value) { $this->modfiles[$key] = $value; } //$this->modfiles = array_merge_recursive($this->modfiles,$fwcCF); } } //Let's move the custom array to the end so it happens last //FREEPBX-12515 //Store in a temporary variable. If Null we make it an empty array $holdarray = $this->modfiles['byconfig']; //Unset it from the array unset($this->modfiles['byconfig']); //Add it back to the array $this->modfiles['byconfig'] = $holdarray; $ampowner = $AMPASTERISKWEBUSER; /* Address concerns carried over from amportal in FREEPBX-8268. If the apache user is different * than the Asterisk user we provide permissions that allow both. */ $ampgroup = $AMPASTERISKWEBUSER != $AMPASTERISKUSER ? $AMPASTERISKGROUP : $AMPASTERISKWEBGROUP; $fcount = 0; if (!$this->quiet) { $output->write("\t" . _("Collecting Files...")); } $exclusive = $input->hasOption('file') ? $input->getOption('file') : null; $process = array(); foreach ($this->modfiles as $moduleName => $modfilelist) { if (!is_array($modfilelist)) { continue; } foreach ($modfilelist as $file) { switch ($file['type']) { case 'file': case 'dir': if (empty($exclusive) || $exclusive == $file['path']) { $file['files'] = array($file['path']); $fcount++; } else { continue 2; } break; case 'execdir': case 'rdir': $files = $this->recursiveDirList($file['path']); $children = false; if (empty($exclusive) || $exclusive == $file['path']) { $file['files'] = array($file['path']); $fcount++; $children = true; } foreach ($files as $f) { if (empty($exclusive) || $children || $exclusive == $f) { $file['files'][] = $f; $fcount++; } else { continue; } } if (empty($file['files'])) { continue 2; } break; } $process[$file['type']][] = $file; } } $verbose = $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE; if (!$this->quiet) { $output->writeln(_("Done")); if (!$verbose) { $progress = new ProgressBar($output, $fcount); $progress->setRedrawFrequency(100); $progress->start(); } } foreach ($process as $type => $modfilelist) { foreach ($modfilelist as $file) { if (!isset($file['path']) || !isset($file['perms']) || !file_exists($file['path'])) { if (!$this->quiet && !$verbose) { $progress->advance(); } continue; } //Handle custom ownership (optional) $owner = isset($file['owner']) ? $file['owner'] : $ampowner; $group = isset($file['group']) ? $file['group'] : $ampgroup; $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); foreach ($file['files'] as $path) { if ($this->checkBlacklist($path)) { $this->infos[] = sprintf(_('%s skipped by configuration'), $path); continue; } switch ($file['type']) { case 'file': case 'dir': $this->setPermissions(array($path, $owner, $group, $file['perms'])); break; case 'rdir': if (is_dir($path)) { $this->setPermissions(array($path, $owner, $group, $file['perms'])); } else { $fileperms = $this->stripExecute($file['perms']); $this->setPermissions(array($path, $owner, $group, $fileperms)); } break; case 'execdir': $this->setPermissions(array($path, $owner, $group, $file['perms'])); break; } if (!$this->quiet && !$verbose) { $progress->advance(); } } } } if (!$this->quiet && !$verbose) { $progress->finish(); } if (!$this->quiet) { $output->writeln(""); $output->writeln("Finished setting permissions"); $errors = array_unique($this->errors); foreach ($errors as $error) { $output->writeln("<error>" . $error . "</error>"); } $infos = array_unique($this->infos); foreach ($infos as $error) { $output->writeln("<info>" . $error . "</info>"); } } }