diff options
author | Jakub Zelenka <bukka@php.net> | 2020-03-29 20:21:24 +0100 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2020-03-29 20:21:24 +0100 |
commit | 477efe935bf120255b9e034d934b81f7e75a075f (patch) | |
tree | 53520b65f431aec1bb636d2ae3842d7a610f80c2 /sapi | |
parent | 5fa17fbf94fa95705922313ac0d19e38ddabbad9 (diff) | |
parent | 0b4e80b8c1462a17ab758e600e2a5ddb39d80c06 (diff) | |
download | php-git-477efe935bf120255b9e034d934b81f7e75a075f.tar.gz |
Merge branch 'PHP-7.4'
Diffstat (limited to 'sapi')
-rw-r--r-- | sapi/fpm/fpm/fpm_unix.c | 36 | ||||
-rw-r--r-- | sapi/fpm/tests/socket-uds-numeric-ugid-nonroot.phpt | 62 | ||||
-rw-r--r-- | sapi/fpm/tests/socket-uds-numeric-ugid.phpt | 58 | ||||
-rw-r--r-- | sapi/fpm/tests/tester.inc | 56 | ||||
-rw-r--r-- | sapi/fpm/www.conf.in | 3 |
5 files changed, 200 insertions, 15 deletions
diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c index 6490a7b5ba..1c28b1aa09 100644 --- a/sapi/fpm/fpm/fpm_unix.c +++ b/sapi/fpm/fpm/fpm_unix.c @@ -163,27 +163,35 @@ int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */ #endif if (c->listen_owner && *c->listen_owner) { - struct passwd *pwd; + if (strlen(c->listen_owner) == strspn(c->listen_owner, "0123456789")) { + wp->socket_uid = strtoul(c->listen_owner, 0, 10); + } else { + struct passwd *pwd; - pwd = getpwnam(c->listen_owner); - if (!pwd) { - zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); - return -1; - } + pwd = getpwnam(c->listen_owner); + if (!pwd) { + zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); + return -1; + } - wp->socket_uid = pwd->pw_uid; - wp->socket_gid = pwd->pw_gid; + wp->socket_uid = pwd->pw_uid; + wp->socket_gid = pwd->pw_gid; + } } if (c->listen_group && *c->listen_group) { - struct group *grp; + if (strlen(c->listen_group) == strspn(c->listen_group, "0123456789")) { + wp->socket_gid = strtoul(c->listen_group, 0, 10); + } else { + struct group *grp; - grp = getgrnam(c->listen_group); - if (!grp) { - zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); - return -1; + grp = getgrnam(c->listen_group); + if (!grp) { + zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); + return -1; + } + wp->socket_gid = grp->gr_gid; } - wp->socket_gid = grp->gr_gid; } return 0; diff --git a/sapi/fpm/tests/socket-uds-numeric-ugid-nonroot.phpt b/sapi/fpm/tests/socket-uds-numeric-ugid-nonroot.phpt new file mode 100644 index 0000000000..a4d352123c --- /dev/null +++ b/sapi/fpm/tests/socket-uds-numeric-ugid-nonroot.phpt @@ -0,0 +1,62 @@ +--TEST-- +FPM: UNIX socket owner and group settings can be numeric +--SKIPIF-- +<?php +include "skipif.inc"; +FPM\Tester::skipIfPosixNotLoaded(); +?> +--FILE-- +<?php + +require_once "tester.inc"; + +$cfg = <<<EOT +[global] +error_log = {{FILE:LOG}} +[unconfined] +listen = {{ADDR:UDS}} +listen.owner = {{UID}} +listen.group = {{GID}} +user = {{USER}} +ping.path = /ping +ping.response = pong +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +EOT; + +$tester = new FPM\Tester($cfg); +$tester->testConfig(); +$tester->start(); +$tester->expectLogNotice( + "'user' directive is ignored when FPM is not running as root", + 'unconfined' +); +$tester->expectLogStartNotices(); +$tester->ping('{{ADDR:UDS}}'); +$st = stat($tester->getListen('{{ADDR:UDS}}')); +if ($st) { + $pw = posix_getpwuid($st['uid']); + $gr = posix_getgrgid($st['gid']); + $user = $pw ? $pw['name'] : 'UNKNOWN'; + $group = $gr ? $gr['name'] : 'UNKNOWN'; + echo "{$st['uid']}/{$user},{$st['gid']}/{$group}\n"; +} else { + echo "stat failed for " . $tester->getListen('{{ADDR:UDS}}'); +} +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECTF-- +%d/%s,%d/%s +Done +--CLEAN-- +<?php +require_once "tester.inc"; +FPM\Tester::clean(); +?> diff --git a/sapi/fpm/tests/socket-uds-numeric-ugid.phpt b/sapi/fpm/tests/socket-uds-numeric-ugid.phpt new file mode 100644 index 0000000000..d97ab2fc3f --- /dev/null +++ b/sapi/fpm/tests/socket-uds-numeric-ugid.phpt @@ -0,0 +1,58 @@ +--TEST-- +FPM: UNIX socket owner and group settings can be numeric +--SKIPIF-- +<?php +include "skipif.inc"; +FPM\Tester::skipIfPosixNotLoaded(); +FPM\Tester::skipIfNotRoot(); +?> +--FILE-- +<?php + +require_once "tester.inc"; + +$cfg = <<<EOT +[global] +error_log = {{FILE:LOG}} +[unconfined] +listen = {{ADDR:UDS}} +listen.owner = 1234 +listen.group = 1234 +user = 1234 +ping.path = /ping +ping.response = pong +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +EOT; + +$tester = new FPM\Tester($cfg); +$tester->start(); +$tester->expectLogStartNotices(); +$tester->ping('{{ADDR:UDS}}'); +$st = stat($tester->getListen('{{ADDR:UDS}}')); +if ($st) { + $pw = posix_getpwuid($st['uid']); + $gr = posix_getgrgid($st['gid']); + $user = $pw ? $pw['name'] : 'UNKNOWN'; + $group = $gr ? $gr['name'] : 'UNKNOWN'; + echo "{$st['uid']}/{$user},{$st['gid']}/{$group}\n"; +} else { + echo "stat failed for " . $tester->getListen('{{ADDR:UDS}}'); +} +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECT-- +1234/UNKNOWN,1234/UNKNOWN +Done +--CLEAN-- +<?php +require_once "tester.inc"; +FPM\Tester::clean(); +?> diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index 3424898074..e553e94f15 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -269,6 +269,26 @@ class Tester } /** + * Skip if not running as root. + */ + static public function skipIfNotRoot() + { + if (getmyuid() != 0) { + die('skip not running as root'); + } + } + + /** + * Skip if posix extension not loaded. + */ + static public function skipIfPosixNotLoaded() + { + if (!extension_loaded('posix')) { + die('skip posix extension not loaded'); + } + } + + /** * Tester constructor. * * @param string|array $configTemplate @@ -666,6 +686,38 @@ class Tester } /** + * @return string + */ + public function getUser() + { + return get_current_user(); + } + + /** + * @return string + */ + public function getGroup() + { + return get_current_group(); + } + + /** + * @return int + */ + public function getUid() + { + return getmyuid(); + } + + /** + * @return int + */ + public function getGid() + { + return getmygid(); + } + + /** * Send signal to the supplied PID or the server PID. * * @param string $signal @@ -761,6 +813,10 @@ class Tester 'ADDR:UDS' => ['getAddr', 'uds'], 'PORT' => ['getPort', 'ip'], 'INCLUDE:CONF' => self::CONF_DIR . '/*.conf', + 'USER' => ['getUser'], + 'GROUP' => ['getGroup'], + 'UID' => ['getUid'], + 'GID' => ['getGid'], ]; $aliases = [ 'ADDR' => 'ADDR:IPv4', diff --git a/sapi/fpm/www.conf.in b/sapi/fpm/www.conf.in index 815618c65d..0bb4008ae1 100644 --- a/sapi/fpm/www.conf.in +++ b/sapi/fpm/www.conf.in @@ -41,7 +41,8 @@ listen = 127.0.0.1:9000 ; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many -; BSD-derived systems allow connections regardless of permissions. +; BSD-derived systems allow connections regardless of permissions. The owner +; and group can be specified either by name or by their numeric IDs. ; Default Values: user and group are set as the running user ; mode is set to 0660 ;listen.owner = @php_fpm_user@ |