Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the ramsey/uuid library
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
10
 * @license http://opensource.org/licenses/MIT MIT
11
 */
12
 
13
declare(strict_types=1);
14
 
15
namespace Ramsey\Uuid\Provider\Dce;
16
 
17
use Ramsey\Uuid\Exception\DceSecurityException;
18
use Ramsey\Uuid\Provider\DceSecurityProviderInterface;
19
use Ramsey\Uuid\Type\Integer as IntegerObject;
20
 
21
use function escapeshellarg;
22
use function preg_split;
23
use function str_getcsv;
24
use function strrpos;
25
use function strtolower;
26
use function strtoupper;
27
use function substr;
28
use function trim;
29
 
30
use const PREG_SPLIT_NO_EMPTY;
31
 
32
/**
33
 * SystemDceSecurityProvider retrieves the user or group identifiers from the system
34
 */
35
class SystemDceSecurityProvider implements DceSecurityProviderInterface
36
{
37
    /**
38
     * @throws DceSecurityException if unable to get a user identifier
39
     *
40
     * @inheritDoc
41
     */
42
    public function getUid(): IntegerObject
43
    {
44
        /** @var int|float|string|IntegerObject|null $uid */
45
        static $uid = null;
46
 
47
        if ($uid instanceof IntegerObject) {
48
            return $uid;
49
        }
50
 
51
        if ($uid === null) {
52
            $uid = $this->getSystemUid();
53
        }
54
 
55
        if ($uid === '') {
56
            throw new DceSecurityException(
57
                'Unable to get a user identifier using the system DCE '
58
                . 'Security provider; please provide a custom identifier or '
59
                . 'use a different provider'
60
            );
61
        }
62
 
63
        $uid = new IntegerObject($uid);
64
 
65
        return $uid;
66
    }
67
 
68
    /**
69
     * @throws DceSecurityException if unable to get a group identifier
70
     *
71
     * @inheritDoc
72
     */
73
    public function getGid(): IntegerObject
74
    {
75
        /** @var int|float|string|IntegerObject|null $gid */
76
        static $gid = null;
77
 
78
        if ($gid instanceof IntegerObject) {
79
            return $gid;
80
        }
81
 
82
        if ($gid === null) {
83
            $gid = $this->getSystemGid();
84
        }
85
 
86
        if ($gid === '') {
87
            throw new DceSecurityException(
88
                'Unable to get a group identifier using the system DCE '
89
                . 'Security provider; please provide a custom identifier or '
90
                . 'use a different provider'
91
            );
92
        }
93
 
94
        $gid = new IntegerObject($gid);
95
 
96
        return $gid;
97
    }
98
 
99
    /**
100
     * Returns the UID from the system
101
     */
102
    private function getSystemUid(): string
103
    {
104
        if (!$this->hasShellExec()) {
105
            return '';
106
        }
107
 
108
        return match ($this->getOs()) {
109
            'WIN' => $this->getWindowsUid(),
110
            default => trim((string) shell_exec('id -u')),
111
        };
112
    }
113
 
114
    /**
115
     * Returns the GID from the system
116
     */
117
    private function getSystemGid(): string
118
    {
119
        if (!$this->hasShellExec()) {
120
            return '';
121
        }
122
 
123
        return match ($this->getOs()) {
124
            'WIN' => $this->getWindowsGid(),
125
            default => trim((string) shell_exec('id -g')),
126
        };
127
    }
128
 
129
    /**
130
     * Returns true if shell_exec() is available for use
131
     */
132
    private function hasShellExec(): bool
133
    {
134
        $disabledFunctions = strtolower((string) ini_get('disable_functions'));
135
 
136
        return !str_contains($disabledFunctions, 'shell_exec');
137
    }
138
 
139
    /**
140
     * Returns the PHP_OS string
141
     */
142
    private function getOs(): string
143
    {
144
        /**
145
         * @psalm-suppress UnnecessaryVarAnnotation
146
         * @var string $phpOs
147
         */
148
        $phpOs = constant('PHP_OS');
149
 
150
        return strtoupper(substr($phpOs, 0, 3));
151
    }
152
 
153
    /**
154
     * Returns the user identifier for a user on a Windows system
155
     *
156
     * Windows does not have the same concept as an effective POSIX UID for the
157
     * running script. Instead, each user is uniquely identified by an SID
158
     * (security identifier). The SID includes three 32-bit unsigned integers
159
     * that make up a unique domain identifier, followed by an RID (relative
160
     * identifier) that we will use as the UID. The primary caveat is that this
161
     * UID may not be unique to the system, since it is, instead, unique to the
162
     * domain.
163
     *
164
     * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number?
165
     * @link https://bit.ly/30vE7NM Well-known SID Structures
166
     * @link https://bit.ly/2FWcYKJ Well-known security identifiers in Windows operating systems
167
     * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user
168
     */
169
    private function getWindowsUid(): string
170
    {
171
        $response = shell_exec('whoami /user /fo csv /nh');
172
 
173
        if ($response === null) {
174
            return '';
175
        }
176
 
177
        $sid = str_getcsv(trim((string) $response))[1] ?? '';
178
 
179
        if (($lastHyphen = strrpos($sid, '-')) === false) {
180
            return '';
181
        }
182
 
183
        return trim(substr($sid, $lastHyphen + 1));
184
    }
185
 
186
    /**
187
     * Returns a group identifier for a user on a Windows system
188
     *
189
     * Since Windows does not have the same concept as an effective POSIX GID
190
     * for the running script, we will get the local group memberships for the
191
     * user running the script. Then, we will get the SID (security identifier)
192
     * for the first group that appears in that list. Finally, we will return
193
     * the RID (relative identifier) for the group and use that as the GID.
194
     *
195
     * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line
196
     */
197
    private function getWindowsGid(): string
198
    {
199
        $response = shell_exec('net user %username% | findstr /b /i "Local Group Memberships"');
200
 
201
        if ($response === null) {
202
            return '';
203
        }
204
 
205
        /** @var string[] $userGroups */
206
        $userGroups = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);
207
 
208
        $firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B");
209
 
210
        if ($firstGroup === '') {
211
            return '';
212
        }
213
 
214
        $response = shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup));
215
 
216
        if ($response === null) {
217
            return '';
218
        }
219
 
220
        /** @var string[] $userGroup */
221
        $userGroup = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY);
222
 
223
        $sid = $userGroup[1] ?? '';
224
 
225
        if (($lastHyphen = strrpos($sid, '-')) === false) {
226
            return '';
227
        }
228
 
229
        return trim(substr($sid, $lastHyphen + 1));
230
    }
231
}