示例#1
0
}
// bootstrap.php should always be called from freepbx.conf so
// database conifguration already included, connect to database:
//
require_once $dirname . '/libraries/db_connect.php';
//PEAR must be installed
// BMO: Initialize BMO as early as possible.
$bmo = dirname(__FILE__) . "/libraries/BMO/FreePBX.class.php";
if (file_exists($bmo)) {
    include_once $bmo;
    $bmo = new FreePBX($amp_conf);
} else {
    throw new Exception("Unable to load BMO");
}
// get settings
$freepbx_conf = $bmo->Freepbx_conf();
// passing by reference, this means that the $amp_conf available to everyone is the same one as present
// within the class, which is probably a direction we want to go to use the class.
//
$bootstrap_settings['amportal_conf_initialized'] = false;
$amp_conf =& $freepbx_conf->parse_amportal_conf("/etc/amportal.conf", $amp_conf);
// set the language so local module languages take
set_language();
$asterisk_conf =& $freepbx_conf->get_asterisk_conf();
$bootstrap_settings['amportal_conf_initialized'] = true;
//connect to cdrdb if requestes
if ($bootstrap_settings['cdrdb']) {
    $dsn = array('phptype' => $amp_conf['CDRDBTYPE'] ? $amp_conf['CDRDBTYPE'] : $amp_conf['AMPDBENGINE'], 'hostspec' => $amp_conf['CDRDBHOST'] ? $amp_conf['CDRDBHOST'] : $amp_conf['AMPDBHOST'], 'username' => $amp_conf['CDRDBUSER'] ? $amp_conf['CDRDBUSER'] : $amp_conf['AMPDBUSER'], 'password' => $amp_conf['CDRDBPASS'] ? $amp_conf['CDRDBPASS'] : $amp_conf['AMPDBPASS'], 'port' => $amp_conf['CDRDBPORT'] ? $amp_conf['CDRDBPORT'] : '3306', 'database' => $amp_conf['CDRDBNAME'] ? $amp_conf['CDRDBNAME'] : 'asteriskcdrdb');
    $cdrdb = DB::connect($dsn);
}
$bootstrap_settings['astman_connected'] = false;
示例#2
0
 /**
  * Check Permissions on said directory and fix if need be
  * @param {string} $dir = false The Directory to check and fix
  */
 private function checkPermissions($dir = false)
 {
     if (!$dir) {
         // No directory specified. Let's use the default.
         $dir = $this->getKeysLocation();
     }
     // If it ends in a slash, remove it, for sanity
     $dir = rtrim($dir, "/");
     if (!is_dir($dir)) {
         // That's worrying. Can I make it?
         $ret = @mkdir($dir);
         if (!$ret) {
             throw new \Exception(sprintf(_("Directory %s doesn't exist, and I can't make it."), $dir));
         }
     }
     // Now, who should be running OpenSSL normally?
     $freepbxuser = \FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER');
     $pwent = posix_getpwnam($freepbxuser);
     $uid = $pwent['uid'];
     $gid = $pwent['gid'];
     // What are the permissions of the keys directory?
     $stat = stat($dir);
     if ($uid != $stat['uid']) {
         // Permissions are wrong on the keys directory. Hopefully, I'm root, so I can fix them.
         if (posix_geteuid() !== 0) {
             throw new \Exception(sprintf(_("Permissions error on directory %s (is %s:%s, should be %s:%s)- please run 'fwconsole chown' as root to repair"), $dir, $stat['uid'], $stat['gid'], $uid, $gid));
         }
         // We're root. Yay.
         chown($dir, $uid);
         chgrp($dir, $gid);
     }
     // Check the permissions of the files inside the key location
     $allfiles = glob($dir . "/*");
     // Add the entropy file
     $allfiles[] = "{$dir}/.rnd";
     foreach ($allfiles as $file) {
         if (!file_exists($file)) {
             // .rnd file may not exist
             continue;
         }
         $stat = stat($file);
         if ($uid != $stat['uid']) {
             // Permissions are wrong on the keys directory. Hopefully, I'm root, so I can fix them.
             if (posix_geteuid() !== 0) {
                 throw new \Exception(sprintf(_("Permissions error on file %s - please re-run as root to automatically repair"), $file));
             }
             // We're root. Yay.
             chown($file, $uid);
             chgrp($file, $gid);
         }
     }
 }
示例#3
0
 private function createFreePBXAdmin($settings)
 {
     // This will never, ever, overwrite an existing admin.
     $db = FreePBX::Database();
     if (!$this->isFrameworkOOBENeeded()) {
         throw new \Exception("Tried to add an admin user, but some users ({$count}) already exist.");
     }
     $sth = $db->prepare("INSERT INTO `ampusers` (`username`, `password_sha1`, `sections`) VALUES ( ?, ?, '*')");
     $username = htmlentities(strip_tags($settings['username']));
     $sth->execute(array($username, sha1($settings['password'])));
     // TODO: REMOVE IN FREEPBX 14 - ARI is deprecated as of FreePBX 12
     // set ari password
     $freepbx_conf = FreePBX::Freepbx_conf();
     if ($freepbx_conf->conf_setting_exists('ARI_ADMIN_USERNAME') && $freepbx_conf->conf_setting_exists('ARI_ADMIN_PASSWORD')) {
         $freepbx_conf->set_conf_values(array('ARI_ADMIN_USERNAME' => $username, 'ARI_ADMIN_PASSWORD' => $settings['password']), true);
     }
     //set email address
     $cm =& cronmanager::create($db);
     $cm->save_email($settings['email']);
 }
示例#4
0
 private function checkPermissions($dir = false)
 {
     if (!$dir) {
         // No directory specified. Let's use the default.
         $dir = $this->getGpgLocation();
     }
     // If it ends in a slash, remove it, for sanity
     $dir = rtrim($dir, "/");
     if (!is_dir($dir)) {
         // That's worrying. Can I make it?
         $ret = @mkdir($dir);
         if (!$ret) {
             throw new Exception(sprintf(_("Directory %s doesn't exist, and I can't make it. (checkPermissions)"), $dir));
         }
     }
     // Now, who should be running gpg normally?
     $freepbxuser = FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER');
     $pwent = posix_getpwnam($freepbxuser);
     $uid = $pwent['uid'];
     $gid = $pwent['gid'];
     // What are the permissions of the GPG home directory?
     $stat = stat($dir);
     if ($uid != $stat['uid'] || $gid != $stat['gid']) {
         // Permissions are wrong on the GPG directory. Hopefully, I'm root, so I can fix them.
         if (!posix_geteuid() === 0) {
             throw new Exception(sprintf(_("Permissions error on %s - please re-run as root to automatically repair"), $home));
         }
         // We're root. Yay.
         chown($dir, $uid);
         chgrp($dir, $gid);
     }
     // Check the permissions of the files inside the .gpg directory
     $allfiles = glob($dir . "/*");
     foreach ($allfiles as $file) {
         $stat = stat($file);
         if ($uid != $stat['uid'] || $gid != $stat['gid']) {
             // Permissions are wrong on the file inside the .gnupg directory.
             if (!posix_geteuid() === 0) {
                 throw new Exception(sprintf(_("Permissions error on %s - please re-run as root to automatically repair"), $home));
             }
             // We're root. Yay.
             chown($file, $uid);
             chgrp($file, $gid);
         }
     }
 }
示例#5
0
 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>");
         }
     }
 }
示例#6
0
 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>");
         }
     }
 }