Viewing file: SystemDceSecurityProvider.php (6.45 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * This file is part of the ramsey/uuid library * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT */
declare(strict_types=1);
namespace Ramsey\Uuid\Provider\Dce;
use Ramsey\Uuid\Exception\DceSecurityException; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Type\Integer as IntegerObject;
use function escapeshellarg; use function preg_split; use function str_getcsv; use function strrpos; use function strtolower; use function strtoupper; use function substr; use function trim;
use const PREG_SPLIT_NO_EMPTY;
/** * SystemDceSecurityProvider retrieves the user or group identifiers from the system */ class SystemDceSecurityProvider implements DceSecurityProviderInterface { /** * @throws DceSecurityException if unable to get a user identifier * * @inheritDoc */ public function getUid(): IntegerObject { /** @var int|float|string|IntegerObject|null $uid */ static $uid = null;
if ($uid instanceof IntegerObject) { return $uid; }
if ($uid === null) { $uid = $this->getSystemUid(); }
if ($uid === '') { throw new DceSecurityException( 'Unable to get a user identifier using the system DCE ' . 'Security provider; please provide a custom identifier or ' . 'use a different provider' ); }
$uid = new IntegerObject($uid);
return $uid; }
/** * @throws DceSecurityException if unable to get a group identifier * * @inheritDoc */ public function getGid(): IntegerObject { /** @var int|float|string|IntegerObject|null $gid */ static $gid = null;
if ($gid instanceof IntegerObject) { return $gid; }
if ($gid === null) { $gid = $this->getSystemGid(); }
if ($gid === '') { throw new DceSecurityException( 'Unable to get a group identifier using the system DCE ' . 'Security provider; please provide a custom identifier or ' . 'use a different provider' ); }
$gid = new IntegerObject($gid);
return $gid; }
/** * Returns the UID from the system */ private function getSystemUid(): string { if (!$this->hasShellExec()) { return ''; }
return match ($this->getOs()) { 'WIN' => $this->getWindowsUid(), default => trim((string) shell_exec('id -u')), }; }
/** * Returns the GID from the system */ private function getSystemGid(): string { if (!$this->hasShellExec()) { return ''; }
return match ($this->getOs()) { 'WIN' => $this->getWindowsGid(), default => trim((string) shell_exec('id -g')), }; }
/** * Returns true if shell_exec() is available for use */ private function hasShellExec(): bool { $disabledFunctions = strtolower((string) ini_get('disable_functions'));
return !str_contains($disabledFunctions, 'shell_exec'); }
/** * Returns the PHP_OS string */ private function getOs(): string { /** * @psalm-suppress UnnecessaryVarAnnotation * @var string $phpOs */ $phpOs = constant('PHP_OS');
return strtoupper(substr($phpOs, 0, 3)); }
/** * Returns the user identifier for a user on a Windows system * * Windows does not have the same concept as an effective POSIX UID for the * running script. Instead, each user is uniquely identified by an SID * (security identifier). The SID includes three 32-bit unsigned integers * that make up a unique domain identifier, followed by an RID (relative * identifier) that we will use as the UID. The primary caveat is that this * UID may not be unique to the system, since it is, instead, unique to the * domain. * * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number? * @link https://bit.ly/30vE7NM Well-known SID Structures * @link https://bit.ly/2FWcYKJ Well-known security identifiers in Windows operating systems * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user */ private function getWindowsUid(): string { $response = shell_exec('whoami /user /fo csv /nh');
if ($response === null) { return ''; }
$sid = str_getcsv(trim((string) $response))[1] ?? '';
if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; }
return trim(substr($sid, $lastHyphen + 1)); }
/** * Returns a group identifier for a user on a Windows system * * Since Windows does not have the same concept as an effective POSIX GID * for the running script, we will get the local group memberships for the * user running the script. Then, we will get the SID (security identifier) * for the first group that appears in that list. Finally, we will return * the RID (relative identifier) for the group and use that as the GID. * * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line */ private function getWindowsGid(): string { $response = shell_exec('net user %username% | findstr /b /i "Local Group Memberships"');
if ($response === null) { return ''; }
/** @var string[] $userGroups */ $userGroups = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);
$firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B");
if ($firstGroup === '') { return ''; }
$response = shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup));
if ($response === null) { return ''; }
/** @var string[] $userGroup */ $userGroup = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);
$sid = $userGroup[1] ?? '';
if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; }
return trim(substr($sid, $lastHyphen + 1)); } }
|