Example #1
0
 public function getGroups()
 {
     $gids = posix_getgroups();
     $ret = [];
     foreach ($gids as $gid) {
         $ret[] = new Group($gid);
     }
     return $ret;
 }
Example #2
0
 public function get($name)
 {
     $data = posix_getpwnam($name);
     if ($data !== false) {
         $data['groups'] = array_map(function ($group) {
             $group = posix_getgrgid($group);
             return $group['name'];
         }, posix_getgroups());
     }
     return $data;
 }
 /**
  * @inheritdoc
  *
  * @return array
  */
 function check()
 {
     if ($this->path[0] == '/') {
         $filename = $this->path;
     } else {
         $filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $this->path);
     }
     if (file_exists($filename)) {
         $isWriteable = is_writeable($filename);
     } else {
         $isWriteable = is_writeable(dirname($filename));
     }
     if (!$isWriteable) {
         if (function_exists('posix_getgroups')) {
             $userID = posix_geteuid();
             $user = posix_getpwuid($userID);
             $currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename));
             $currentOwner = posix_getpwuid($currentOwnerID);
             $message = "User '{$user['name']}' needs to be able to write to this file:\n{$filename}\n\nThe file is currently owned by '{$currentOwner['name']}'.  ";
             if ($user['name'] == $currentOwner['name']) {
                 $message .= "We recommend that you make the file writeable.";
             } else {
                 $groups = posix_getgroups();
                 $groupList = array();
                 foreach ($groups as $group) {
                     $groupInfo = posix_getgrgid($group);
                     if (in_array($currentOwner['name'], $groupInfo['members'])) {
                         $groupList[] = $groupInfo['name'];
                     }
                 }
                 if ($groupList) {
                     $message .= "\tWe recommend that you make the file group-writeable and change the group to one of these groups:\n - " . implode("\n - ", $groupList) . "\n\nFor example:\nchmod g+w {$filename}\nchgrp " . $groupList[0] . " {$filename}";
                 } else {
                     $message .= "  There is no user-group that contains both the web-server user and the owner of this file.  Change the ownership of the file, create a new group, or temporarily make the file writeable by everyone during the install process.";
                 }
             }
         } else {
             $message = "The webserver user needs to be able to write to this file:\n{$filename}";
         }
         return array(EnvironmentCheck::ERROR, $message);
     }
     return array(EnvironmentCheck::OK, '');
 }
Example #4
0
 function have_direct_access()
 {
     if (!is_null($this->have_direct_access)) {
         return $this->have_direct_access;
     }
     $this->have_direct_access = false;
     if (!function_exists('getmyuid') || !function_exists('fileowner') || !function_exists('posix_getgroups') || !function_exists('filegroup')) {
         return $this->have_direct_access;
     }
     $temp_file_name = $this->config->root_path . '/temp-write-test-' . time();
     $temp_handle = @fopen($temp_file_name, 'w');
     if ($temp_handle) {
         if (getmyuid() == @fileowner($temp_file_name) || in_array(@filegroup($temp_file_name), posix_getgroups())) {
             $this->have_direct_access = true;
         }
         @fclose($temp_handle);
         @unlink($temp_file_name);
     }
     return $this->have_direct_access;
 }
Example #5
0
File: test.php Project: rair/yacs
             $gmembers = array();
             foreach ($ginfo['members'] as $index => $label) {
                 $gmembers[] = $label;
             }
             if (count($gmembers)) {
                 $glabel .= ' (' . implode(', ', $gmembers) . ')';
             }
         }
     }
     // display gathered information
     echo '<p>' . i18n::s('user/group of this script:') . ' ' . $ulabel . '/' . $glabel . "</p>\n";
 } else {
     echo '<p>' . i18n::s('Impossible to retrieve user/group of this script.') . "</p>\n";
 }
 // user/group of this process
 if (is_callable('posix_geteuid') && ($uid = posix_geteuid()) !== FALSE && is_callable('posix_getgroups') && ($gids = posix_getgroups()) !== FALSE) {
     // describe user
     $ulabel = $uid;
     if (is_callable('posix_getpwuid') && ($uinfo = posix_getpwuid($uid)) !== FALSE) {
         if (isset($uinfo['name'])) {
             $ulabel = $uinfo['name'] . '[' . $uid . ']';
         }
     }
     // describe groups
     $glabel = '';
     foreach ($gids as $gid) {
         // group name
         if (is_callable('posix_getgrgid') && ($ginfo = posix_getgrgid($gid)) !== FALSE && isset($ginfo['name'])) {
             $glabel .= $ginfo['name'] . '[' . $gid . ']';
         } else {
             $glabel .= $gid;
Example #6
0
 function isInFossyGroup()
 {
     $gid_array = posix_getgroups();
     foreach ($gid_array as $gid) {
         $gid_info = posix_getgrgid($gid);
         if ($gid_info['name'] === 'fossy') {
             return true;
         }
     }
     $uid = posix_getuid();
     $uid_info = posix_getpwuid($uid);
     return $uid_info['name'] !== 'root';
 }
/**
 * Run a MediaWiki script based on the parameters (like --wiki) given to CLI.
 *
 * The first argument must be the relative (to MediaWiki) script file path.
 * If only a filename is given, it will be assumed to reside in /maintenance.
 * The second argument must be the --wiki parameter. This is to avoid
 * any "options with args" ambiguity (see Maintenance.php).
 *
 * When the actual script is run, $argv[0] (this file's name) will be not be kept.
 * Also, $argv[1] (the script path) will be changed to the script file name.
 * All other arguments will be preserved.
 *
 * @return string Absolute MediaWiki script path
 */
function getMWScriptWithArgs()
{
    global $argv;
    if (count($argv) < 2) {
        fwrite(STDERR, "This script can only be run from the command line.\n");
        exit(1);
    }
    # Security check -- don't allow scripts to run as privileged users
    $gids = posix_getgroups();
    foreach ($gids as $gid) {
        $info = posix_getgrgid($gid);
        if ($info && in_array($info['name'], array('sudo', 'wikidev', 'root'))) {
            fwrite(STDERR, "Cannot run a MediaWiki script as a user in the " . "group {$info['name']}\n");
            fwrite(STDERR, <<<EOT
Maintenance scripts should generally be run using sudo -u www-data which
is available to all wikidev users.  Running a maintenance script as a
privileged user risks compromise of the user account.

You should run this script as the www-data user:

 sudo -u www-data <command>

EOT
);
            exit(1);
        }
    }
    $relFile = $argv[1];
    // the script file to run
    # If no MW directory is given then assume this is a /maintenance script
    if (strpos($relFile, '/') === false) {
        $relFile = "maintenance/{$relFile}";
        // convenience
    }
    # Remove effects of this wrapper from $argv...
    array_shift($argv);
    // remove this file's name from args
    # Code stolen from wfBasename() in GlobalFunctions.php :)
    if (preg_match("#([^/\\\\]*?)[/\\\\]*\$#", $argv[0], $matches)) {
        $argv[0] = $matches[1];
        // make first arg the script file name
    }
    # For addwiki.php, the wiki DB doesn't yet exist, and for some
    # other maintenance scripts we don't care what wiki DB is used...
    $wikiless = array('maintenance/purgeList.php', 'extensions/WikimediaMaintenance/addWiki.php', 'extensions/WikimediaMaintenance/dumpInterwiki.php', 'extensions/WikimediaMaintenance/getJobQueueLengths.php', 'extensions/WikimediaMaintenance/rebuildInterwiki.php', 'extensions/WikimediaMaintenance/filebackend/setZoneAccess.php', 'maintenance/mctest.php', 'maintenance/mcc.php');
    # Check if a --wiki param was given...
    # Maintenance.php will treat $argv[1] as the wiki if it doesn't start '-'
    if (!isset($argv[1]) || !preg_match('/^([^-]|--wiki(=|$))/', $argv[1])) {
        if (in_array($relFile, $wikiless)) {
            # Assume aawiki as Maintenance.php does.
            $argv = array_merge(array($argv[0], "--wiki=aawiki"), array_slice($argv, 1));
        }
    }
    # MWScript.php should be in common/
    require_once __DIR__ . '/MWVersion.php';
    $file = getMediaWikiCli($relFile);
    if (!file_exists($file)) {
        fwrite(STDERR, "The MediaWiki script file \"{$file}\" does not exist.\n");
        exit(1);
    }
    return $file;
}
Example #8
0
 /**
  * Get groups
  *
  * @return array
  */
 public function getgroups()
 {
     return posix_getgroups();
 }
Example #9
0
function is_writable_or_chmodable($fn)
{
    $stat = stat($fn);
    if (!$stat) {
        return false;
    }
    $myuid = posix_getuid();
    $mygids = posix_getgroups();
    if ($myuid == 0 || $myuid == $stat['uid'] || in_array($stat['gid'], $mygids) && $stat['mode'] & 020 || $stat['mode'] & 02) {
        return true;
    }
    return false;
}
 /**
  * Check if test on filesystem group ownership can be done in this environment
  * If so, return second group of webserver user
  *
  * @param string calling method name
  * @return mixed FALSE if test cannot be run, string name of the second group of webserver user
  */
 private function checkGroups($methodName)
 {
     if (TYPO3_OS == 'WIN') {
         $this->markTestSkipped($methodName . '() test not available on Windows.');
         return FALSE;
     }
     if (!function_exists('posix_getgroups')) {
         $this->markTestSkipped('Function posix_getgroups() not available, ' . $methodName . '() tests skipped');
     }
     $groups = posix_getgroups();
     if (count($groups) <= 1) {
         $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
         return FALSE;
     }
     $groupInfo = posix_getgrgid($groups[1]);
     return $groupInfo['name'];
 }
Example #11
0
 /**
  * @author faw, phpBB Group and Kleeja team
  */
 function _chmod($filepath, $perm = 0644)
 {
     static $continue;
     if (empty($continue)) {
         if (!function_exists('fileowner') || !function_exists('filegroup')) {
             #if we cant get those data, no need to complete the check
             $continue['process'] = false;
         } else {
             #get the owner and group of the common.php file, why common.php? it's the master
             $common_php_owner = @fileowner(PATH . 'includes/common.php');
             $common_php_group = @filegroup(PATH . 'includes/common.php');
             // And the owner and the groups PHP is running under.
             $php_uid = function_exists('posix_getuid') ? @posix_getuid() : false;
             $php_gids = function_exists('posix_getgroups') ? @posix_getgroups() : false;
             // If we are unable to get owner/group, then do not try to set them by guessing
             if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) {
                 $continue['process'] = false;
             } else {
                 $continue = array('process' => true, 'common_owner' => $common_php_owner, 'common_group' => $common_php_group, 'php_uid' => $php_uid, 'php_gids' => $php_gids);
             }
         }
     }
     # From static, or not .. lets continue
     if ($continue['process']) {
         $file_uid = @fileowner($this->_fixpath($filepath));
         $file_gid = @filegroup($this->_fixpath($filepath));
         // Change owner
         if (@chown($this->_fixpath($filepath), $continue['common_owner'])) {
             clearstatcache();
             $file_uid = @fileowner($this->_fixpath($filepath));
         }
         // Change group
         if (@chgrp($this->_fixpath($filepath), $continue['common_group'])) {
             clearstatcache();
             $file_gid = @filegroup($this->_fixpath($filepath));
         }
         // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something
         if ($file_uid != $continue['common_owner'] || $file_gid != $continue['common_group']) {
             $continue['process'] = false;
         }
     }
     # Still able to process?
     if ($continue['process']) {
         if ($file_uid == $continue['php_uid']) {
             $php = 'owner';
         } else {
             if (in_array($file_gid, $continue['php_gids'])) {
                 $php = 'group';
             } else {
                 // Since we are setting the everyone bit anyway, no need to do expensive operations
                 $continue['process'] = false;
             }
         }
     }
     // We are not able to determine or change something
     if (!$continue['process']) {
         $php = 'other';
     }
     // Owner always has read/write permission
     $owner = 4 | 2;
     if (is_dir($this->_fixpath($filepath))) {
         $owner |= 1;
         // Only add execute bit to the permission if the dir needs to be readable
         if ($perm & 4) {
             $perm |= 1;
         }
     }
     switch ($php) {
         case 'owner':
             $result = @chmod($this->_fixpath($filepath), ($owner << 6) + (0 << 3) + (0 << 0));
             clearstatcache();
             if (is_readable($this->_fixpath($filepath)) && is_writable($this->_fixpath($filepath))) {
                 break;
             }
         case 'group':
             $result = @chmod($this->_fixpath($filepath), ($owner << 6) + ($perm << 3) + (0 << 0));
             clearstatcache();
             if ((!($perm & 4) || is_readable($this->_fixpath($filepath))) && (!($perm & 2) || is_writable($this->_fixpath($filepath)))) {
                 break;
             }
         case 'other':
             $result = @chmod($this->_fixpath($filepath), ($owner << 6) + ($perm << 3) + ($perm << 0));
             clearstatcache();
             if ((!($perm & 4) || is_readable($this->_fixpath($filepath))) && (!($perm & 2) || is_writable($this->_fixpath($filepath)))) {
                 break;
             }
         default:
             return false;
             break;
     }
     # if nothing works well use the handler...
     if (!$result) {
         $result = $this->f->_chmod($this->_fixpath($filepath), $perm);
     }
     return $result;
 }
 * The name of the testrepo will be in the fossology.conf file in the test
 * configuration directory.
 *
 * This program can be called to drop the DB and clean up.
 *
 * @version "$Id$"
 *
 * Created on Sep 14, 2011 by Mark Donohoe
 */
require_once __DIR__ . '/../lib/libTestDB.php';
$Options = getopt('c:d:esh');
$usage = $argv[0] . ": [-h] -c path [-d name] [-s]\n" . "-c path:  The path to the fossology system configuration directory\n" . "-d name:  Drop the named data base.\n" . "-e:       create ONLY an empty db, sysconf dir and repository\n" . "-h:       This message (Usage)\n" . "-s:       Start the scheduler with the new sysconfig directory\n" . "Examples:\n" . "  Create a test DB: 'createTestDb.php' \n" . "  Drop the database fosstest1537938: 'createTestDb.php -d fosstest1537938'\n" . "  Create test DB, start scheduler: 'createTestDb.php -s'\n" . "  Create empty DB, sysconf and repo: 'createTestDb.php -e'\n";
$pathPrefix = '/srv/fossology';
$dbPrefix = 'fosstest';
// check if the user is in the fossy group
$gid_array = posix_getgroups();
$gflag = 0;
// 0: in the fossy group, 1: not in the fossy group
foreach ($gid_array as $gid) {
    $gid_info = posix_getgrgid($gid);
    if ($gid_info['name'] === 'fossy') {
        $gflag = 1;
        // the user is in fossy group
        break;
    }
}
$uid = posix_getuid();
$uid_info = posix_getpwuid($uid);
if ($uid_info['name'] === 'root') {
    $gflag = 1;
}
Example #13
0
 /**
  * Check if test on filesystem group ownership can be done in this environment
  * If so, return second group of webserver user
  *
  * @param string calling method name
  * @return mixed FALSE if test cannot be run, string name of the second group of webserver user
  */
 private function checkGroups($methodName)
 {
     if (TYPO3_OS == 'WIN') {
         $this->markTestSkipped($methodName . '() test not available on Windows.');
         return false;
     }
     if (!function_exists('posix_getgroups')) {
         $this->markTestSkipped('Function posix_getgroups() not available, ' . $methodName . '() tests skipped');
     }
     $groups = posix_getgroups();
     if (count($groups) <= 1) {
         $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
         return false;
     }
     $uname = strtolower(php_uname());
     $groupOffset = 1;
     if (strpos($uname, 'darwin') !== false) {
         // We are on OSX and it seems that the first group needs to be fetched since Mavericks
         $groupOffset = 0;
     }
     $groupInfo = posix_getgrgid($groups[$groupOffset]);
     return $groupInfo['name'];
 }
Example #14
0
File: Node.php Project: jasny/Q
 /**
  * Get the number of bits to shift to get the privileges of the user of the current process.
  * 
  * {@example
  *  $mode = ($file['mode'] >> $file->modeBitShift()) & 7;          // Privileges for the current user as bitset (rwx)
  *  $privs = substr($file['privs'], 7 - $file->modeBitShift(), 3); // Privileges for the current user as string
  * }}
  *
  * @param  int $flags  FS::% options
  * @return int
  * @throws Exception if posix extension is not available.
  */
 public function modeBitShift($user, $flags = 0)
 {
     if (!extension_loaded('posix')) {
         throw new Exception("Unable to determine the which part of the mode of '{$this->_path}' applies to the current user: Posix extension not avaible.");
     }
     return $this->getAttribute('uid', $flags) == posix_getuid() ? 6 : (in_array($this->getAttribute('gid', $flags), posix_getgroups()) ? 3 : 0);
 }
Example #15
0
echo "gid={$gid}\n";
$egid = posix_getegid();
echo "egid={$egid}\n";
posix_setuid(1004);
$uid = posix_getuid();
echo "uid={$uid}\n";
posix_seteuid(1004);
$euid = posix_geteuid();
echo "euid={$euid}\n";
posix_setgid(1004);
$gid = posix_getgid();
echo "gid={$gid}\n";
posix_setegid(1004);
$egid = posix_getegid();
echo "egid={$egid}\n";
$groups = posix_getgroups();
echo "groups=\n";
print_r($groups);
$login = posix_getlogin();
echo "login={$login}\n";
$pgrp = posix_getpgrp();
echo "pgrp={$pgrp}\n";
$setsid = posix_setsid();
if ($setsid > 0) {
    echo "posix_setsid succeeded\n";
} else {
    echo "posix_setsid failed\n";
}
$getpgid = posix_getpgid($pid);
if ($getpgid > 0) {
    echo "posix_getpgid succeeded\n";
Example #16
0
 /**
  * Return the group set of the current process
  *
  * @return array
  */
 public function getgroups() : array
 {
     return posix_getgroups();
 }
 /**
  * Вход в консоль Pinger.
  * 
  * @param array $argv Копия массива <code>$argv</code> с аргументами вызова скрипта.
  * @return void
  * @access protected
  * @static
  */
 public static function main($argv)
 {
     if ('cli' !== PHP_SAPI) {
         die("CLI only!");
     }
     if (!count(array_intersect(posix_getgroups(), [0, posix_getgrnam('pinger')['gid']]))) {
         echo "Error: Pinger Console must be launched as root or from group named 'pinger'!\n";
         exit(1);
     }
     $argv += array_fill(0, 4, null);
     switch ($argv[1]) {
         case 'list':
             static::cmdList();
             break;
         case 'add':
             static::cmdAdd($argv[2], $argv[3]);
             break;
         case 'rem':
             static::cmdRem($argv[2]);
             break;
         case 'enable':
             static::cmdEnable($argv[2]);
             break;
         case 'disable':
             static::cmdDisable($argv[2]);
             break;
         case 'help':
         default:
             static::cmdHelp($argv[1]);
             break;
     }
 }
Example #18
0
	/**
	 * Returns an array of data returned from the UNIX 'id' command
	 *
	 * includes uid, username, gid, groupname, and groups (if "exec"
	 * is enabled). Groups is an array of all the groups the user
	 * belongs to.  Keys are the group ids, values are the group names.
	 *
	 * returns FALSE if no suitable function is available to retrieve
	 * the data
	 *
	 * @return array|boolean
	 */
	function getUnixId() {

		if ($this->osIsWindows()) {
			return false;
		}

		$success = false;


		if (function_exists("exec") && !PhpSecInfo_Test::getBooleanIniValue('safe_mode')) {
			$id_raw = exec('id');
			// uid=1000(coj) gid=1000(coj) groups=1000(coj),1001(admin)
			preg_match( "|uid=(\d+)\((\S+)\)\s+gid=(\d+)\((\S+)\)\s+groups=(.+)|i",
						$id_raw,
						$matches);

			if (!$matches) {
				/**
				 * for some reason the output from 'id' wasn't as we expected.
				 * return false so the test doesn't run.
				 */
				$success = false;
			} else {
				$id_data = array(	'uid'=>$matches[1],
									'username'=>$matches[2],
									'gid'=>$matches[3],
									'group'=>$matches[4] );

				$groups = array();
				if ($matches[5]) {
					$gs = $matches[5];
					$gs = explode(',', $gs);
					foreach ($gs as $groupstr) {
						if (preg_match("/(\d+)\(([^\)]+)\)/", $groupstr, $subs)) {
							$groups[$subs[1]] = $subs[2];
						} else {
							$groups[$groupstr] = '';
						}
					}
					ksort($groups);
				}
				$id_data['groups'] = $groups;
				$success = true;
			}

		}

		if (!$success && function_exists("posix_getpwuid") && function_exists("posix_geteuid")
			&& function_exists('posix_getgrgid') && function_exists('posix_getgroups') ) {
			$data = posix_getpwuid( posix_getuid() );
			$id_data['uid'] = $data['uid'];
			$id_data['username'] = $data['name'];
			$id_data['gid'] = $data['gid'];
			//$group_data = posix_getgrgid( posix_getegid() );
			//$id_data['group'] = $group_data['name'];
			$id_data['groups'] = array();
			$groups = posix_getgroups();
			foreach ( $groups as $gid ) {
				//$group_data = posix_getgrgid(posix_getgid());
				$id_data['groups'][$gid] = '<unknown>';
			}
			$success = true;
		}

		if ($success) {
			return $id_data;
		} else {
			return false;
		}
	}
Example #19
0
 public function requireWriteable($filename, $testDetails, $absolute = false)
 {
     $this->testing($testDetails);
     if ($absolute) {
         $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
     } else {
         $filename = $this->getBaseDir() . str_replace('/', DIRECTORY_SEPARATOR, $filename);
     }
     if (file_exists($filename)) {
         $isWriteable = is_writeable($filename);
     } else {
         $isWriteable = is_writeable(dirname($filename));
     }
     if (!$isWriteable) {
         if (function_exists('posix_getgroups')) {
             $userID = posix_geteuid();
             $user = posix_getpwuid($userID);
             $currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename));
             $currentOwner = posix_getpwuid($currentOwnerID);
             $testDetails[2] .= "User '{$user['name']}' needs to be able to write to this file:\n{$filename}\n\nThe " . "file is currently owned by '{$currentOwner['name']}'.  ";
             if ($user['name'] == $currentOwner['name']) {
                 $testDetails[2] .= "We recommend that you make the file writeable.";
             } else {
                 $groups = posix_getgroups();
                 $groupList = array();
                 foreach ($groups as $group) {
                     $groupInfo = posix_getgrgid($group);
                     if (in_array($currentOwner['name'], $groupInfo['members'])) {
                         $groupList[] = $groupInfo['name'];
                     }
                 }
                 if ($groupList) {
                     $testDetails[2] .= "\tWe recommend that you make the file group-writeable " . "and change the group to one of these groups:\n - " . implode("\n - ", $groupList) . "\n\nFor example:\nchmod g+w {$filename}\nchgrp " . $groupList[0] . " {$filename}";
                 } else {
                     $testDetails[2] .= "  There is no user-group that contains both the web-server user and the " . "owner of this file.  Change the ownership of the file, create a new group, or " . "temporarily make the file writeable by everyone during the install process.";
                 }
             }
         } else {
             $testDetails[2] .= "The webserver user needs to be able to write to this file:\n{$filename}";
         }
         $this->error($testDetails);
     }
 }
Example #20
0
 /**
  * Check if test on filesystem group ownership can be done in this environment
  * If so, return second group of webserver user
  *
  * @param string $methodName calling method name
  * @return mixed FALSE if test cannot be run, int group id of the second group of webserver user
  */
 private function checkGroups($methodName)
 {
     if (TYPO3_OS === 'WIN') {
         $this->markTestSkipped($methodName . '() test not available on Windows.');
         return false;
     }
     if (!function_exists('posix_getegid')) {
         $this->markTestSkipped('Function posix_getegid() not available, ' . $methodName . '() tests skipped');
         return false;
     }
     if (posix_getegid() === -1) {
         $this->markTestSkipped('Function posix_getegid() returns -1, ' . $methodName . '() tests skipped');
         return false;
     }
     if (!function_exists('posix_getgroups')) {
         $this->markTestSkipped('Function posix_getgroups() not available, ' . $methodName . '() tests skipped');
         return false;
     }
     $groups = posix_getgroups();
     if (count($groups) <= 1) {
         $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
         return false;
     }
     $secondaryGroups = array_diff($groups, [posix_getegid()]);
     return array_shift($secondaryGroups);
 }
/**
* Global function for chmodding directories and files for internal use
*
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
* The function determines owner and group from common.php file and sets the same to the provided file.
* The function uses bit fields to build the permissions.
* The function sets the appropiate execute bit on directories.
*
* Supported constants representing bit fields are:
*
* CHMOD_ALL - all permissions (7)
* CHMOD_READ - read permission (4)
* CHMOD_WRITE - write permission (2)
* CHMOD_EXECUTE - execute permission (1)
*
* NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
*
* @param string	$filename	The file/directory to be chmodded
* @param int	$perms		Permissions to set
*
* @return bool	true on success, otherwise false
* @author faw, phpBB Group
*/
function phpbb_chmod($filename, $perms = CHMOD_READ)
{
    static $_chmod_info;
    // Return if the file no longer exists.
    if (!file_exists($filename)) {
        return false;
    }
    // Determine some common vars
    if (empty($_chmod_info)) {
        if (!function_exists('fileowner') || !function_exists('filegroup')) {
            // No need to further determine owner/group - it is unknown
            $_chmod_info['process'] = false;
        } else {
            global $phpbb_root_path, $phpEx;
            // Determine owner/group of common.php file and the filename we want to change here
            $common_php_owner = @fileowner($phpbb_root_path . 'common.' . $phpEx);
            $common_php_group = @filegroup($phpbb_root_path . 'common.' . $phpEx);
            // And the owner and the groups PHP is running under.
            $php_uid = function_exists('posix_getuid') ? @posix_getuid() : false;
            $php_gids = function_exists('posix_getgroups') ? @posix_getgroups() : false;
            // If we are unable to get owner/group, then do not try to set them by guessing
            if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) {
                $_chmod_info['process'] = false;
            } else {
                $_chmod_info = array('process' => true, 'common_owner' => $common_php_owner, 'common_group' => $common_php_group, 'php_uid' => $php_uid, 'php_gids' => $php_gids);
            }
        }
    }
    if ($_chmod_info['process']) {
        $file_uid = @fileowner($filename);
        $file_gid = @filegroup($filename);
        // Change owner
        if (@chown($filename, $_chmod_info['common_owner'])) {
            clearstatcache();
            $file_uid = @fileowner($filename);
        }
        // Change group
        if (@chgrp($filename, $_chmod_info['common_group'])) {
            clearstatcache();
            $file_gid = @filegroup($filename);
        }
        // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something
        if ($file_uid != $_chmod_info['common_owner'] || $file_gid != $_chmod_info['common_group']) {
            $_chmod_info['process'] = false;
        }
    }
    // Still able to process?
    if ($_chmod_info['process']) {
        if ($file_uid == $_chmod_info['php_uid']) {
            $php = 'owner';
        } else {
            if (in_array($file_gid, $_chmod_info['php_gids'])) {
                $php = 'group';
            } else {
                // Since we are setting the everyone bit anyway, no need to do expensive operations
                $_chmod_info['process'] = false;
            }
        }
    }
    // We are not able to determine or change something
    if (!$_chmod_info['process']) {
        $php = 'other';
    }
    // Owner always has read/write permission
    $owner = CHMOD_READ | CHMOD_WRITE;
    if (is_dir($filename)) {
        $owner |= CHMOD_EXECUTE;
        // Only add execute bit to the permission if the dir needs to be readable
        if ($perms & CHMOD_READ) {
            $perms |= CHMOD_EXECUTE;
        }
    }
    switch ($php) {
        case 'owner':
            $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
            clearstatcache();
            if (is_readable($filename) && is_writable($filename)) {
                break;
            }
        case 'group':
            $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
            clearstatcache();
            if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) {
                break;
            }
        case 'other':
            $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
            clearstatcache();
            if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) {
                break;
            }
        default:
            return false;
            break;
    }
    return $result;
}
Example #22
0
 /**
  * Returns an array of data returned from the UNIX 'id' command
  *
  * includes uid, username, gid, groupname, and groups (if "exec"
  * is enabled). Groups is an array of all the groups the user
  * belongs to.  Keys are the group ids, values are the group names.
  *
  * returns FALSE if no suitable function is available to retrieve
  * the data
  *
  * @return array|boolean
  */
 function getUnixId()
 {
     if ($this->osIsWindows()) {
         return false;
     } elseif (function_exists("exec") && !PhpSecInfo_Test::getBooleanIniValue('safe_mode')) {
         $id_raw = exec('id');
         // uid=1000(coj) gid=1000(coj) groups=1000(coj),1001(admin)
         preg_match("|uid=(\\d+)\\((\\S+)\\)\\s+gid=(\\d+)\\((\\S+)\\)\\s+groups=(.+)|i", $id_raw, $matches);
         $id_data = array('uid' => $matches[1], 'username' => $matches[2], 'gid' => $matches[3], 'group' => $matches[4]);
         if ($matches[5]) {
             $gs = $matches[5];
             $gs = explode(',', $gs);
             foreach ($gs as $groupstr) {
                 preg_match("/(\\d+)\\(([^\\)]+)\\)/", $groupstr, $subs);
                 $groups[$subs[1]] = $subs[2];
             }
             ksort($groups);
             $id_data['groups'] = $groups;
         }
         return $id_data;
     } elseif (function_exists("posix_getpwuid") && function_exists("posix_geteuid") && function_exists('posix_getgrgid') && function_exists('posix_getgroups')) {
         $data = posix_getpwuid(posix_getuid());
         $id_data['uid'] = $data['uid'];
         $id_data['username'] = $data['name'];
         $id_data['gid'] = $data['gid'];
         //$group_data = posix_getgrgid( posix_getegid() );
         //$id_data['group'] = $group_data['name'];
         $groups = posix_getgroups();
         foreach ($groups as $gid) {
             //$group_data = posix_getgrgid(posix_getgid());
             $id_data['groups'][$gid] = '<unknown>';
         }
     }
     return false;
 }
Example #23
0
/**
* Global function for chmodding directories and files for internal use
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
* The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission.
* The function uses bit fields to build the permissions.
* The function sets the appropiate execute bit on directories.
*
* Supported constants representing bit fields are:
*
* CHMOD_ALL - all permissions (7)
* CHMOD_READ - read permission (4)
* CHMOD_WRITE - write permission (2)
* CHMOD_EXECUTE - execute permission (1)
*
* NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
*
* @param $filename The file/directory to be chmodded
* @param $perms Permissions to set
* @return true on success, otherwise false
*
* @author faw, phpBB Group
*/
function phpbb_chmod($filename, $perms = CHMOD_READ)
{
    // Return if the file no longer exists.
    if (!file_exists($filename)) {
        return false;
    }
    if (!function_exists('fileowner') || !function_exists('filegroup')) {
        $file_uid = $file_gid = false;
        $common_php_owner = $common_php_group = false;
    } else {
        global $phpbb_root_path, $phpEx;
        // Determine owner/group of common.php file and the filename we want to change here
        $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx);
        $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx);
        $file_uid = fileowner($filename);
        $file_gid = filegroup($filename);
        // Try to set the owner to the same common.php has
        if ($common_php_owner !== $file_uid && $common_php_owner !== false && $file_uid !== false) {
            // Will most likely not work
            if (@chown($filename, $common_php_owner)) {
            }
            clearstatcache();
            $file_uid = fileowner($filename);
        }
        // Try to set the group to the same common.php has
        if ($common_php_group !== $file_gid && $common_php_group !== false && $file_gid !== false) {
            if (@chgrp($filename, $common_php_group)) {
            }
            clearstatcache();
            $file_gid = filegroup($filename);
        }
    }
    // And the owner and the groups PHP is running under.
    $php_uid = function_exists('posix_getuid') ? @posix_getuid() : false;
    $php_gids = function_exists('posix_getgroups') ? @posix_getgroups() : false;
    // Who is PHP?
    if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false) {
        $php = NULL;
    } else {
        if ($file_uid == $php_uid) {
            $php = 'owner';
        } else {
            if (in_array($file_gid, $php_gids)) {
                $php = 'group';
            } else {
                $php = 'other';
            }
        }
    }
    // Owner always has read/write permission
    $owner = CHMOD_READ | CHMOD_WRITE;
    if (is_dir($filename)) {
        $owner |= CHMOD_EXECUTE;
        // Only add execute bit to the permission if the dir needs to be readable
        if ($perms & CHMOD_READ) {
            $perms |= CHMOD_EXECUTE;
        }
    }
    switch ($php) {
        case null:
        case 'owner':
            /* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups.
            
            			$result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
            
            			clearstatcache();
            
            			if (!is_null($php) || (is_readable($filename) && is_writable($filename)))
            			{
            				break;
            			}
            		*/
        /* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups.
        
        			$result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
        
        			clearstatcache();
        
        			if (!is_null($php) || (is_readable($filename) && is_writable($filename)))
        			{
        				break;
        			}
        		*/
        case 'group':
            $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
            clearstatcache();
            if (!is_null($php) || (!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) {
                break;
            }
        case 'other':
            $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
            clearstatcache();
            if (!is_null($php) || (!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) {
                break;
            }
        default:
            return false;
            break;
    }
    return $result;
}
Example #24
0
 /**
  * {@inheritdoc}
  */
 public function phpbb_chmod($files, $perms = null, $recursive = false, $force_chmod_link = false)
 {
     if (is_null($perms)) {
         // Default to read permission for compatibility reasons
         $perms = self::CHMOD_READ;
     }
     if (empty($this->chmod_info)) {
         if (!function_exists('fileowner') || !function_exists('filegroup')) {
             $this->chmod_info['process'] = false;
         } else {
             $common_php_owner = @fileowner(__FILE__);
             $common_php_group = @filegroup(__FILE__);
             // And the owner and the groups PHP is running under.
             $php_uid = function_exists('posic_getuid') ? @posix_getuid() : false;
             $php_gids = function_exists('posix_getgroups') ? @posix_getgroups() : false;
             // If we are unable to get owner/group, then do not try to set them by guessing
             if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) {
                 $this->chmod_info['process'] = false;
             } else {
                 $this->chmod_info = array('process' => true, 'common_owner' => $common_php_owner, 'common_group' => $common_php_group, 'php_uid' => $php_uid, 'php_gids' => $php_gids);
             }
         }
     }
     if ($this->chmod_info['process']) {
         try {
             foreach ($this->to_iterator($files) as $file) {
                 $file_uid = @fileowner($file);
                 $file_gid = @filegroup($file);
                 // Change owner
                 if ($file_uid !== $this->chmod_info['common_owner']) {
                     $this->chown($file, $this->chmod_info['common_owner'], $recursive);
                 }
                 // Change group
                 if ($file_gid !== $this->chmod_info['common_group']) {
                     $this->chgrp($file, $this->chmod_info['common_group'], $recursive);
                 }
                 clearstatcache();
                 $file_uid = @fileowner($file);
                 $file_gid = @filegroup($file);
             }
         } catch (filesystem_exception $e) {
             $this->chmod_info['process'] = false;
         }
     }
     // Still able to process?
     if ($this->chmod_info['process']) {
         if ($file_uid === $this->chmod_info['php_uid']) {
             $php = 'owner';
         } else {
             if (in_array($file_gid, $this->chmod_info['php_gids'])) {
                 $php = 'group';
             } else {
                 // Since we are setting the everyone bit anyway, no need to do expensive operations
                 $this->chmod_info['process'] = false;
             }
         }
     }
     // We are not able to determine or change something
     if (!$this->chmod_info['process']) {
         $php = 'other';
     }
     switch ($php) {
         case 'owner':
             try {
                 $this->chmod($files, $perms, $recursive, $force_chmod_link);
                 clearstatcache();
                 if ($this->is_readable($files) && $this->is_writable($files)) {
                     break;
                 }
             } catch (filesystem_exception $e) {
                 // Do nothing
             }
         case 'group':
             try {
                 $this->chmod($files, $perms, $recursive, $force_chmod_link);
                 clearstatcache();
                 if ((!($perms & self::CHMOD_READ) || $this->is_readable($files, $recursive)) && (!($perms & self::CHMOD_WRITE) || $this->is_writable($files, $recursive))) {
                     break;
                 }
             } catch (filesystem_exception $e) {
                 // Do nothing
             }
         case 'other':
         default:
             $this->chmod($files, $perms, $recursive, $force_chmod_link);
             break;
     }
 }