first update

This commit is contained in:
tuend-work
2025-11-12 20:19:03 +07:00
commit ca56c8cfa5
76 changed files with 10082 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,166 @@
From 4af4a4a71827c0bc5e0ec67af23edef4f15cee8e Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 5 Mar 2018 10:56:29 -0800
Subject: [PATCH] fflush: adjust to glibc 2.28 libio.h removal
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Problem reported by Daniel P. Berrangé in:
https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html
* lib/fbufmode.c (fbufmode):
* lib/fflush.c (clear_ungetc_buffer_preserving_position)
(disable_seek_optimization, rpl_fflush):
* lib/fpending.c (__fpending):
* lib/fpurge.c (fpurge):
* lib/freadable.c (freadable):
* lib/freadahead.c (freadahead):
* lib/freading.c (freading):
* lib/freadptr.c (freadptr):
* lib/freadseek.c (freadptrinc):
* lib/fseeko.c (fseeko):
* lib/fseterr.c (fseterr):
* lib/fwritable.c (fwritable):
* lib/fwriting.c (fwriting):
Check _IO_EOF_SEEN instead of _IO_ftrylockfile.
* lib/stdio-impl.h (_IO_IN_BACKUP) [_IO_EOF_SEEN]:
Define if not already defined.
[yann.morin.1998@free.fr: partially backport from upstream gnulib]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
lib/fflush.c | 6 +++---
lib/fpending.c | 2 +-
lib/fpurge.c | 2 +-
lib/freadahead.c | 2 +-
lib/freading.c | 2 +-
lib/fseeko.c | 4 ++--
lib/stdio-impl.h | 6 ++++++
7 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/lib/fflush.c b/build-aux/gnulib/lib/fflush.c
index 983ade0ff..a6edfa105 100644
--- a/lib/fflush.c
+++ b/lib/fflush.c
@@ -33,7 +33,7 @@
#undef fflush
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
/* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
static void
@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
#endif
-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
+#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
# if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
if (stream == NULL || ! freading (stream))
return fflush (stream);
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
clear_ungetc_buffer_preserving_position (stream);
diff --git a/lib/fpending.c b/build-aux/gnulib/lib/fpending.c
index c84e3a5b4..789f50e4e 100644
--- a/lib/fpending.c
+++ b/lib/fpending.c
@@ -32,7 +32,7 @@ __fpending (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
return fp->_IO_write_ptr - fp->_IO_write_base;
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/fpurge.c b/build-aux/gnulib/lib/fpurge.c
index b1d417c7a..3aedcc373 100644
--- a/lib/fpurge.c
+++ b/lib/fpurge.c
@@ -62,7 +62,7 @@ fpurge (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
fp->_IO_read_end = fp->_IO_read_ptr;
fp->_IO_write_ptr = fp->_IO_write_base;
/* Avoid memory leak when there is an active ungetc buffer. */
diff --git a/lib/freadahead.c b/build-aux/gnulib/lib/freadahead.c
index c2ecb5b28..23ec76ee5 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -30,7 +30,7 @@ extern size_t __sreadahead (FILE *);
size_t
freadahead (FILE *fp)
{
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
if (fp->_IO_write_ptr > fp->_IO_write_base)
return 0;
return (fp->_IO_read_end - fp->_IO_read_ptr)
diff --git a/lib/freading.c b/build-aux/gnulib/lib/freading.c
index 73c28acdd..c24d0c88a 100644
--- a/lib/freading.c
+++ b/lib/freading.c
@@ -31,7 +31,7 @@ freading (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
return ((fp->_flags & _IO_NO_WRITES) != 0
|| ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
&& fp->_IO_read_base != NULL));
diff --git a/lib/fseeko.c b/build-aux/gnulib/lib/fseeko.c
index 0101ab55f..193f4e8ce 100644
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence)
#endif
/* These tests are based on fpurge.c. */
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
if (fp->_IO_read_end == fp->_IO_read_ptr
&& fp->_IO_write_ptr == fp->_IO_write_base
&& fp->_IO_save_base == NULL)
@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int whence)
return -1;
}
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
fp->_flags &= ~_IO_EOF_SEEN;
fp->_offset = pos;
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
diff --git a/lib/stdio-impl.h b/build-aux/gnulib/lib/stdio-impl.h
index 78d896e9f..05c5752a2 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -18,6 +18,12 @@
the same implementation of stdio extension API, except that some fields
have different naming conventions, or their access requires some casts. */
+/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
+ problem by defining it ourselves. FIXME: Do not rely on glibc
+ internals. */
+#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
+# define _IO_IN_BACKUP 0x100
+#endif
/* BSD stdio derived implementations. */
--
2.14.1

View File

@@ -0,0 +1,151 @@
From 74d9d6a293d7462dea8f83e7fc5ac792e956a0ad Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 8 Mar 2018 16:42:45 -0800
Subject: [PATCH 2/2] fflush: be more paranoid about libio.h change
Suggested by Eli Zaretskii in:
https://lists.gnu.org/r/emacs-devel/2018-03/msg00270.html
* lib/fbufmode.c (fbufmode):
* lib/fflush.c (clear_ungetc_buffer_preserving_position)
(disable_seek_optimization, rpl_fflush):
* lib/fpending.c (__fpending):
* lib/fpurge.c (fpurge):
* lib/freadable.c (freadable):
* lib/freadahead.c (freadahead):
* lib/freading.c (freading):
* lib/freadptr.c (freadptr):
* lib/freadseek.c (freadptrinc):
* lib/fseeko.c (fseeko):
* lib/fseterr.c (fseterr):
* lib/fwritable.c (fwritable):
* lib/fwriting.c (fwriting):
Look at _IO_ftrylockfile as well as at _IO_EOF_SEEN.
---
lib/fflush.c | 9 ++++++---
lib/fpending.c | 3 ++-
lib/fpurge.c | 3 ++-
lib/freadahead.c | 3 ++-
lib/freading.c | 3 ++-
lib/fseeko.c | 6 ++++--
6 files changed, 18 insertions(+), 9 deletions(-)
[yann.morin.1998@free.fr: partially backport from upstream gnulib]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
diff --git a/lib/fflush.c b/build-aux/gnulib/lib/fflush.c
index a6edfa105..a140b7ad9 100644
--- a/lib/fflush.c
+++ b/lib/fflush.c
@@ -33,7 +33,8 @@
#undef fflush
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+/* GNU libc, BeOS, Haiku, Linux libc5 */
/* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
static void
@@ -72,7 +73,8 @@ clear_ungetc_buffer (FILE *fp)
#endif
-#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
+#if ! (defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1)
+/* GNU libc, BeOS, Haiku, Linux libc5 */
# if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
@@ -148,7 +150,8 @@ rpl_fflush (FILE *stream)
if (stream == NULL || ! freading (stream))
return fflush (stream);
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
clear_ungetc_buffer_preserving_position (stream);
diff --git a/lib/fpending.c b/build-aux/gnulib/lib/fpending.c
index 789f50e4e..7bc235ded 100644
--- a/lib/fpending.c
+++ b/lib/fpending.c
@@ -32,7 +32,8 @@ __fpending (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
return fp->_IO_write_ptr - fp->_IO_write_base;
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/fpurge.c b/build-aux/gnulib/lib/fpurge.c
index 3aedcc373..554790b56 100644
--- a/lib/fpurge.c
+++ b/lib/fpurge.c
@@ -62,7 +62,8 @@ fpurge (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
fp->_IO_read_end = fp->_IO_read_ptr;
fp->_IO_write_ptr = fp->_IO_write_base;
/* Avoid memory leak when there is an active ungetc buffer. */
diff --git a/lib/freadahead.c b/build-aux/gnulib/lib/freadahead.c
index 23ec76ee5..ed3dd0ebd 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -30,7 +30,8 @@ extern size_t __sreadahead (FILE *);
size_t
freadahead (FILE *fp)
{
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
if (fp->_IO_write_ptr > fp->_IO_write_base)
return 0;
return (fp->_IO_read_end - fp->_IO_read_ptr)
diff --git a/lib/freading.c b/build-aux/gnulib/lib/freading.c
index c24d0c88a..790f92ca3 100644
--- a/lib/freading.c
+++ b/lib/freading.c
@@ -31,7 +31,8 @@ freading (FILE *fp)
/* Most systems provide FILE as a struct and the necessary bitmask in
<stdio.h>, because they need it for implementing getc() and putc() as
fast macros. */
-# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
return ((fp->_flags & _IO_NO_WRITES) != 0
|| ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
&& fp->_IO_read_base != NULL));
diff --git a/lib/fseeko.c b/build-aux/gnulib/lib/fseeko.c
index 193f4e8ce..e5c5172e7 100644
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -47,7 +47,8 @@ fseeko (FILE *fp, off_t offset, int whence)
#endif
/* These tests are based on fpurge.c. */
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
if (fp->_IO_read_end == fp->_IO_read_ptr
&& fp->_IO_write_ptr == fp->_IO_write_base
&& fp->_IO_save_base == NULL)
@@ -123,7 +124,8 @@ fseeko (FILE *fp, off_t offset, int whence)
return -1;
}
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
fp->_flags &= ~_IO_EOF_SEEN;
fp->_offset = pos;
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
--
2.14.1

View File

@@ -0,0 +1,58 @@
Description: Support OpenSSL 1.1
When building with OpenSSL 1.1 and newer, use the new built-in
hostname verification instead of code that doesn't compile due to
structs having been made opaque.
Bug-Debian: https://bugs.debian.org/828589
--- a/src/osdep/unix/ssl_unix.c
+++ b/src/osdep/unix/ssl_unix.c
@@ -227,8 +227,16 @@ static char *ssl_start_work (SSLSTREAM *
/* disable certificate validation? */
if (flags & NET_NOVALIDATECERT)
SSL_CTX_set_verify (stream->context,SSL_VERIFY_NONE,NIL);
- else SSL_CTX_set_verify (stream->context,SSL_VERIFY_PEER,ssl_open_verify);
+ else {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ X509_VERIFY_PARAM *param = SSL_CTX_get0_param(stream->context);
+ X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ X509_VERIFY_PARAM_set1_host(param, host, 0);
+#endif
+
+ SSL_CTX_set_verify (stream->context,SSL_VERIFY_PEER,ssl_open_verify);
/* set default paths to CAs... */
+ }
SSL_CTX_set_default_verify_paths (stream->context);
/* ...unless a non-standard path desired */
if (s = (char *) mail_parameters (NIL,GET_SSLCAPATH,NIL))
@@ -266,6 +274,7 @@ static char *ssl_start_work (SSLSTREAM *
if (SSL_write (stream->con,"",0) < 0)
return ssl_last_error ? ssl_last_error : "SSL negotiation failed";
/* need to validate host names? */
+#if OPENSSL_VERSION_NUMBER < 0x10100000
if (!(flags & NET_NOVALIDATECERT) &&
(err = ssl_validate_cert (cert = SSL_get_peer_certificate (stream->con),
host))) {
@@ -275,6 +284,7 @@ static char *ssl_start_work (SSLSTREAM *
sprintf (tmp,"*%.128s: %.255s",err,cert ? cert->name : "???");
return ssl_last_error = cpystr (tmp);
}
+#endif
return NIL;
}
@@ -313,6 +323,7 @@ static int ssl_open_verify (int ok,X509_
* Returns: NIL if validated, else string of error message
*/
+#if OPENSSL_VERSION_NUMBER < 0x10100000
static char *ssl_validate_cert (X509 *cert,char *host)
{
int i,n;
@@ -342,6 +353,7 @@ static char *ssl_validate_cert (X509 *ce
else ret = "Unable to locate common name in certificate";
return ret;
}
+#endif
/* Case-independent wildcard pattern match
* Accepts: base string

View File

@@ -0,0 +1,20 @@
--- sapi/fpm/fpm/fpm_main.c.old 2014-09-15 10:19:13.910192543 +0200
+++ sapi/fpm/fpm/fpm_main.c 2014-09-15 10:48:25.238490219 +0200
@@ -1237,6 +1237,17 @@
SG(request_info).request_uri = orig_script_name;
}
path_info[0] = old;
+ } else if (apache_was_here && env_script_name) {
+ /* Using mod_proxy_fcgi and ProxyPass, apache cannot set PATH_INFO
+ * As we can extract PATH_INFO from PATH_TRANSLATED
+ * it is probably also in SCRIPT_NAME and need to be removed
+ */
+ int snlen = strlen(env_script_name);
+ if (snlen>slen && !strcmp(env_script_name+snlen-slen, path_info)) {
+ _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC);
+ env_script_name[snlen-slen] = 0;
+ SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_script_name TSRMLS_CC);
+ }
}
env_path_info = _sapi_cgibin_putenv("PATH_INFO", path_info TSRMLS_CC);
}

View File

@@ -0,0 +1,11 @@
--- awstats_buildstaticpages.pl.orig 2012-12-10 01:51:41.000000000 -0700
+++ awstats_buildstaticpages.pl 2012-12-10 02:34:12.000000000 -0700
@@ -425,7 +425,7 @@
my $cpt=0;
my $NoLoadPlugin="";
if ($BuildPDF) { $NoLoadPlugin.="tooltips,rawlog,hostinfo"; }
-my $smallcommand="\"$Awstats\" -config=$SiteConfig".($BuildPDF?" -buildpdf":"").($NoLoadPlugin?" -noloadplugin=$NoLoadPlugin":"").($DatabaseBreak?" -databasebreak=$DatabaseBreak":"")." -staticlinks".($OutputSuffix ne $SiteConfig?"=$OutputSuffix":"");
+my $smallcommand="\"$Awstats\" -config=$SiteConfig".($BuildPDF?" -buildpdf":"").($NoLoadPlugin?" -noloadplugin=$NoLoadPlugin":"").($DatabaseBreak?" -databasebreak=$DatabaseBreak":"")." -staticlinks".($OutputSuffix ne $SiteConfig?"=awstats.$OutputSuffix":"");
if ($StaticExt && $StaticExt ne 'html') { $smallcommand.=" -staticlinksext=$StaticExt"; }
if ($DirIcons) { $smallcommand.=" -diricons=$DirIcons"; }
if ($DirConfig) { $smallcommand.=" -configdir=$DirConfig"; }

View File

@@ -0,0 +1,15 @@
--- spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm 2014/06/18 16:47:04 1603517
+++ spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm 2014/06/18 16:48:04 1603518
@@ -204,8 +204,10 @@
@ns_addr_port = @{$self->{conf}->{dns_servers}};
dbg("dns: servers set by config to: %s", join(', ',@ns_addr_port));
} elsif ($res) { # default as provided by Net::DNS, e.g. /etc/resolv.conf
- @ns_addr_port = map(untaint_var("[$_]:" . $res->{port}),
- @{$res->{nameservers}});
+ my @ns = $res->UNIVERSAL::can('nameservers') ? $res->nameservers
+ : @{$res->{nameservers}};
+ my $port = $res->UNIVERSAL::can('port') ? $res->port : $res->{port};
+ @ns_addr_port = map(untaint_var("[$_]:" . $port), @ns);
dbg("dns: servers obtained from Net::DNS : %s", join(', ',@ns_addr_port));
}
return @ns_addr_port;

View File

@@ -0,0 +1,75 @@
--- src/lib-master/test-event-stats.c.orig 2019-02-22 17:27:55.996934000 -0700
+++ src/lib-master/test-event-stats.c 2019-02-22 17:32:00.455939000 -0700
@@ -13,6 +13,7 @@
#include "test-common.h"
#include <fcntl.h>
#include <unistd.h>
+#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
@@ -360,7 +361,7 @@
event_unref(&child_ev);
test_assert(
compare_test_stats_to(
- "EVENT %lu 1 0 0"
+ "EVENT %"PRIu64" 1 0 0"
" stest-event-stats.c %d"
" l0 0 ctest2\n", id, l));
test_end();
@@ -386,12 +387,12 @@
event_unref(&child_ev);
test_assert(
compare_test_stats_to(
- "BEGIN %lu 0 1 0 0"
+ "BEGIN %"PRIu64" 0 1 0 0"
" stest-event-stats.c %d ctest1\n"
- "EVENT %lu 1 1 0"
+ "EVENT %"PRIu64" 1 1 0"
" stest-event-stats.c %d"
" l1 0 ctest2\n"
- "END\t%lu\n", idp, lp, idp, l, idp));
+ "END\t%"PRIu64"\n", idp, lp, idp, l, idp));
test_end();
}
@@ -451,7 +452,7 @@
event_unref(&merge_ev2);
test_assert(
compare_test_stats_to(
- "EVENT %lu 1 0 0"
+ "EVENT %"PRIu64" 1 0 0"
" stest-event-stats.c %d l0 0"
" ctest3 ctest2 ctest1 Tkey3"
" 10 0 Ikey2 20"
@@ -483,11 +484,11 @@
event_unref(&child_ev);
test_assert(
compare_test_stats_to(
- "BEGIN %lu 0 1 0 0"
+ "BEGIN %"PRIu64" 0 1 0 0"
" stest-event-stats.c %d ctest1\n"
- "EVENT %lu 1 3 0 "
+ "EVENT %"PRIu64" 1 3 0 "
"stest-event-stats.c %d l3 0"
- " ctest2\nEND\t%lu\n", id, lp, id, l, id));
+ " ctest2\nEND\t%"PRIu64"\n", id, lp, id, l, id));
test_end();
}
@@ -525,12 +526,12 @@
event_unref(&child2_ev);
test_assert(
compare_test_stats_to(
- "BEGIN %lu 0 1 0 0"
+ "BEGIN %"PRIu64" 0 1 0 0"
" stest-event-stats.c %d ctest1\n"
- "EVENT %lu 1 3 0 "
+ "EVENT %"PRIu64" 1 3 0 "
"stest-event-stats.c %d l3 0 "
"ctest4 ctest5 Tkey3 10 0 Skey4"
- " str4\nEND\t%lu\n", id, lp, id, l, id));
+ " str4\nEND\t%"PRIu64"\n", id, lp, id, l, id));
test_end();
}

View File

@@ -0,0 +1,20 @@
--- src/plugins/quota/quota-maildir.c.orig 2020-02-05 19:21:08.582998417 -0700
+++ src/plugins/quota/quota-maildir.c 2020-02-05 19:21:22.184998798 -0700
@@ -84,7 +84,7 @@
p = strstr(dp->d_name, ",S=");
num = (uoff_t)-1;
- if (p != NULL) {
+ if (0 && p != NULL) {
/* ,S=nnnn[:,] */
p += 3;
for (num = 0; *p >= '0' && *p <= '9'; p++)
@@ -104,7 +104,7 @@
str_truncate(path, len);
str_append(path, dp->d_name);
if (stat(str_c(path), &st) == 0) {
- *total_bytes += st.st_size;
+ *total_bytes += st.st_blocks * 512;
*total_count += 1;
} else if (errno != ENOENT && errno != ESTALE) {
*error_r = t_strdup_printf(

View File

@@ -0,0 +1,86 @@
--- dovecot.conf.orig 2013-04-18 01:28:36.000000000 -0600
+++ dovecot.conf 2013-09-11 15:38:09.000000000 -0600
@@ -15,7 +15,7 @@
mail_location = maildir:~/Maildir
default_process_limit=512
-default_client_limit=2048
+default_client_limit=2560
passdb {
driver = shadow
@@ -24,8 +24,13 @@
args = username_format=%n /etc/virtual/%d/passwd
driver = passwd-file
}
-protocols = imap pop3
+protocols = imap pop3 lmtp sieve
service auth {
+ unix_listener auth-master {
+ user = mail
+ group = mail
+ mode = 0660
+ }
user = root
}
service imap-login {
@@ -56,3 +61,59 @@
remote 127.0.0.1 {
mail_max_userip_connections = 40
}
+
+
+# LMTP socket for local delivery from exim
+service lmtp {
+ unix_listener lmtp-client {
+ user = mail
+ group = mail
+ mode = 0660
+ }
+}
+
+#Managesieve service (allows rules editing on client-side)
+service managesieve-login {
+ inet_listener sieve {
+ port = 4190
+ }
+ service_count = 1
+ process_min_avail = 4
+ vsz_limit = 64M
+}
+
+service managesieve {
+}
+
+protocol lmtp {
+ mail_plugins = $mail_plugins sieve
+ log_path = /var/log/dovecot-lmtp-errors.log
+ info_log_path = /var/log/dovecot-lmtp.log
+ postmaster_address = postmaster@hostname #required
+}
+
+protocol sieve {
+ managesieve_max_line_length = 65536
+ managesieve_implementation_string = Dovecot Pigeonhole
+ managesieve_max_compile_errors = 5
+ managesieve_logout_format = bytes=%i/%o
+ log_path = /var/log/dovecot-sieve-errors.log
+ info_log_path = /var/log/dovecot-sieve.log
+}
+
+plugin {
+ #More details: http://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration
+ # the path to the user's main active script (per user)
+ sieve = ~/.dovecot.sieve
+
+ # path to a global sieve script file, which gets executed ONLY if user's private Sieve script doesn't exist,
+ sieve_default = /var/lib/dovecot/sieve/default.sieve
+
+ # Directory where user's rules are stored
+ sieve_dir = ~/sieve
+
+ # Directory for :global include scripts for the include extension
+ sieve_global_dir = /var/lib/dovecot/sieve/global/
+}
+
+

View File

@@ -0,0 +1,77 @@
--- dovecot.conf.orig 2013-04-18 01:28:36.000000000 -0600
+++ dovecot.conf 2013-04-18 14:11:46.000000000 -0600
@@ -24,8 +24,13 @@
args = username_format=%n /etc/virtual/%d/passwd
driver = passwd-file
}
-protocols = imap pop3
+protocols = imap pop3 lmtp sieve
service auth {
+ unix_listener auth-master {
+ user = mail
+ group = mail
+ mode = 0660
+ }
user = root
}
service imap-login {
@@ -56,3 +61,59 @@
remote 127.0.0.1 {
mail_max_userip_connections = 40
}
+
+
+# LMTP socket for local delivery from exim
+service lmtp {
+ unix_listener lmtp-client {
+ user = mail
+ group = mail
+ mode = 0660
+ }
+}
+
+#Managesieve service (allows rules editing on client-side)
+service managesieve-login {
+ inet_listener sieve {
+ port = 4190
+ }
+ service_count = 1
+ process_min_avail = 4
+ vsz_limit = 64M
+}
+
+service managesieve {
+}
+
+protocol lmtp {
+ mail_plugins = $mail_plugins sieve
+ log_path = /var/log/dovecot-lmtp-errors.log
+ info_log_path = /var/log/dovecot-lmtp.log
+ postmaster_address = postmaster@hostname #required
+}
+
+protocol sieve {
+ managesieve_max_line_length = 65536
+ managesieve_implementation_string = Dovecot Pigeonhole
+ managesieve_max_compile_errors = 5
+ managesieve_logout_format = bytes=%i/%o
+ log_path = /var/log/dovecot-sieve-errors.log
+ info_log_path = /var/log/dovecot-sieve.log
+}
+
+plugin {
+ #More details: http://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration
+ # the path to the user's main active script (per user)
+ sieve = ~/.dovecot.sieve
+
+ # path to a global sieve script file, which gets executed ONLY if user's private Sieve script doesn't exist,
+ sieve_default = /var/lib/dovecot/sieve/default.sieve
+
+ # Directory where user's rules are stored
+ sieve_dir = ~/sieve
+
+ # Directory for :global include scripts for the include extension
+ sieve_global_dir = /var/lib/dovecot/sieve/global/
+}
+
+

View File

@@ -0,0 +1,86 @@
--- dovecot.conf.orig 2013-04-18 01:28:36.000000000 -0600
+++ dovecot.conf 2013-09-11 15:38:09.000000000 -0600
@@ -15,7 +15,7 @@
mail_location = maildir:~/Maildir
default_process_limit=512
-default_client_limit=2048
+default_client_limit=2560
passdb {
driver = shadow
@@ -24,8 +24,13 @@
args = username_format=%n /etc/virtual/%d/passwd
driver = passwd-file
}
-protocols = imap pop3
+protocols = imap pop3 lmtp sieve
service auth {
+ unix_listener auth-master {
+ user = mail
+ group = mail
+ mode = 0660
+ }
user = root
}
service imap-login {
@@ -56,3 +61,59 @@
remote 127.0.0.1 {
mail_max_userip_connections = 40
}
+
+
+# LMTP socket for local delivery from exim
+service lmtp {
+ unix_listener lmtp-client {
+ user = mail
+ group = mail
+ mode = 0660
+ }
+}
+
+#Managesieve service (allows rules editing on client-side)
+service managesieve-login {
+ inet_listener sieve {
+ port = 4190
+ }
+ service_count = 1
+ process_min_avail = 4
+ vsz_limit = 64M
+}
+
+service managesieve {
+}
+
+protocol lmtp {
+ mail_plugins = $mail_plugins sieve
+ log_path = /var/log/dovecot-lmtp-errors.log
+ info_log_path = /var/log/dovecot-lmtp.log
+ postmaster_address = postmaster@hostname #required
+}
+
+protocol sieve {
+ managesieve_max_line_length = 65536
+ managesieve_implementation_string = Dovecot Pigeonhole
+ managesieve_max_compile_errors = 5
+ managesieve_logout_format = bytes=%i/%o
+ log_path = /var/log/dovecot-sieve-errors.log
+ info_log_path = /var/log/dovecot-sieve.log
+}
+
+plugin {
+ #More details: http://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration
+ # the path to the user's main active script (per user)
+ sieve = ~/.dovecot.sieve
+
+ # path to a global sieve script file, which gets executed ONLY if user's private Sieve script doesn't exist,
+ sieve_default = /var/lib/dovecot/sieve/default.sieve
+
+ # Directory where user's rules are stored
+ sieve_dir = ~/sieve
+
+ # Directory for :global include scripts for the include extension
+ sieve_global_dir = /var/lib/dovecot/sieve/global/
+}
+
+

View File

@@ -0,0 +1,37 @@
--- support/suexec.c.orig 2021-02-04 17:05:35.900988770 -0700
+++ support/suexec.c 2021-02-04 17:07:07.559046274 -0700
@@ -495,6 +495,34 @@
exit(108);
}
+ //DA_START
+ char user_slice[128];
+ snprintf(user_slice, sizeof(user_slice), "/sys/fs/cgroup/user.slice/user-%d.slice", uid);
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/directadmin-exec.scope");
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/cgroup.procs");
+ FILE *fp = fopen(user_slice, "a");
+ //if there is no cgroup, we may hit permission denied. Wait moment.
+ if (fp == NULL) {
+ struct timespec ns;
+ ns.tv_sec = 0;
+ ns.tv_nsec = 10 * 1000000; //10ms
+ int count=20;
+ while (fp == NULL && count--) {
+ nanosleep(&ns, NULL);
+ fp = fopen(user_slice, "a");
+ }
+ }
+ if (fp == NULL) {
+ log_err("Error opening %s for writing: %s", user_slice, strerror(errno));
+ } else {
+ fprintf(fp, "%d\n", (int) getpid());
+ fclose(fp);
+ }
+ }
+ }
+ //DA_END
/*
* Change UID/GID here so that the following tests work over NFS.
*

View File

@@ -0,0 +1,12 @@
--- sapi/fpm/fpm/fpm_unix.c.orig 2019-12-05 17:02:37.818844398 -0700
+++ sapi/fpm/fpm/fpm_unix.c 2019-12-05 17:20:39.578769107 -0700
@@ -235,7 +235,8 @@
if (wp->socket_uid != -1 || wp->socket_gid != -1) {
if (0 > chown(path, wp->socket_uid, wp->socket_gid)) {
zlog(ZLOG_SYSERROR, "[pool %s] failed to chown() the socket '%s'", wp->config->name, wp->config->listen_address);
- return -1;
+ chown(path, 0, wp->socket_gid);
+ return 0;
}
}
return 0;

View File

@@ -0,0 +1,41 @@
--- sapi/fpm/fpm/fpm_children.c.orig 2021-01-05 03:45:07.000000000 -0700
+++ sapi/fpm/fpm/fpm_children.c 2021-02-04 16:59:32.198595918 -0700
@@ -431,6 +431,39 @@
zlog(ZLOG_DEBUG, "unblocking signals, child born");
fpm_signals_unblock();
child->pid = pid;
+
+ //DA_START
+ char user_slice[128];
+ char systemd_start[128];
+ snprintf(systemd_start, sizeof(systemd_start), "/bin/systemctl start user-%d.slice", wp->set_uid);
+ snprintf(user_slice, sizeof(user_slice), "/sys/fs/cgroup/user.slice/user-%d.slice", wp->set_uid);
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/directadmin-exec.scope");
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/cgroup.procs");
+ FILE *fp = fopen(user_slice, "a");
+ //if there is no cgroup, we may hit permission denied. Wait moment.
+ if (fp == NULL) {
+ struct timespec ns;
+ ns.tv_sec = 0;
+ ns.tv_nsec = 10 * 1000000; //10ms
+ int count=20;
+ while (fp == NULL && count--) {
+ nanosleep(&ns, NULL);
+ fp = fopen(user_slice, "a");
+ }
+ }
+ if (fp == NULL) {
+ zlog(ZLOG_WARNING, "Error opening %s for writing: %s", user_slice, strerror(errno));
+ } else {
+ fprintf(fp, "%d\n", (int) pid);
+ fclose(fp);
+ }
+ system(systemd_start);
+ }
+ }
+ //DA_END
+
fpm_clock_get(&child->started);
fpm_parent_resources_use(child);

View File

@@ -0,0 +1,23 @@
--- sapi/fpm/fpm/fpm_main.c 2014-04-08 07:17:51.106951000 +0200
+++ sapi/fpm/fpm/fpm_main.c 2014-04-29 16:20:05.975142000 +0200
@@ -1211,8 +1211,20 @@
char *path_info;
if (apache_was_here) {
/* recall that PATH_INFO won't exist */
+ int offset;
+ char *tmp_str;
path_info = script_path_translated + ptlen;
tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
+ offset = strlen(env_script_name) - strlen(path_info);
+ if (strcmp(env_script_name + offset, path_info) == 0) {
+ tmp_str = (char *) emalloc(offset + 1);
+ memcpy(tmp_str, env_script_name, offset);
+ tmp_str[offset] = '\0';
+ if (!orig_script_name || !*orig_script_name) {
+ orig_script_name = env_script_name;
+ }
+ env_script_name = tmp_str;
+ }
} else {
path_info = env_path_info ? env_path_info + pilen - slen : NULL;
tflag = (orig_path_info != path_info);

View File

@@ -0,0 +1,398 @@
From c600ec7bcf2696882ffe961e7b158c67aa2e7277 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Sat, 2 Oct 2021 22:53:41 +0100
Subject: [PATCH] Fix bug #81026 (PHP-FPM oob R/W in root process leading to
priv escalatio)
The main change is to store scoreboard procs directly to the variable sized
array rather than indirectly through the pointer.
---
sapi/fpm/fpm/fpm_children.c | 14 ++---
sapi/fpm/fpm/fpm_request.c | 4 +-
sapi/fpm/fpm/fpm_scoreboard.c | 106 ++++++++++++++++++++-------------
sapi/fpm/fpm/fpm_scoreboard.h | 11 ++--
sapi/fpm/fpm/fpm_status.c | 4 +-
sapi/fpm/fpm/fpm_worker_pool.c | 2 +-
6 files changed, 81 insertions(+), 60 deletions(-)
diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
index fd121372f3..912f77c11a 100644
--- a/sapi/fpm/fpm/fpm_children.c
+++ b/sapi/fpm/fpm/fpm_children.c
@@ -246,7 +246,7 @@ void fpm_children_bury() /* {{{ */
fpm_child_unlink(child);
- fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_clock_get(&tv1);
@@ -256,9 +256,9 @@ void fpm_children_bury() /* {{{ */
if (!fpm_pctl_can_spawn_children()) {
severity = ZLOG_DEBUG;
}
- zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
} else {
- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
}
fpm_child_close(child, 1 /* in event_loop */);
@@ -324,7 +324,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
return 0;
}
- if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) {
+ if (0 > fpm_scoreboard_proc_alloc(c)) {
fpm_stdio_discard_pipes(c);
fpm_child_free(c);
return 0;
@@ -336,7 +336,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */
{
- fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_stdio_discard_pipes(child);
fpm_child_free(child);
}
@@ -349,10 +349,10 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
if (wp == child->wp) {
continue;
}
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid());
+ fpm_scoreboard_child_use(child, getpid());
fpm_stdio_child_use_pipes(child);
fpm_child_free(child);
}
diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c
index c80aa14462..0a6f6a7cfb 100644
--- a/sapi/fpm/fpm/fpm_request.c
+++ b/sapi/fpm/fpm/fpm_request.c
@@ -285,7 +285,7 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
struct fpm_scoreboard_proc_s *proc;
/* no need in atomicity here */
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return 0;
}
@@ -300,7 +300,7 @@ int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /*
if (!tv) return -1;
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return -1;
}
diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c
index 328f999f0c..7e9da4d684 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.c
+++ b/sapi/fpm/fpm/fpm_scoreboard.c
@@ -6,6 +6,7 @@
#include <time.h>
#include "fpm_config.h"
+#include "fpm_children.h"
#include "fpm_scoreboard.h"
#include "fpm_shm.h"
#include "fpm_sockets.h"
@@ -23,7 +24,6 @@ static float fpm_scoreboard_tick;
int fpm_scoreboard_init_main() /* {{{ */
{
struct fpm_worker_pool_s *wp;
- unsigned int i;
#ifdef HAVE_TIMES
#if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
@@ -40,7 +40,7 @@ int fpm_scoreboard_init_main() /* {{{ */
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
void *shm_mem;
if (wp->config->pm_max_children < 1) {
@@ -53,22 +53,15 @@ int fpm_scoreboard_init_main() /* {{{ */
return -1;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
- shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size);
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+ shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
if (!shm_mem) {
return -1;
}
- wp->scoreboard = shm_mem;
+ wp->scoreboard = shm_mem;
+ wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->nprocs = wp->config->pm_max_children;
- shm_mem += scoreboard_size;
-
- for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) {
- wp->scoreboard->procs[i] = shm_mem;
- }
-
- wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->start_epoch = time(NULL);
strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
}
@@ -162,28 +155,48 @@ struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
}
/* }}} */
-struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex(
+ struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/
{
if (!scoreboard) {
- scoreboard = fpm_scoreboard;
+ return NULL;
}
- if (!scoreboard) {
+ if (child_index < 0 || (unsigned int)child_index >= nprocs) {
return NULL;
}
+ return &scoreboard->procs[child_index];
+}
+/* }}} */
+
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(
+ struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+{
+ if (!scoreboard) {
+ scoreboard = fpm_scoreboard;
+ }
+
if (child_index < 0) {
child_index = fpm_scoreboard_i;
}
- if (child_index < 0 || (unsigned int)child_index >= scoreboard->nprocs) {
- return NULL;
- }
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs);
+}
+/* }}} */
- return scoreboard->procs[child_index];
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/
+{
+ struct fpm_worker_pool_s *wp = child->wp;
+ unsigned int nprocs = wp->config->pm_max_children;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
+
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs);
}
/* }}} */
+
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
{
struct fpm_scoreboard_s *s;
@@ -234,28 +247,28 @@ void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */
proc->lock = 0;
}
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */
{
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
if (!scoreboard) {
zlog(ZLOG_ERROR, "**scoreboard is NULL");
return;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs;
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size);
+ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
}
/* }}} */
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */
{
struct fpm_scoreboard_proc_s *proc;
- fpm_scoreboard = scoreboard;
- fpm_scoreboard_i = child_index;
- proc = fpm_scoreboard_proc_get(scoreboard, child_index);
+ fpm_scoreboard = child->wp->scoreboard;
+ fpm_scoreboard_i = child->scoreboard_i;
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return;
}
@@ -264,18 +277,22 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */
+void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */
{
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
+
if (!scoreboard) {
return;
}
- if (child_index < 0 || (unsigned int)child_index >= scoreboard->nprocs) {
+ if (child_index < 0 || child_index >= wp->config->pm_max_children) {
return;
}
- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
+ if (scoreboard->procs[child_index].used > 0) {
+ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
}
/* set this slot as free to avoid search on next alloc */
@@ -283,41 +300,44 @@ void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */
{
int i = -1;
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int nprocs = wp->config->pm_max_children;
- if (!scoreboard || !child_index) {
+ if (!scoreboard) {
return -1;
}
/* first try the slot which is supposed to be free */
- if (scoreboard->free_proc >= 0 && (unsigned int)scoreboard->free_proc < scoreboard->nprocs) {
- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
+ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) {
+ if (!scoreboard->procs[scoreboard->free_proc].used) {
i = scoreboard->free_proc;
}
}
if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
- for (i = 0; i < (int)scoreboard->nprocs; i++) {
- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
+ for (i = 0; i < nprocs; i++) {
+ if (!scoreboard->procs[i].used) { /* found */
break;
}
}
}
/* no free slot */
- if (i < 0 || i >= (int)scoreboard->nprocs) {
+ if (i < 0 || i >= nprocs) {
zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
return -1;
}
- scoreboard->procs[i]->used = 1;
- *child_index = i;
+ scoreboard->procs[i].used = 1;
+ child->scoreboard_i = i;
/* supposed next slot is free */
- if (i + 1 >= (int)scoreboard->nprocs) {
+ if (i + 1 >= nprocs) {
scoreboard->free_proc = 0;
} else {
scoreboard->free_proc = i + 1;
diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
index 1fecde1d0f..9d5981e1c7 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.h
+++ b/sapi/fpm/fpm/fpm_scoreboard.h
@@ -63,7 +63,7 @@ struct fpm_scoreboard_s {
unsigned int nprocs;
int free_proc;
unsigned long int slow_rq;
- struct fpm_scoreboard_proc_s *procs[];
+ struct fpm_scoreboard_proc_s procs[];
};
int fpm_scoreboard_init_main();
@@ -72,18 +72,19 @@ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_s *fpm_scoreboard_get();
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child);
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang);
void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang);
void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc);
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard);
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp);
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid);
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid);
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index);
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index);
+void fpm_scoreboard_proc_free(struct fpm_child_s *child);
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child);
#ifdef HAVE_TIMES
float fpm_scoreboard_get_tick();
diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
index 36d2240635..de8db9d61a 100644
--- a/sapi/fpm/fpm/fpm_status.c
+++ b/sapi/fpm/fpm/fpm_status.c
@@ -498,10 +498,10 @@ int fpm_status_handle_request(void) /* {{{ */
first = 1;
for (i=0; i<scoreboard_p->nprocs; i++) {
- if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) {
+ if (!scoreboard_p->procs[i].used) {
continue;
}
- proc = *scoreboard_p->procs[i];
+ proc = scoreboard_p->procs[i];
if (first) {
first = 0;
diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c
index d04528f4e0..65a9b226b1 100644
--- a/sapi/fpm/fpm/fpm_worker_pool.c
+++ b/sapi/fpm/fpm/fpm_worker_pool.c
@@ -54,7 +54,7 @@ static void fpm_worker_pool_cleanup(int which, void *arg) /* {{{ */
fpm_worker_pool_config_free(wp->config);
fpm_children_free(wp->children);
if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) {
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
fpm_worker_pool_free(wp);
}
--
2.25.1

View File

@@ -0,0 +1,397 @@
From: Jakub Zelenka <bukka@php.net>
Date: Sat, 2 Oct 2021 22:53:41 +0100
Subject: Fix bug #81026 (PHP-FPM oob R/W in root process leading to priv
escalation)
The main change is to store scoreboard procs directly to the variable sized
array rather than indirectly through the pointer.
Signed-off-by: Stanislav Malyshev <stas@php.net>
(cherry picked from commit cb2021e5f69da5e2868130a05bb53db0f9f89e4b)
(cherry picked from commit 4699cc1b1b957c843c71a79fa816446b622d4278)
---
sapi/fpm/fpm/fpm_children.c | 14 +++---
sapi/fpm/fpm/fpm_request.c | 4 +-
sapi/fpm/fpm/fpm_scoreboard.c | 107 ++++++++++++++++++++++++-----------------
sapi/fpm/fpm/fpm_scoreboard.h | 11 +++--
sapi/fpm/fpm/fpm_status.c | 4 +-
sapi/fpm/fpm/fpm_worker_pool.c | 2 +-
6 files changed, 81 insertions(+), 61 deletions(-)
diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
index 45cc075..74c2f38 100644
--- a/sapi/fpm/fpm/fpm_children.c
+++ b/sapi/fpm/fpm/fpm_children.c
@@ -239,7 +239,7 @@ void fpm_children_bury() /* {{{ */
fpm_child_unlink(child);
- fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_clock_get(&tv1);
@@ -249,9 +249,9 @@ void fpm_children_bury() /* {{{ */
if (!fpm_pctl_can_spawn_children()) {
severity = ZLOG_DEBUG;
}
- zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
} else {
- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
}
fpm_child_close(child, 1 /* in event_loop */);
@@ -317,7 +317,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
return 0;
}
- if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) {
+ if (0 > fpm_scoreboard_proc_alloc(c)) {
fpm_stdio_discard_pipes(c);
fpm_child_free(c);
return 0;
@@ -329,7 +329,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */
{
- fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_stdio_discard_pipes(child);
fpm_child_free(child);
}
@@ -342,10 +342,10 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
if (wp == child->wp) {
continue;
}
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid());
+ fpm_scoreboard_child_use(child, getpid());
fpm_stdio_child_use_pipes(child);
fpm_child_free(child);
}
diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c
index ed7e7a8..23782fb 100644
--- a/sapi/fpm/fpm/fpm_request.c
+++ b/sapi/fpm/fpm/fpm_request.c
@@ -287,7 +287,7 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
struct fpm_scoreboard_proc_s *proc;
/* no need in atomicity here */
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return 0;
}
@@ -302,7 +302,7 @@ int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /*
if (!tv) return -1;
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return -1;
}
diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c
index e1e69c9..fcf9f16 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.c
+++ b/sapi/fpm/fpm/fpm_scoreboard.c
@@ -8,6 +8,7 @@
#include <time.h>
#include "fpm_config.h"
+#include "fpm_children.h"
#include "fpm_scoreboard.h"
#include "fpm_shm.h"
#include "fpm_sockets.h"
@@ -25,7 +26,6 @@ static float fpm_scoreboard_tick;
int fpm_scoreboard_init_main() /* {{{ */
{
struct fpm_worker_pool_s *wp;
- unsigned int i;
#ifdef HAVE_TIMES
#if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
@@ -42,7 +42,7 @@ int fpm_scoreboard_init_main() /* {{{ */
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
void *shm_mem;
if (wp->config->pm_max_children < 1) {
@@ -55,22 +55,15 @@ int fpm_scoreboard_init_main() /* {{{ */
return -1;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
- shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size);
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+ shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
if (!shm_mem) {
return -1;
}
- wp->scoreboard = shm_mem;
+ wp->scoreboard = shm_mem;
+ wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->nprocs = wp->config->pm_max_children;
- shm_mem += scoreboard_size;
-
- for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) {
- wp->scoreboard->procs[i] = shm_mem;
- }
-
- wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->start_epoch = time(NULL);
strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
}
@@ -164,28 +157,47 @@ struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
}
/* }}} */
-struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex(
+ struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/
{
if (!scoreboard) {
- scoreboard = fpm_scoreboard;
+ return NULL;
}
- if (!scoreboard) {
+ if (child_index < 0 || (unsigned int)child_index >= nprocs) {
return NULL;
}
+ return &scoreboard->procs[child_index];
+}
+/* }}} */
+
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(
+ struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+{
+ if (!scoreboard) {
+ scoreboard = fpm_scoreboard;
+ }
+
if (child_index < 0) {
child_index = fpm_scoreboard_i;
}
- if (child_index < 0 || child_index >= scoreboard->nprocs) {
- return NULL;
- }
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs);
+}
+
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/
+{
+ struct fpm_worker_pool_s *wp = child->wp;
+ unsigned int nprocs = wp->config->pm_max_children;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
- return scoreboard->procs[child_index];
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs);
}
/* }}} */
+
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
{
struct fpm_scoreboard_s *s;
@@ -236,28 +248,28 @@ void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */
proc->lock = 0;
}
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */
{
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
if (!scoreboard) {
zlog(ZLOG_ERROR, "**scoreboard is NULL");
return;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs;
-
- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size);
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+
+ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
}
/* }}} */
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */
{
struct fpm_scoreboard_proc_s *proc;
- fpm_scoreboard = scoreboard;
- fpm_scoreboard_i = child_index;
- proc = fpm_scoreboard_proc_get(scoreboard, child_index);
+ fpm_scoreboard = child->wp->scoreboard;
+ fpm_scoreboard_i = child->scoreboard_i;
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return;
}
@@ -266,18 +278,22 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */
+void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */
{
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
+
if (!scoreboard) {
return;
}
- if (child_index < 0 || child_index >= scoreboard->nprocs) {
+ if (child_index < 0 || child_index >= wp->config->pm_max_children) {
return;
}
- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
+ if (scoreboard->procs[child_index].used > 0) {
+ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
}
/* set this slot as free to avoid search on next alloc */
@@ -285,41 +301,44 @@ void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */
{
int i = -1;
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int nprocs = wp->config->pm_max_children;
- if (!scoreboard || !child_index) {
+ if (!scoreboard) {
return -1;
}
/* first try the slot which is supposed to be free */
- if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) {
- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
+ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) {
+ if (!scoreboard->procs[scoreboard->free_proc].used) {
i = scoreboard->free_proc;
}
}
if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
- for (i = 0; i < scoreboard->nprocs; i++) {
- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
+ for (i = 0; i < nprocs; i++) {
+ if (!scoreboard->procs[i].used) { /* found */
break;
}
}
}
/* no free slot */
- if (i < 0 || i >= scoreboard->nprocs) {
+ if (i < 0 || i >= nprocs) {
zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
return -1;
}
- scoreboard->procs[i]->used = 1;
- *child_index = i;
+ scoreboard->procs[i].used = 1;
+ child->scoreboard_i = i;
/* supposed next slot is free */
- if (i + 1 >= scoreboard->nprocs) {
+ if (i + 1 >= nprocs) {
scoreboard->free_proc = 0;
} else {
scoreboard->free_proc = i + 1;
diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
index f58a287..a0cc093 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.h
+++ b/sapi/fpm/fpm/fpm_scoreboard.h
@@ -65,7 +65,7 @@ struct fpm_scoreboard_s {
unsigned int nprocs;
int free_proc;
unsigned long int slow_rq;
- struct fpm_scoreboard_proc_s *procs[];
+ struct fpm_scoreboard_proc_s procs[];
};
int fpm_scoreboard_init_main();
@@ -74,18 +74,19 @@ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_s *fpm_scoreboard_get();
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child);
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang);
void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang);
void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc);
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard);
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp);
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid);
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid);
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index);
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index);
+void fpm_scoreboard_proc_free(struct fpm_child_s *child);
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child);
#ifdef HAVE_TIMES
float fpm_scoreboard_get_tick();
diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
index 2363b57..a2ee398 100644
--- a/sapi/fpm/fpm/fpm_status.c
+++ b/sapi/fpm/fpm/fpm_status.c
@@ -399,10 +399,10 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
first = 1;
for (i=0; i<scoreboard_p->nprocs; i++) {
- if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) {
+ if (!scoreboard_p->procs[i].used) {
continue;
}
- proc = *scoreboard_p->procs[i];
+ proc = scoreboard_p->procs[i];
if (first) {
first = 0;
diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c
index a002291..c778b33 100644
--- a/sapi/fpm/fpm/fpm_worker_pool.c
+++ b/sapi/fpm/fpm/fpm_worker_pool.c
@@ -44,7 +44,7 @@ static void fpm_worker_pool_cleanup(int which, void *arg) /* {{{ */
fpm_worker_pool_config_free(wp->config);
fpm_children_free(wp->children);
if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) {
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
fpm_worker_pool_free(wp);
}

View File

@@ -0,0 +1,396 @@
From: Jakub Zelenka <bukka@php.net>
Date: Sat, 2 Oct 2021 22:53:41 +0100
Subject: Fix bug #81026 (PHP-FPM oob R/W in root process leading to priv
escalation)
The main change is to store scoreboard procs directly to the variable sized
array rather than indirectly through the pointer.
Signed-off-by: Stanislav Malyshev <stas@php.net>
(cherry picked from commit cb2021e5f69da5e2868130a05bb53db0f9f89e4b)
---
sapi/fpm/fpm/fpm_children.c | 14 +++---
sapi/fpm/fpm/fpm_request.c | 4 +-
sapi/fpm/fpm/fpm_scoreboard.c | 107 ++++++++++++++++++++++++-----------------
sapi/fpm/fpm/fpm_scoreboard.h | 11 +++--
sapi/fpm/fpm/fpm_status.c | 4 +-
sapi/fpm/fpm/fpm_worker_pool.c | 2 +-
6 files changed, 81 insertions(+), 61 deletions(-)
diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
index b48fa54..c7f97fd 100644
--- a/sapi/fpm/fpm/fpm_children.c
+++ b/sapi/fpm/fpm/fpm_children.c
@@ -239,7 +239,7 @@ void fpm_children_bury() /* {{{ */
fpm_child_unlink(child);
- fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_clock_get(&tv1);
@@ -249,9 +249,9 @@ void fpm_children_bury() /* {{{ */
if (!fpm_pctl_can_spawn_children()) {
severity = ZLOG_DEBUG;
}
- zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
} else {
- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
+ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
}
fpm_child_close(child, 1 /* in event_loop */);
@@ -317,7 +317,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
return 0;
}
- if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) {
+ if (0 > fpm_scoreboard_proc_alloc(c)) {
fpm_stdio_discard_pipes(c);
fpm_child_free(c);
return 0;
@@ -329,7 +329,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */
{
- fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i);
+ fpm_scoreboard_proc_free(child);
fpm_stdio_discard_pipes(child);
fpm_child_free(child);
}
@@ -342,10 +342,10 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
if (wp == child->wp) {
continue;
}
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid());
+ fpm_scoreboard_child_use(child, getpid());
fpm_stdio_child_use_pipes(child);
fpm_child_free(child);
}
diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c
index 3f82a7d..a707fd2 100644
--- a/sapi/fpm/fpm/fpm_request.c
+++ b/sapi/fpm/fpm/fpm_request.c
@@ -287,7 +287,7 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
struct fpm_scoreboard_proc_s *proc;
/* no need in atomicity here */
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return 0;
}
@@ -302,7 +302,7 @@ int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /*
if (!tv) return -1;
- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return -1;
}
diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c
index 5693ce4..45d44f4 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.c
+++ b/sapi/fpm/fpm/fpm_scoreboard.c
@@ -8,6 +8,7 @@
#include <time.h>
#include "fpm_config.h"
+#include "fpm_children.h"
#include "fpm_scoreboard.h"
#include "fpm_shm.h"
#include "fpm_sockets.h"
@@ -25,7 +26,6 @@ static float fpm_scoreboard_tick;
int fpm_scoreboard_init_main() /* {{{ */
{
struct fpm_worker_pool_s *wp;
- unsigned int i;
#ifdef HAVE_TIMES
#if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
@@ -42,7 +42,7 @@ int fpm_scoreboard_init_main() /* {{{ */
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
void *shm_mem;
if (wp->config->pm_max_children < 1) {
@@ -55,22 +55,15 @@ int fpm_scoreboard_init_main() /* {{{ */
return -1;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
- shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size);
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+ shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
if (!shm_mem) {
return -1;
}
- wp->scoreboard = shm_mem;
+ wp->scoreboard = shm_mem;
+ wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->nprocs = wp->config->pm_max_children;
- shm_mem += scoreboard_size;
-
- for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) {
- wp->scoreboard->procs[i] = shm_mem;
- }
-
- wp->scoreboard->pm = wp->config->pm;
wp->scoreboard->start_epoch = time(NULL);
strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
}
@@ -164,28 +157,47 @@ struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
}
/* }}} */
-struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex(
+ struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/
{
if (!scoreboard) {
- scoreboard = fpm_scoreboard;
+ return NULL;
}
- if (!scoreboard) {
+ if (child_index < 0 || (unsigned int)child_index >= nprocs) {
return NULL;
}
+ return &scoreboard->procs[child_index];
+}
+/* }}} */
+
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(
+ struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
+{
+ if (!scoreboard) {
+ scoreboard = fpm_scoreboard;
+ }
+
if (child_index < 0) {
child_index = fpm_scoreboard_i;
}
- if (child_index < 0 || child_index >= scoreboard->nprocs) {
- return NULL;
- }
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs);
+}
+
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/
+{
+ struct fpm_worker_pool_s *wp = child->wp;
+ unsigned int nprocs = wp->config->pm_max_children;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
- return scoreboard->procs[child_index];
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs);
}
/* }}} */
+
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
{
struct fpm_scoreboard_s *s;
@@ -236,28 +248,28 @@ void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */
proc->lock = 0;
}
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */
{
- size_t scoreboard_size, scoreboard_nprocs_size;
+ size_t scoreboard_procs_size;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
if (!scoreboard) {
zlog(ZLOG_ERROR, "**scoreboard is NULL");
return;
}
- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *);
- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs;
-
- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size);
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+
+ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
}
/* }}} */
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */
{
struct fpm_scoreboard_proc_s *proc;
- fpm_scoreboard = scoreboard;
- fpm_scoreboard_i = child_index;
- proc = fpm_scoreboard_proc_get(scoreboard, child_index);
+ fpm_scoreboard = child->wp->scoreboard;
+ fpm_scoreboard_i = child->scoreboard_i;
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return;
}
@@ -266,18 +278,22 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */
+void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */
{
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
+
if (!scoreboard) {
return;
}
- if (child_index < 0 || child_index >= scoreboard->nprocs) {
+ if (child_index < 0 || child_index >= wp->config->pm_max_children) {
return;
}
- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
+ if (scoreboard->procs[child_index].used > 0) {
+ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
}
/* set this slot as free to avoid search on next alloc */
@@ -285,41 +301,44 @@ void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_ind
}
/* }}} */
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */
{
int i = -1;
+ struct fpm_worker_pool_s *wp = child->wp;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int nprocs = wp->config->pm_max_children;
- if (!scoreboard || !child_index) {
+ if (!scoreboard) {
return -1;
}
/* first try the slot which is supposed to be free */
- if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) {
- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
+ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) {
+ if (!scoreboard->procs[scoreboard->free_proc].used) {
i = scoreboard->free_proc;
}
}
if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
- for (i = 0; i < scoreboard->nprocs; i++) {
- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
+ for (i = 0; i < nprocs; i++) {
+ if (!scoreboard->procs[i].used) { /* found */
break;
}
}
}
/* no free slot */
- if (i < 0 || i >= scoreboard->nprocs) {
+ if (i < 0 || i >= nprocs) {
zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
return -1;
}
- scoreboard->procs[i]->used = 1;
- *child_index = i;
+ scoreboard->procs[i].used = 1;
+ child->scoreboard_i = i;
/* supposed next slot is free */
- if (i + 1 >= scoreboard->nprocs) {
+ if (i + 1 >= nprocs) {
scoreboard->free_proc = 0;
} else {
scoreboard->free_proc = i + 1;
diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
index f58a287..a0cc093 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.h
+++ b/sapi/fpm/fpm/fpm_scoreboard.h
@@ -65,7 +65,7 @@ struct fpm_scoreboard_s {
unsigned int nprocs;
int free_proc;
unsigned long int slow_rq;
- struct fpm_scoreboard_proc_s *procs[];
+ struct fpm_scoreboard_proc_s procs[];
};
int fpm_scoreboard_init_main();
@@ -74,18 +74,19 @@ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_s *fpm_scoreboard_get();
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child);
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang);
void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard);
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang);
void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc);
-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard);
+void fpm_scoreboard_free(struct fpm_worker_pool_s *wp);
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid);
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid);
-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index);
-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index);
+void fpm_scoreboard_proc_free(struct fpm_child_s *child);
+int fpm_scoreboard_proc_alloc(struct fpm_child_s *child);
#ifdef HAVE_TIMES
float fpm_scoreboard_get_tick();
diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
index 3e82fac..666a1d9 100644
--- a/sapi/fpm/fpm/fpm_status.c
+++ b/sapi/fpm/fpm/fpm_status.c
@@ -402,10 +402,10 @@ int fpm_status_handle_request(void) /* {{{ */
first = 1;
for (i=0; i<scoreboard_p->nprocs; i++) {
- if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) {
+ if (!scoreboard_p->procs[i].used) {
continue;
}
- proc = *scoreboard_p->procs[i];
+ proc = scoreboard_p->procs[i];
if (first) {
first = 0;
diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c
index a002291..c778b33 100644
--- a/sapi/fpm/fpm/fpm_worker_pool.c
+++ b/sapi/fpm/fpm/fpm_worker_pool.c
@@ -44,7 +44,7 @@ static void fpm_worker_pool_cleanup(int which, void *arg) /* {{{ */
fpm_worker_pool_config_free(wp->config);
fpm_children_free(wp->children);
if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) {
- fpm_scoreboard_free(wp->scoreboard);
+ fpm_scoreboard_free(wp);
}
fpm_worker_pool_free(wp);
}

View File

@@ -0,0 +1,74 @@
--- src/Makefile 2018-06-26 00:46:36.000000000 +0700
+++ src/Makefile 2020-02-03 20:23:54.066910822 +0700
@@ -1,3 +1,4 @@
+
# Makefile for building Lua
# See ../doc/readme.html for installation and customization instructions.
@@ -7,7 +8,7 @@
PLAT= none
CC= gcc -std=gnu99
-CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
+CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) -fPIC
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
@@ -43,7 +43,8 @@
LUAC_O= luac.o
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
+LUA_SO= liblua.so
+ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
ALL_A= $(LUA_A)
# Targets start here.
@@ -59,6 +60,11 @@
$(AR) $@ $(BASE_O)
$(RANLIB) $@
+$(LUA_SO): $(CORE_O) $(LIB_O)
+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
+
$(LUA_T): $(LUA_O) $(LUA_A)
$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
--- Makefile 2016-12-20 23:26:08.000000000 +0700
+++ Makefile 2020-02-03 20:43:00.870910828 +0700
@@ -38,10 +38,14 @@
# Convenience platforms targets.
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
+# Lua version and release.
+V= 5.3
+R= $V.5
+
# What to install.
TO_BIN= lua luac
TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
-TO_LIB= liblua.a
+TO_LIB= liblua.a liblua.so.$(R)
TO_MAN= lua.1 luac.1
# Lua version and release.
@@ -52,7 +56,7 @@
all: $(PLAT)
$(PLATS) clean:
- cd src && $(MAKE) $@
+ cd src && $(MAKE) $@ V=$(V) R=$(R)
test: dummy
src/lua -v
@@ -63,6 +67,8 @@
cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+ ln -s $(INSTALL_LIB)/liblua.so.$(R) $(INSTALL_LIB)/liblua.so.$(V)
+ ln -s $(INSTALL_LIB)/liblua.so.$(R) $(INSTALL_LIB)/liblua.so
uninstall:
cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)

View File

@@ -0,0 +1,16 @@
--- libspf2-1.2.10/src/include/spf_log.h
+++ libspf2-1.2.10/src/include/spf_log.h 2015-10-20 23:23:04.579055906 +0200
@@ -60,10 +60,10 @@
#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-#define SPF_errorf(format, ... ) SPF_errorx( __FILE__, __LINE__, format, __VA_ARGS__ )
-#define SPF_warningf(format, ... ) SPF_warningx( __FILE__, __LINE__, format, __VA_ARGS__ )
-#define SPF_infof(format, ... ) SPF_infox( __FILE__, __LINE__, format, __VA_ARGS__ )
-#define SPF_debugf(format, ... ) SPF_debugx( __FILE__, __LINE__, format, __VA_ARGS__ )
+#define SPF_errorf(...) SPF_errorx( __FILE__, __LINE__, __VA_ARGS__ )
+#define SPF_warningf(...) SPF_warningx( __FILE__, __LINE__, __VA_ARGS__ )
+#define SPF_infof(...) SPF_infox( __FILE__, __LINE__, __VA_ARGS__ )
+#define SPF_debugf(...) SPF_debugx( __FILE__, __LINE__, __VA_ARGS__ )
#elif defined( __GNUC__ )

View File

@@ -0,0 +1,34 @@
diff --git a/src/util/maildirlock.c b/src/util/maildirlock.c
index 89fbacc3d..a6ebdc71b 100644
--- a/src/util/maildirlock.c
+++ b/src/util/maildirlock.c
@@ -34,6 +34,11 @@ static int maildir_lock(const char *path, unsigned int timeout,
return file_dotlock_create(&dotlock_settings, path, 0, dotlock_r);
}
+static void dummy_read(int *fd ATTR_UNUSED)
+{
+ /* this should never be reached anyways */
+}
+
int main(int argc, const char *argv[])
{
struct dotlock *dotlock;
@@ -91,12 +96,16 @@ int main(int argc, const char *argv[])
if (maildir_lock(argv[1], timeout, &dotlock) <= 0)
return 1;
+ struct io *io = io_add(fd[0], IO_READ, dummy_read, fd);
+
/* locked - send a byte */
if (write_full(fd[1], "", 1) < 0)
i_fatal("write(pipe) failed: %m");
io_loop_run(ioloop);
+ io_remove(&io);
+
file_dotlock_delete(&dotlock);
lib_signals_deinit();

View File

@@ -0,0 +1,15 @@
--- storage/rocksdb/rocksdb/port/jemalloc_helper.h.orig 2019-12-30 17:34:30.454412000 -0700
+++ storage/rocksdb/rocksdb/port/jemalloc_helper.h 2019-12-30 17:38:27.519320000 -0700
@@ -12,6 +12,12 @@
#include <jemalloc/jemalloc.h>
#endif
+#ifdef __FreeBSD__
+#ifndef JEMALLOC_USABLE_SIZE_CONST
+#define JEMALLOC_USABLE_SIZE_CONST const
+#endif
+#endif
+
#ifndef JEMALLOC_CXX_THROW
#define JEMALLOC_CXX_THROW
#endif

View File

@@ -0,0 +1,26 @@
--- mod_aclr2.c.unpatched 2015-05-12 20:12:32.687000116 +0200
+++ mod_aclr2.c 2015-05-13 10:23:09.215000116 +0200
@@ -147,6 +147,23 @@
real_uri += docroot_len;
}
+ if (!strncmp(real_uri, "/~", 2))
+ {
+ char *first = real_uri+1; //points to ~
+ //and then do the same thing for the shifting.
+ char *bbb = strchr(first, '/'); //points to 2nd /
+ if (bbb)
+ {
+ int size = strlen(bbb);
+ memmove(real_uri, bbb, size);
+ real_uri[size] = '\0'; //ensure string is null terminated.
+ }
+ else
+ {
+ real_uri[1] = '\0'; //stomp on the ~ making it "/"
+ }
+ }
+
snprintf(iredirect, sizeof(iredirect), "%s%s", idhead, real_uri);
aclr_debug(3, r->server, "trying to process request: %s%s -> %s",

View File

@@ -0,0 +1,30 @@
--- httpd-2.4.10/modules/generators/mod_suexec.c.old 2011-12-05 01:08:01.000000000 +0100
+++ httpd-2.4.10/modules/generators/mod_suexec.c 2014-09-11 00:16:21.444000009 +0200
@@ -59,7 +59,7 @@
const char *uid, const char *gid)
{
suexec_config_t *cfg = (suexec_config_t *) mconfig;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_LOCATION|NOT_IN_FILES);
if (err != NULL) {
return err;
@@ -116,7 +116,7 @@
{
/* XXX - Another important reason not to allow this in .htaccess is that
* the ap_[ug]name2id() is not thread-safe */
- AP_INIT_TAKE2("SuexecUserGroup", set_suexec_ugid, NULL, RSRC_CONF,
+ AP_INIT_TAKE2("SuexecUserGroup", set_suexec_ugid, NULL, RSRC_CONF|ACCESS_CONF,
"User and group for spawned processes"),
{ NULL }
};
--- httpd-2.4.10/support/suexec.c.old 2014-10-10 11:48:20.388000025 +0200
+++ httpd-2.4.10/support/suexec.c 2014-10-10 11:50:30.757000025 +0200
@@ -308,6 +308,7 @@
#ifdef AP_SUEXEC_UMASK
fprintf(stderr, " -D AP_SUEXEC_UMASK=%03o\n", AP_SUEXEC_UMASK);
#endif
+ fprintf(stderr, " -D AP_PER_DIR=\"yes\"\n");
#ifdef AP_UID_MIN
fprintf(stderr, " -D AP_UID_MIN=%d\n", AP_UID_MIN);
#endif

View File

@@ -0,0 +1,108 @@
diff --git a/apache2/msc_logging.c b/apache2/msc_logging.c
index 3323fac..ce8b069 100644
--- a/apache2/msc_logging.c
+++ b/apache2/msc_logging.c
@@ -225,10 +225,20 @@ static char *construct_auditlog_filename(apr_pool_t *mp, const char *uniqueid) {
char tstr[300];
apr_size_t len;
+ /**
+ * This is required for mpm-itk & mod_ruid2, though should be harmless for other implementations
+ * It also changes the return statement.
+ */
+ char *username;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ apr_uid_current(&uid, &gid, mp);
+ apr_uid_name_get(&username, uid, mp);
+
apr_time_exp_lt(&t, apr_time_now());
apr_strftime(tstr, &len, 299, "/%Y%m%d/%Y%m%d-%H%M/%Y%m%d-%H%M%S", &t);
- return apr_psprintf(mp, "%s-%s", tstr, uniqueid);
+ return apr_psprintf(mp, "/%s%s-%s", username, tstr, uniqueid);
}
/**
diff --git a/apache2/persist_dbm.c b/apache2/persist_dbm.c
index b698e79..8631ac9 100644
--- a/apache2/persist_dbm.c
+++ b/apache2/persist_dbm.c
@@ -101,6 +101,15 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
int expired = 0;
int i;
+ /**
+ * This is required for mpm-itk & mod_ruid2, though should be harmless for other implementations
+ */
+ char *username;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ apr_uid_current(&uid, &gid, msr->mp);
+ apr_uid_name_get(&username, uid, msr->mp);
+
if (msr->txcfg->data_dir == NULL) {
msr_log(msr, 1, "collection_retrieve_ex: Unable to retrieve collection (name \"%s\", key \"%s\"). Use "
"SecDataDir to define data directory first.", log_escape(msr->mp, col_name),
@@ -108,7 +117,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
goto cleanup;
}
- dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", col_name, NULL);
+ dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", username, "-", col_name, NULL);
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "collection_retrieve_ex: collection_retrieve_ex: Retrieving collection (name \"%s\", filename \"%s\")",log_escape(msr->mp, col_name),
@@ -336,6 +345,15 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
const apr_table_t *stored_col = NULL;
const apr_table_t *orig_col = NULL;
+ /**
+ * This is required for mpm-itk & mod_ruid2, though should be harmless for other implementations
+ */
+ char *username;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ apr_uid_current(&uid, &gid, msr->mp);
+ apr_uid_name_get(&username, uid, msr->mp);
+
var_name = (msc_string *)apr_table_get(col, "__name");
if (var_name == NULL) {
goto error;
@@ -354,7 +372,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
}
// ENH: lowercase the var name in the filename
- dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", var_name->value, NULL);
+ dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", username, "-", var_name->value, NULL);
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "collection_store: Retrieving collection (name \"%s\", filename \"%s\")",log_escape(msr->mp, var_name->value),
@@ -585,6 +603,15 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
apr_time_t now = apr_time_sec(msr->request_time);
int i;
+ /**
+ * This is required for mpm-itk & mod_ruid2, though should be harmless for other implementations
+ */
+ char *username;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ apr_uid_current(&uid, &gid, msr->mp);
+ apr_uid_name_get(&username, uid, msr->mp);
+
if (msr->txcfg->data_dir == NULL) {
/* The user has been warned about this problem enough times already by now.
* msr_log(msr, 1, "Unable to access collection file (name \"%s\"). Use SecDataDir to "
@@ -594,9 +621,9 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
}
if(strstr(col_name,"USER") || strstr(col_name,"SESSION") || strstr(col_name, "RESOURCE"))
- dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", msr->txcfg->webappid, "_", col_name, NULL);
+ dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", username, "-", msr->txcfg->webappid, "_", col_name, NULL);
else
- dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", col_name, NULL);
+ dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", username, "-", col_name, NULL);
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "collections_remove_stale: Retrieving collection (name \"%s\", filename \"%s\")",log_escape(msr->mp, col_name),

View File

@@ -0,0 +1,690 @@
diff --git a/Makefile.global b/Makefile.global
index 3a5b1c2..7450162 100644
--- a/Makefile.global
+++ b/Makefile.global
@@ -13,6 +13,8 @@ all: $(all_targets)
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
+build-binaries: $(PHP_BINARIES)
+
libphp$(PHP_MAJOR_VERSION).la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
@@ -35,6 +37,8 @@ install-sapi: $(OVERALL_TARGET)
fi
@$(INSTALL_IT)
+install-binaries: build-binaries $(install_binary_targets)
+
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
diff --git a/acinclude.m4 b/acinclude.m4
index 2681b79..605a9ba 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -194,7 +194,7 @@ dnl the path is interpreted relative to the top build-directory.
dnl
dnl which array to append to?
AC_DEFUN([PHP_ADD_SOURCES],[
- PHP_ADD_SOURCES_X($1, $2, $3, ifelse($4,cli,PHP_CLI_OBJS,ifelse($4,sapi,PHP_SAPI_OBJS,PHP_GLOBAL_OBJS)))
+ PHP_ADD_SOURCES_X($1, $2, $3, ifelse($4,sapi,PHP_SAPI_OBJS,PHP_GLOBAL_OBJS))
])
dnl
@@ -772,7 +772,7 @@ dnl
AC_DEFUN([PHP_BUILD_SHARED],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libphp[]$PHP_MAJOR_VERSION[.la]
- php_build_target=shared
+ php_sapi_module=shared
php_c_pre=$shared_c_pre
php_c_meta=$shared_c_meta
@@ -789,7 +789,7 @@ dnl
AC_DEFUN([PHP_BUILD_STATIC],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libphp[]$PHP_MAJOR_VERSION[.la]
- php_build_target=static
+ php_sapi_module=static
])
dnl
@@ -798,14 +798,13 @@ dnl
AC_DEFUN([PHP_BUILD_BUNDLE],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libs/libphp[]$PHP_MAJOR_VERSION[.bundle]
- php_build_target=static
+ php_sapi_module=static
])
dnl
dnl PHP_BUILD_PROGRAM
dnl
AC_DEFUN([PHP_BUILD_PROGRAM],[
- OVERALL_TARGET=[]ifelse($1,,php,$1)
php_c_pre='$(LIBTOOL) --mode=compile $(CC)'
php_c_meta='$(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS)'
php_c_post=
@@ -826,8 +825,6 @@ AC_DEFUN([PHP_BUILD_PROGRAM],[
shared_cxx_meta='$(COMMON_FLAGS) $(CXXFLAGS_CLEAN) $(EXTRA_CXXFLAGS) '$pic_setting
shared_cxx_post=
shared_lo=lo
-
- php_build_target=program
])
dnl
@@ -873,32 +870,46 @@ EOF
dnl
dnl PHP_SELECT_SAPI(name, type[, sources [, extra-cflags [, build-target]]])
dnl
-dnl Selects the SAPI name and type (static, shared, programm)
+dnl Selects the SAPI name and type (static, shared, bundle, program)
dnl and optionally also the source-files for the SAPI-specific
dnl objects.
dnl
AC_DEFUN([PHP_SELECT_SAPI],[
- if test "$PHP_SAPI" != "default"; then
-AC_MSG_ERROR([
+ if test "$2" = "program"; then
+ PHP_BINARIES="$PHP_BINARIES $1"
+ elif test "$PHP_SAPI" != "none"; then
+ AC_MSG_ERROR([
+--------------------------------------------------------------------+
| *** ATTENTION *** |
| |
| You've configured multiple SAPIs to be build. You can build only |
-| one SAPI module and CLI binary at the same time. |
+| one SAPI module plus CGI, CLI and FPM binaries at the same time. |
+--------------------------------------------------------------------+
])
+ else
+ PHP_SAPI=$1
fi
- PHP_SAPI=$1
-
+ PHP_ADD_BUILD_DIR([sapi/$1])
+
+ PHP_INSTALLED_SAPIS="$PHP_INSTALLED_SAPIS $1"
+
case "$2" in
static[)] PHP_BUILD_STATIC;;
shared[)] PHP_BUILD_SHARED;;
bundle[)] PHP_BUILD_BUNDLE;;
- program[)] PHP_BUILD_PROGRAM($5);;
+ program[)] PHP_BUILD_PROGRAM;;
esac
- ifelse($3,,,[PHP_ADD_SOURCES([sapi/$1],[$3],[$4],[sapi])])
+ ifelse($2,program,[
+ install_binaries="install-binaries"
+ install_binary_targets="$install_binary_targets install-$1"
+ PHP_SUBST(PHP_[]translit($1,a-z0-9-,A-Z0-9_)[]_OBJS)
+ ifelse($3,,,[PHP_ADD_SOURCES_X([sapi/$1],[$3],[$4],PHP_[]translit($1,a-z0-9-,A-Z0-9_)[]_OBJS)])
+ ],[
+ install_sapi="install-sapi"
+ ifelse($3,,,[PHP_ADD_SOURCES([sapi/$1],[$3],[$4],[sapi])])
+ ])
])
dnl deprecated
diff --git a/configure.in b/configure.in
index 183c3e3..fb69028 100644
--- a/configure.in
+++ b/configure.in
@@ -304,8 +304,8 @@ dnl -------------------------------------------------------------------------
PTHREADS_CHECK
PHP_HELP_SEPARATOR([SAPI modules:])
PHP_SHLIB_SUFFIX_NAMES
-PHP_SAPI=default
PHP_BUILD_PROGRAM
+PHP_SAPI=none
dnl SAPI configuration.
@@ -324,6 +324,20 @@ dnl Show which main SAPI was selected
AC_MSG_CHECKING([for chosen SAPI module])
AC_MSG_RESULT([$PHP_SAPI])
+dnl Show which binaries were selected
+AC_MSG_CHECKING([for executable SAPI binaries])
+if test "$PHP_BINARIES"; then
+ AC_MSG_RESULT([$PHP_BINARIES])
+else
+ AC_MSG_RESULT([none])
+fi
+
+dnl Exit early
+if test -z "$PHP_INSTALLED_SAPIS"; then
+ AC_MSG_ERROR([Nothing to build.])
+fi
+
+dnl force ZTS
if test "$enable_maintainer_zts" = "yes"; then
PTHREADS_ASSIGN_VARS
PTHREADS_FLAGS
@@ -965,14 +979,8 @@ dnl -------------------------------------------------------------------------
enable_shared=yes
enable_static=yes
-case $php_build_target in
- program|static)
- standard_libtool_flag='-prefer-non-pic -static'
- if test -z "$PHP_MODULES" && test -z "$PHP_ZEND_EX"; then
- enable_shared=no
- fi
- ;;
- shared)
+case $php_sapi_module in
+ shared[)]
enable_static=no
case $with_pic in
yes)
@@ -984,6 +992,12 @@ case $php_build_target in
esac
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -avoid-version -module"
;;
+ *[)]
+ standard_libtool_flag='-prefer-non-pic -static'
+ if test -z "$PHP_MODULES" && test -z "$PHP_ZEND_EX"; then
+ enable_shared=no
+ fi
+ ;;
esac
EXTRA_LIBS="$EXTRA_LIBS $DLIBS $LIBS"
@@ -1221,24 +1235,15 @@ case $host_alias in
;;
esac
-if test "$PHP_CLI" != "no"; then
- PHP_CLI_TARGET="\$(SAPI_CLI_PATH)"
- PHP_INSTALL_CLI_TARGET="install-cli"
- PHP_ADD_SOURCES(sapi/cli, php_cli.c php_cli_readline.c,, cli)
- PHP_INSTALLED_SAPIS="cli $PHP_SAPI"
- PHP_EXECUTABLE="\$(top_builddir)/\$(SAPI_CLI_PATH)"
-else
- PHP_INSTALLED_SAPIS="$PHP_SAPI"
-fi
-
PHP_SUBST_OLD(PHP_INSTALLED_SAPIS)
PHP_SUBST(PHP_EXECUTABLE)
-PHP_SUBST(PHP_CLI_TARGET)
+
PHP_SUBST(PHP_SAPI_OBJS)
-PHP_SUBST(PHP_CLI_OBJS)
+PHP_SUBST(PHP_BINARY_OBJS)
PHP_SUBST(PHP_GLOBAL_OBJS)
+PHP_SUBST(PHP_BINARIES)
PHP_SUBST(PHP_MODULES)
PHP_SUBST(PHP_ZEND_EX)
@@ -1382,20 +1387,12 @@ else
pharcmd_install=
fi;
-all_targets="$lcov_target \$(OVERALL_TARGET) \$(PHP_MODULES) \$(PHP_ZEND_EX) \$(PHP_CLI_TARGET) $pharcmd"
-install_targets="$install_modules install-build install-headers install-programs $install_pear $pharcmd_install"
-
-case $PHP_SAPI in
- cli)
- install_targets="$PHP_INSTALL_CLI_TARGET $install_targets"
- ;;
- *)
- install_targets="install-sapi $PHP_INSTALL_CLI_TARGET $install_targets"
- ;;
-esac
+all_targets="$lcov_target \$(OVERALL_TARGET) \$(PHP_MODULES) \$(PHP_ZEND_EX) \$(PHP_BINARIES) $pharcmd"
+install_targets="$install_sapi $install_modules $install_binaries install-build install-headers install-programs $install_pear $pharcmd_install"
PHP_SUBST(all_targets)
PHP_SUBST(install_targets)
+PHP_SUBST(install_binary_targets)
PHP_INSTALL_HEADERS([Zend/ TSRM/ include/ main/ main/streams/])
@@ -1420,7 +1417,7 @@ case $host_alias in
PHP_ADD_BUILD_DIR(netware)
;;
*)
- PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
+ PHP_ADD_SOURCES_X(/main, internal_functions_cli.c,, PHP_BINARY_OBJS)
;;
esac
@@ -1451,7 +1448,6 @@ fi
PHP_ADD_SOURCES_X(Zend, zend_execute.c,,PHP_GLOBAL_OBJS,,$flag)
PHP_ADD_BUILD_DIR(main main/streams)
-PHP_ADD_BUILD_DIR(sapi/$PHP_SAPI sapi/cli)
PHP_ADD_BUILD_DIR(TSRM)
PHP_ADD_BUILD_DIR(Zend)
diff --git a/sapi/cgi/Makefile.frag b/sapi/cgi/Makefile.frag
index 57a3b29..505119e 100644
--- a/sapi/cgi/Makefile.frag
+++ b/sapi/cgi/Makefile.frag
@@ -1,2 +1,9 @@
-$(SAPI_CGI_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
+cgi: $(SAPI_CGI_PATH)
+
+$(SAPI_CGI_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_CGI_OBJS)
$(BUILD_CGI)
+
+install-cgi: $(SAPI_CGI_PATH)
+ @echo "Installing PHP CGI binary: $(INSTALL_ROOT)$(bindir)/"
+ @$(INSTALL) -m 0755 $(SAPI_CGI_PATH) $(INSTALL_ROOT)$(bindir)/$(program_prefix)php-cgi$(program_suffix)$(EXEEXT)
+
diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4
index 9df454a..67251ae 100644
--- a/sapi/cgi/config9.m4
+++ b/sapi/cgi/config9.m4
@@ -8,11 +8,9 @@ PHP_ARG_ENABLE(cgi,,
dnl
dnl CGI setup
dnl
-if test "$PHP_SAPI" = "default"; then
- AC_MSG_CHECKING(whether to build CGI binary)
- if test "$PHP_CGI" != "no"; then
+AC_MSG_CHECKING(for CGI build)
+if test "$PHP_CGI" != "no"; then
AC_MSG_RESULT(yes)
-
AC_MSG_CHECKING([for socklen_t in sys/socket.h])
AC_EGREP_HEADER([socklen_t], [sys/socket.h],
[AC_MSG_RESULT([yes])
@@ -50,31 +48,29 @@ if test "$PHP_SAPI" = "default"; then
SAPI_CGI_PATH=sapi/cgi/php-cgi
;;
esac
- PHP_SUBST(SAPI_CGI_PATH)
- dnl Set install target and select SAPI
- INSTALL_IT="@echo \"Installing PHP CGI binary: \$(INSTALL_ROOT)\$(bindir)/\"; \$(INSTALL) -m 0755 \$(SAPI_CGI_PATH) \$(INSTALL_ROOT)\$(bindir)/\$(program_prefix)php-cgi\$(program_suffix)\$(EXEEXT)"
+ dnl Select SAPI
PHP_SELECT_SAPI(cgi, program, cgi_main.c fastcgi.c,, '$(SAPI_CGI_PATH)')
case $host_alias in
*aix*)
- BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
+ if test "$php_sapi_module" = "shared"; then
+ BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
+ else
+ BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
+ fi
;;
*darwin*)
- BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
+ BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
;;
*)
- BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
+ BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)"
;;
esac
+ dnl Expose to Makefile
+ PHP_SUBST(SAPI_CGI_PATH)
PHP_SUBST(BUILD_CGI)
-
- elif test "$PHP_CLI" != "no"; then
- AC_MSG_RESULT(no)
- OVERALL_TARGET=
- PHP_SAPI=cli
- else
- AC_MSG_ERROR([No SAPIs selected.])
- fi
+else
+ AC_MSG_RESULT(yes)
fi
diff --git a/sapi/cli/Makefile.frag b/sapi/cli/Makefile.frag
index 6903ca1..0afad4f 100644
--- a/sapi/cli/Makefile.frag
+++ b/sapi/cli/Makefile.frag
@@ -1,11 +1,12 @@
cli: $(SAPI_CLI_PATH)
-$(SAPI_CLI_PATH): $(PHP_GLOBAL_OBJS) $(PHP_CLI_OBJS)
+$(SAPI_CLI_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_CLI_OBJS)
$(BUILD_CLI)
install-cli: $(SAPI_CLI_PATH)
@echo "Installing PHP CLI binary: $(INSTALL_ROOT)$(bindir)/"
- @$(INSTALL_CLI)
+ @$(INSTALL) -m 0755 $(SAPI_CLI_PATH) $(INSTALL_ROOT)$(bindir)/$(program_prefix)php$(program_suffix)$(EXEEXT)
@echo "Installing PHP CLI man page: $(INSTALL_ROOT)$(mandir)/man1/"
@$(mkinstalldirs) $(INSTALL_ROOT)$(mandir)/man1
- @$(INSTALL_DATA) $(builddir)/php.1 $(INSTALL_ROOT)$(mandir)/man1/$(program_prefix)php$(program_suffix).1
+ @$(INSTALL_DATA) sapi/cli/php.1 $(INSTALL_ROOT)$(mandir)/man1/$(program_prefix)php$(program_suffix).1
+
diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4
index 1a6fdbf..0a0a660 100644
--- a/sapi/cli/config.m4
+++ b/sapi/cli/config.m4
@@ -8,32 +8,41 @@ PHP_ARG_ENABLE(cli,,
AC_MSG_CHECKING(for CLI build)
if test "$PHP_CLI" != "no"; then
- PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cli/Makefile.frag,$abs_srcdir/sapi/cli,sapi/cli)
+ PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cli/Makefile.frag)
+
+ dnl Set filename
SAPI_CLI_PATH=sapi/cli/php
- PHP_SUBST(SAPI_CLI_PATH)
+
+ dnl Select SAPI
+ PHP_SELECT_SAPI(cli, program, php_cli.c php_cli_readline.c,, '$(SAPI_CLI_PATH)')
case $host_alias in
*aix*)
- if test "$php_build_target" = "shared"; then
- BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
+ if test "$php_sapi_module" = "shared"; then
+ BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
else
- BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
+ BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
fi
;;
*darwin*)
- BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
+ BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
;;
*netware*)
- BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -Lnetware -lphp5lib -o \$(SAPI_CLI_PATH)"
+ BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -Lnetware -lphp5lib -o \$(SAPI_CLI_PATH)"
;;
*)
- BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
+ BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)"
;;
esac
- INSTALL_CLI="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(bindir); \$(INSTALL) -m 0755 \$(SAPI_CLI_PATH) \$(INSTALL_ROOT)\$(bindir)/\$(program_prefix)php\$(program_suffix)\$(EXEEXT)"
+ dnl Set executable for tests
+ PHP_EXECUTABLE="\$(top_builddir)/\$(SAPI_CLI_PATH)"
+ PHP_SUBST(PHP_EXECUTABLE)
+
+ dnl Expose to Makefile
+ PHP_SUBST(SAPI_CLI_PATH)
PHP_SUBST(BUILD_CLI)
- PHP_SUBST(INSTALL_CLI)
+
PHP_OUTPUT(sapi/cli/php.1)
fi
AC_MSG_RESULT($PHP_CLI)
diff --git a/sapi/fpm/Makefile.frag b/sapi/fpm/Makefile.frag
index c5cea7e..6ed9e4a 100644
--- a/sapi/fpm/Makefile.frag
+++ b/sapi/fpm/Makefile.frag
@@ -1,17 +1,9 @@
fpm: $(SAPI_FPM_PATH)
-$(builddir)/fpm:
- @mkdir -p $(builddir)/fpm
- @mkdir -p $(builddir)/fpm/events
-
-$(SAPI_FPM_PATH): $(builddir)/fpm $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(SAPI_EXTRA_DEPS)
+$(SAPI_FPM_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_FPM_OBJS)
$(BUILD_FPM)
-$(builddir)/fpm/fpm_conf.lo: $(builddir)/../../main/build-defs.h
-
-install-build: install-fpm
-
-install-fpm: install-sapi
+install-fpm: $(SAPI_FPM_PATH)
@echo "Installing PHP FPM binary: $(INSTALL_ROOT)$(sbindir)/"
@$(mkinstalldirs) $(INSTALL_ROOT)$(sbindir)
@$(mkinstalldirs) $(INSTALL_ROOT)$(localstatedir)/log
@@ -20,7 +12,6 @@ install-fpm: install-sapi
@echo "Installing PHP FPM config: $(INSTALL_ROOT)$(sysconfdir)/" && \
$(mkinstalldirs) $(INSTALL_ROOT)$(sysconfdir) || :
-
@$(INSTALL_DATA) sapi/fpm/php-fpm.conf $(INSTALL_ROOT)$(sysconfdir)/php-fpm.conf.default || :
@echo "Installing PHP FPM man page: $(INSTALL_ROOT)$(mandir)/man8/"
diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4
index 7687660..7a0955d 100644
--- a/sapi/fpm/config.m4
+++ b/sapi/fpm/config.m4
@@ -583,19 +583,21 @@ if test "$PHP_FPM" != "no"; then
AC_DEFINE_UNQUOTED(PHP_FPM_USER, "$php_fpm_user", [fpm user name])
AC_DEFINE_UNQUOTED(PHP_FPM_GROUP, "$php_fpm_group", [fpm group name])
+ PHP_ADD_BUILD_DIR(sapi/fpm/fpm)
PHP_OUTPUT(sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html)
- PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/fpm/Makefile.frag], [$abs_srcdir/sapi/fpm], [sapi/fpm])
+ PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/fpm/Makefile.frag])
SAPI_FPM_PATH=sapi/fpm/php-fpm
- PHP_SUBST(SAPI_FPM_PATH)
if test "$fpm_trace_type" && test -f "$abs_srcdir/sapi/fpm/fpm/fpm_trace_$fpm_trace_type.c"; then
PHP_FPM_TRACE_FILES="fpm/fpm_trace.c fpm/fpm_trace_$fpm_trace_type.c"
fi
PHP_FPM_CFLAGS="-I$abs_srcdir/sapi/fpm"
+
+ FPM_EXTRA_LIBS="$LIBEVENT_LIBS"
+ PHP_SUBST(FPM_EXTRA_LIBS)
- INSTALL_IT=":"
PHP_FPM_FILES="fpm/fastcgi.c \
fpm/fpm.c \
fpm/fpm_children.c \
@@ -631,17 +633,19 @@ if test "$PHP_FPM" != "no"; then
case $host_alias in
*aix*)
- BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
+ BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
;;
*darwin*)
- BUILD_FPM="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
+ BUILD_FPM="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
;;
*)
- BUILD_FPM="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(SAPI_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
+ BUILD_FPM="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)"
;;
esac
+ PHP_SUBST(SAPI_FPM_PATH)
PHP_SUBST(BUILD_FPM)
+
else
AC_MSG_RESULT(no)
fi
diff --git a/sapi/litespeed/Makefile.frag b/sapi/litespeed/Makefile.frag
index e1af2b9..99d0832 100644
--- a/sapi/litespeed/Makefile.frag
+++ b/sapi/litespeed/Makefile.frag
@@ -1,3 +1,9 @@
-$(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
+litespeed: $(SAPI_LITESPEED_PATH)
+
+$(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_LITESPEED_OBJS)
$(BUILD_LITESPEED)
+install-litespeed: $(SAPI_LITESPEED_PATH)
+ @echo "Installing PHP LitSpeed binary: $(INSTALL_ROOT)$(bindir)/"
+ @$(INSTALL) -m 0755 $(SAPI_LITESPEED_PATH) $(INSTALL_ROOT)$(bindir)/lsphp
+
diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4
index 2b9522a..268b9ae 100644
--- a/sapi/litespeed/config.m4
+++ b/sapi/litespeed/config.m4
@@ -10,22 +10,21 @@ PHP_ARG_WITH(litespeed,,
if test "$PHP_LITESPEED" != "no"; then
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/litespeed/Makefile.frag,$abs_srcdir/sapi/litespeed,sapi/litespeed)
SAPI_LITESPEED_PATH=sapi/litespeed/php
- PHP_SUBST(SAPI_LITESPEED_PATH)
PHP_SELECT_SAPI(litespeed, program, lsapi_main.c lsapilib.c, "", '$(SAPI_LITESPEED_PATH)')
- INSTALL_IT="@echo \"Installing PHP LiteSpeed into: \$(INSTALL_ROOT)\$(bindir)/\"; \$(INSTALL) -m 0755 \$(SAPI_LITESPEED_PATH) \$(INSTALL_ROOT)\$(bindir)/lsphp"
case $host_alias in
*darwin*)
- BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
+ BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
;;
*cygwin*)
SAPI_LITESPEED_PATH=sapi/litespeed/php.exe
- BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
+ BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
;;
*)
- BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
+ BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)"
;;
esac
+ PHP_SUBST(SAPI_LITESPEED_PATH)
PHP_SUBST(BUILD_LITESPEED)
fi
diff --git a/sapi/milter/Makefile.frag b/sapi/milter/Makefile.frag
index 8dbdf7a..26200a1 100644
--- a/sapi/milter/Makefile.frag
+++ b/sapi/milter/Makefile.frag
@@ -1,2 +1,8 @@
-$(SAPI_MILTER_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
+milter: $(SAPI_MILTER_PATH)
+
+$(SAPI_MILTER_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_SAPI_OBJS)
$(BUILD_MILTER)
+
+install-milter: $(SAPI_MILTER_PATH)
+ @$(INSTALL) -m 0755 $(SAPI_MILTER_PATH) $(bindir)/php-milter
+
diff --git a/sapi/milter/config.m4 b/sapi/milter/config.m4
index e314551..48c7a5d 100644
--- a/sapi/milter/config.m4
+++ b/sapi/milter/config.m4
@@ -25,8 +25,7 @@ if test "$PHP_MILTER" != "no"; then
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/milter/Makefile.frag)
PHP_SELECT_SAPI(milter, program, php_milter.c getopt.c,,'$(SAPI_MILTER_PATH)')
PHP_ADD_LIBRARY_WITH_PATH(milter, $MILTERPATH,)
- BUILD_MILTER="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_MILTER_PATH)"
- INSTALL_IT="\$(INSTALL) -m 0755 \$(SAPI_MILTER_PATH) \$(bindir)/php-milter"
+ BUILD_MILTER="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_MILTER_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_MILTER_PATH)"
PHP_SUBST(SAPI_MILTER_PATH)
PHP_SUBST(BUILD_MILTER)
fi
diff --git a/aclocal.m4 b/aclocal.m4
index 07b5e61..d114137 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -194,7 +194,7 @@ dnl the path is interpreted relative to the top build-directory.
dnl
dnl which array to append to?
AC_DEFUN([PHP_ADD_SOURCES],[
- PHP_ADD_SOURCES_X($1, $2, $3, ifelse($4,cli,PHP_CLI_OBJS,ifelse($4,sapi,PHP_SAPI_OBJS,PHP_GLOBAL_OBJS)))
+ PHP_ADD_SOURCES_X($1, $2, $3, ifelse($4,sapi,PHP_SAPI_OBJS,PHP_GLOBAL_OBJS))
])
dnl
@@ -772,7 +772,7 @@ dnl
AC_DEFUN([PHP_BUILD_SHARED],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libphp[]$PHP_MAJOR_VERSION[.la]
- php_build_target=shared
+ php_sapi_module=shared
php_c_pre=$shared_c_pre
php_c_meta=$shared_c_meta
@@ -789,7 +789,7 @@ dnl
AC_DEFUN([PHP_BUILD_STATIC],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libphp[]$PHP_MAJOR_VERSION[.la]
- php_build_target=static
+ php_sapi_module=static
])
dnl
@@ -798,14 +798,13 @@ dnl
AC_DEFUN([PHP_BUILD_BUNDLE],[
PHP_BUILD_PROGRAM
OVERALL_TARGET=libs/libphp[]$PHP_MAJOR_VERSION[.bundle]
- php_build_target=static
+ php_sapi_module=static
])
dnl
dnl PHP_BUILD_PROGRAM
dnl
AC_DEFUN([PHP_BUILD_PROGRAM],[
- OVERALL_TARGET=[]ifelse($1,,php,$1)
php_c_pre='$(LIBTOOL) --mode=compile $(CC)'
php_c_meta='$(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS)'
php_c_post=
@@ -826,8 +825,6 @@ AC_DEFUN([PHP_BUILD_PROGRAM],[
shared_cxx_meta='$(COMMON_FLAGS) $(CXXFLAGS_CLEAN) $(EXTRA_CXXFLAGS) '$pic_setting
shared_cxx_post=
shared_lo=lo
-
- php_build_target=program
])
dnl
@@ -873,32 +870,46 @@ EOF
dnl
dnl PHP_SELECT_SAPI(name, type[, sources [, extra-cflags [, build-target]]])
dnl
-dnl Selects the SAPI name and type (static, shared, programm)
+dnl Selects the SAPI name and type (static, shared, bundle, program)
dnl and optionally also the source-files for the SAPI-specific
dnl objects.
dnl
AC_DEFUN([PHP_SELECT_SAPI],[
- if test "$PHP_SAPI" != "default"; then
-AC_MSG_ERROR([
+ if test "$2" = "program"; then
+ PHP_BINARIES="$PHP_BINARIES $1"
+ elif test "$PHP_SAPI" != "none"; then
+ AC_MSG_ERROR([
+--------------------------------------------------------------------+
| *** ATTENTION *** |
| |
| You've configured multiple SAPIs to be build. You can build only |
-| one SAPI module and CLI binary at the same time. |
+| one SAPI module plus CGI, CLI and FPM binaries at the same time. |
+--------------------------------------------------------------------+
])
+ else
+ PHP_SAPI=$1
fi
- PHP_SAPI=$1
-
+ PHP_ADD_BUILD_DIR([sapi/$1])
+
+ PHP_INSTALLED_SAPIS="$PHP_INSTALLED_SAPIS $1"
+
case "$2" in
static[)] PHP_BUILD_STATIC;;
shared[)] PHP_BUILD_SHARED;;
bundle[)] PHP_BUILD_BUNDLE;;
- program[)] PHP_BUILD_PROGRAM($5);;
+ program[)] PHP_BUILD_PROGRAM;;
esac
- ifelse($3,,,[PHP_ADD_SOURCES([sapi/$1],[$3],[$4],[sapi])])
+ ifelse($2,program,[
+ install_binaries="install-binaries"
+ install_binary_targets="$install_binary_targets install-$1"
+ PHP_SUBST(PHP_[]translit($1,a-z0-9-,A-Z0-9_)[]_OBJS)
+ ifelse($3,,,[PHP_ADD_SOURCES_X([sapi/$1],[$3],[$4],PHP_[]translit($1,a-z0-9-,A-Z0-9_)[]_OBJS)])
+ ],[
+ install_sapi="install-sapi"
+ ifelse($3,,,[PHP_ADD_SOURCES([sapi/$1],[$3],[$4],[sapi])])
+ ])
])
dnl deprecated

View File

@@ -0,0 +1,34 @@
--- io_sendfile.c.orig 2019-09-26 02:01:16.604737373 +0200
+++ io_sendfile.c 2019-09-26 02:02:38.201732954 +0200
@@ -132,13 +132,7 @@
int
DoSendfileAvailable(void)
{
-#if defined(FREEBSD_SENDFILE) || defined(MACOSX_SENDFILE)
- return 1;
-#elif defined(LINUX) && (LINUX >= 22000)
return 1;
-#else
- return 0;
-#endif
} /* DoSendfileAvailable */
@@ -266,7 +260,7 @@
struct stat st;
#endif /* FREEBSD, MACOSX */
-#if defined(LINUX) && (LINUX >= 22000)
+#if defined(LINUX)
off_t off, off1;
#endif /* LINUX */
@@ -358,7 +352,7 @@
goto userspace_loop;
}
-#if defined(LINUX) && (LINUX >= 22000)
+#if defined(LINUX)
if ((tntoread == 0) && (fstat(ifd, &st) == 0)) {
tntoread = ntoread = st.st_size;
}

View File

@@ -0,0 +1,48 @@
--- a/sapi/fpm/fpm/fpm_main.c
+++ b/sapi/fpm/fpm/fpm_main.c
@@ -1143,19 +1143,6 @@ static void init_request_info(TSRMLS_D)
TRANSLATE_SLASHES(env_document_root);
}
- if (env_path_translated != NULL && env_redirect_url != NULL &&
- env_path_translated != script_path_translated &&
- strcmp(env_path_translated, script_path_translated) != 0) {
- /*
- * pretty much apache specific. If we have a redirect_url
- * then our script_filename and script_name point to the
- * php executable
- */
- script_path_translated = env_path_translated;
- /* we correct SCRIPT_NAME now in case we don't have PATH_INFO */
- env_script_name = env_redirect_url;
- }
-
#ifdef __riscos__
/* Convert path to unix format*/
__riscosify_control |= __RISCOSIFY_DONT_CHECK_DIR;
@@ -1324,7 +1311,7 @@ static void init_request_info(TSRMLS_D)
efree(pt);
}
} else {
- /* make sure path_info/translated are empty */
+ /* make sure original values are remembered in ORIG_ copies if we've changed them */
if (!orig_script_filename ||
(script_path_translated != orig_script_filename &&
strcmp(script_path_translated, orig_script_filename) != 0)) {
@@ -1333,16 +1320,6 @@ static void init_request_info(TSRMLS_D)
}
script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", script_path_translated TSRMLS_CC);
}
- if (env_redirect_url) {
- if (orig_path_info) {
- _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC);
- _sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC);
- }
- if (orig_path_translated) {
- _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC);
- _sapi_cgibin_putenv("PATH_TRANSLATED", NULL TSRMLS_CC);
- }
- }
if (env_script_name != orig_script_name) {
if (orig_script_name) {
_sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,630 @@
From 4f06e67ad2201390ed35a9ea6288a00c0b04782b Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Tue, 20 Nov 2018 20:54:24 +0100
Subject: [PATCH] Re-commit MySQL 8 cached SHA auth support
With changes to (hopefully) correctly fall back if OpenSSL support
is missing. Furthermore the hard-coded dependency on ext/hash is
no longer an issue, as this extension is required in master.
This reverts commit 63072e9c0ebbb676cd39d0f867d873737c676add, reversing
changes made to 4cbabb6852d2a7d966fb78a53d9d4c1cac18f10b.
---
ext/mysqlnd/mysqlnd_auth.c | 283 ++++++++++++++++++++++++++++-
ext/mysqlnd/mysqlnd_auth.h | 23 +--
ext/mysqlnd/mysqlnd_connection.c | 4 +
ext/mysqlnd/mysqlnd_enum_n_def.h | 1 +
ext/mysqlnd/mysqlnd_structs.h | 10 +
ext/mysqlnd/mysqlnd_wireprotocol.c | 90 ++++++++-
ext/mysqlnd/mysqlnd_wireprotocol.h | 10 +
7 files changed, 392 insertions(+), 29 deletions(-)
diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c
index e56ea2038081..fa04e1b83105 100644
--- a/ext/mysqlnd/mysqlnd_auth.c
+++ b/ext/mysqlnd/mysqlnd_auth.c
@@ -89,6 +89,7 @@ mysqlnd_run_authentication(
}
}
+
{
zend_uchar * switch_to_auth_protocol_data = NULL;
size_t switch_to_auth_protocol_data_len = 0;
@@ -113,10 +114,11 @@ mysqlnd_run_authentication(
DBG_INF_FMT("salt(%d)=[%.*s]", plugin_data_len, plugin_data_len, plugin_data);
/* The data should be allocated with malloc() */
if (auth_plugin) {
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, session_options,
- conn->protocol_frame_codec->data, mysql_flags);
+ scrambled_data = auth_plugin->methods.get_auth_data(
+ NULL, &scrambled_data_len, conn, user, passwd,
+ passwd_len, plugin_data, plugin_data_len,
+ session_options, conn->protocol_frame_codec->data,
+ mysql_flags);
}
if (conn->error_info->error_no) {
@@ -127,6 +129,7 @@ mysqlnd_run_authentication(
charset_no,
first_call,
requested_protocol,
+ auth_plugin, plugin_data, plugin_data_len,
scrambled_data, scrambled_data_len,
&switch_to_auth_protocol, &switch_to_auth_protocol_len,
&switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
@@ -244,6 +247,9 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
unsigned int server_charset_no,
zend_bool use_full_blown_auth_packet,
const char * const auth_protocol,
+ struct st_mysqlnd_authentication_plugin * auth_plugin,
+ const zend_uchar * const orig_auth_plugin_data,
+ const size_t orig_auth_plugin_data_len,
const zend_uchar * const auth_plugin_data,
const size_t auth_plugin_data_len,
char ** switch_to_auth_protocol,
@@ -313,6 +319,11 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
PACKET_FREE(&auth_packet);
}
+ if (auth_plugin && auth_plugin->methods.handle_server_response) {
+ auth_plugin->methods.handle_server_response(auth_plugin, conn,
+ orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len);
+ }
+
if (FAIL == PACKET_READ(conn, &auth_resp_packet) || auth_resp_packet.response_code >= 0xFE) {
if (auth_resp_packet.response_code == 0xFE) {
/* old authentication with new server !*/
@@ -596,7 +607,8 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin =
}
},
{/* methods */
- mysqlnd_native_auth_get_auth_data
+ mysqlnd_native_auth_get_auth_data,
+ NULL
}
};
@@ -645,7 +657,8 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin
}
},
{/* methods */
- mysqlnd_pam_auth_get_auth_data
+ mysqlnd_pam_auth_get_auth_data,
+ NULL
}
};
@@ -820,11 +833,266 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plu
}
},
{/* methods */
- mysqlnd_sha256_auth_get_auth_data
+ mysqlnd_sha256_auth_get_auth_data,
+ NULL
+ }
+};
+#endif
+
+/*************************************** CACHING SHA2 Password *******************************/
+#ifdef MYSQLND_HAVE_SSL
+
+#undef L64
+
+#include "ext/hash/php_hash.h"
+#include "ext/hash/php_hash_sha.h"
+
+#define SHA256_LENGTH 32
+
+/* {{{ php_mysqlnd_scramble_sha2 */
+void php_mysqlnd_scramble_sha2(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const password, const size_t password_len)
+{
+ PHP_SHA256_CTX context;
+ zend_uchar sha1[SHA256_LENGTH];
+ zend_uchar sha2[SHA256_LENGTH];
+
+ /* Phase 1: hash password */
+ PHP_SHA256Init(&context);
+ PHP_SHA256Update(&context, password, password_len);
+ PHP_SHA256Final(sha1, &context);
+
+ /* Phase 2: hash sha1 */
+ PHP_SHA256Init(&context);
+ PHP_SHA256Update(&context, (zend_uchar*)sha1, SHA256_LENGTH);
+ PHP_SHA256Final(sha2, &context);
+
+ /* Phase 3: hash scramble + sha2 */
+ PHP_SHA256Init(&context);
+ PHP_SHA256Update(&context, (zend_uchar*)sha2, SHA256_LENGTH);
+ PHP_SHA256Update(&context, scramble, SCRAMBLE_LENGTH);
+ PHP_SHA256Final(buffer, &context);
+
+ /* let's crypt buffer now */
+ php_mysqlnd_crypt(buffer, (const zend_uchar *)sha1, (const zend_uchar *)buffer, SHA256_LENGTH);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_native_auth_get_auth_data */
+static zend_uchar *
+mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
+ size_t * auth_data_len,
+ MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
+ const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+ const MYSQLND_SESSION_OPTIONS * const session_options,
+ const MYSQLND_PFC_DATA * const pfc_data,
+ zend_ulong mysql_flags
+ )
+{
+ zend_uchar * ret = NULL;
+ DBG_ENTER("mysqlnd_caching_sha2_get_auth_data");
+ DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data);
+ *auth_data_len = 0;
+
+ DBG_INF("First auth step: send hashed password");
+ /* copy scrambled pass*/
+ if (passwd && passwd_len) {
+ ret = malloc(SHA256_LENGTH + 1);
+ *auth_data_len = SHA256_LENGTH;
+ php_mysqlnd_scramble_sha2((zend_uchar*)ret, auth_plugin_data, (zend_uchar*)passwd, passwd_len);
+ ret[SHA256_LENGTH] = '\0';
+ DBG_INF_FMT("hash(%d)=[%.*s]", *auth_data_len, *auth_data_len, ret);
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+static RSA *
+mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
+{
+ RSA * ret = NULL;
+ const MYSQLND_PFC_DATA * const pfc_data = conn->protocol_frame_codec->data;
+ const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
+ pfc_data->sha256_server_public_key:
+ MYSQLND_G(sha256_server_public_key);
+ php_stream * stream;
+ DBG_ENTER("mysqlnd_cached_sha2_get_key");
+ DBG_INF_FMT("options_s256_pk=[%s] MYSQLND_G(sha256_server_public_key)=[%s]",
+ pfc_data->sha256_server_public_key? pfc_data->sha256_server_public_key:"n/a",
+ MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a");
+ if (!fname || fname[0] == '\0') {
+ MYSQLND_PACKET_CACHED_SHA2_RESULT req_packet;
+ MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE pk_resp_packet;
+
+ do {
+ DBG_INF("requesting the public key from the server");
+ conn->payload_decoder_factory->m.init_cached_sha2_result_packet(&req_packet);
+ conn->payload_decoder_factory->m.init_sha256_pk_request_response_packet(&pk_resp_packet);
+ req_packet.request = 1;
+
+ if (! PACKET_WRITE(conn, &req_packet)) {
+ DBG_ERR_FMT("Error while sending public key request packet");
+ php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid());
+ SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
+ break;
+ }
+ if (FAIL == PACKET_READ(conn, &pk_resp_packet) || NULL == pk_resp_packet.public_key) {
+ DBG_ERR_FMT("Error while receiving public key");
+ php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid());
+ SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
+ break;
+ }
+ DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
+ /* now extract the public key */
+ {
+ BIO * bio = BIO_new_mem_buf(pk_resp_packet.public_key, pk_resp_packet.public_key_len);
+ ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ } while (0);
+ PACKET_FREE(&req_packet);
+ PACKET_FREE(&pk_resp_packet);
+
+ DBG_INF_FMT("ret=%p", ret);
+ DBG_RETURN(ret);
+
+ SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
+ "caching_sha2_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key");
+ DBG_ERR("server_public_key is not set");
+ DBG_RETURN(NULL);
+ } else {
+ zend_string * key_str;
+ DBG_INF_FMT("Key in a file. [%s]", fname);
+ stream = php_stream_open_wrapper((char *) fname, "rb", REPORT_ERRORS, NULL);
+
+ if (stream) {
+ if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
+ BIO * bio = BIO_new_mem_buf(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
+ ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ DBG_INF("Successfully loaded");
+ DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
+ zend_string_release(key_str);
+ }
+ php_stream_close(stream);
+ }
+ }
+ DBG_RETURN(ret);
+
+}
+
+
+/* {{{ mysqlnd_caching_sha2_get_key */
+static size_t
+mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
+ const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+ unsigned char **crypted,
+ const char * const passwd,
+ const size_t passwd_len)
+{
+ static RSA *server_public_key;
+ server_public_key = mysqlnd_caching_sha2_get_key(conn);
+
+ DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key(");
+
+ if (server_public_key) {
+ int server_public_key_len;
+ char xor_str[passwd_len + 1];
+ memcpy(xor_str, passwd, passwd_len);
+ xor_str[passwd_len] = '\0';
+ mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len);
+
+ server_public_key_len = RSA_size(server_public_key);
+ /*
+ Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
+ RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
+ http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
+ */
+ if ((size_t) server_public_key_len - 41 <= passwd_len) {
+ /* password message is to long */
+ SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
+ DBG_ERR("password is too long");
+ DBG_RETURN(0);
+ }
+
+ *crypted = emalloc(server_public_key_len);
+ RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, *crypted, server_public_key, RSA_PKCS1_OAEP_PADDING);
+ DBG_RETURN(server_public_key_len);
+ }
+ DBG_RETURN(0);
+}
+/* }}} */
+
+/* {{{ mysqlnd_native_auth_get_auth_data */
+static void
+mysqlnd_caching_sha2_handle_server_response(struct st_mysqlnd_authentication_plugin *self,
+ MYSQLND_CONN_DATA * conn,
+ const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+ const char * const passwd,
+ const size_t passwd_len)
+{
+ DBG_ENTER("mysqlnd_caching_sha2_handle_server_response");
+ MYSQLND_PACKET_CACHED_SHA2_RESULT result_packet;
+ conn->payload_decoder_factory->m.init_cached_sha2_result_packet(&result_packet);
+
+ if (FAIL == PACKET_READ(conn, &result_packet)) {
+ DBG_VOID_RETURN;
+ }
+
+ switch (result_packet.response_code) {
+ case 3:
+ DBG_INF("fast path succeeded");
+ DBG_VOID_RETURN;
+ case 4:
+ if (conn->vio->data->ssl || conn->unix_socket.s) {
+ DBG_INF("fast path failed, doing full auth via SSL");
+ result_packet.password = (zend_uchar *)passwd;
+ result_packet.password_len = passwd_len + 1;
+ PACKET_WRITE(conn, &result_packet);
+ } else {
+ DBG_INF("fast path failed, doing full auth without SSL");
+ result_packet.password_len = mysqlnd_caching_sha2_get_and_use_key(conn, auth_plugin_data, auth_plugin_data_len, &result_packet.password, passwd, passwd_len);
+ PACKET_WRITE(conn, &result_packet);
+ efree(result_packet.password);
+ }
+ DBG_VOID_RETURN;
+ case 2:
+ // The server tried to send a key, which we didn't expect
+ // fall-through
+ default:
+ php_error_docref(NULL, E_WARNING, "Unexpected server respose while doing caching_sha2 auth: %i", result_packet.response_code);
+ }
+
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
+static struct st_mysqlnd_authentication_plugin mysqlnd_caching_sha2_auth_plugin =
+{
+ {
+ MYSQLND_PLUGIN_API_VERSION,
+ "auth_plugin_caching_sha2_password",
+ MYSQLND_VERSION_ID,
+ PHP_MYSQLND_VERSION,
+ "PHP License 3.01",
+ "Johannes Schlüter <johannes.schlueter@php.net>",
+ {
+ NULL, /* no statistics , will be filled later if there are some */
+ NULL, /* no statistics */
+ },
+ {
+ NULL /* plugin shutdown */
+ }
+ },
+ {/* methods */
+ mysqlnd_caching_sha2_get_auth_data,
+ mysqlnd_caching_sha2_handle_server_response
}
};
#endif
+
/* {{{ mysqlnd_register_builtin_authentication_plugins */
void
mysqlnd_register_builtin_authentication_plugins(void)
@@ -832,6 +1100,7 @@ mysqlnd_register_builtin_authentication_plugins(void)
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_native_auth_plugin);
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_pam_authentication_plugin);
#ifdef MYSQLND_HAVE_SSL
+ mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_caching_sha2_auth_plugin);
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_sha256_authentication_plugin);
#endif
}
diff --git a/ext/mysqlnd/mysqlnd_auth.h b/ext/mysqlnd/mysqlnd_auth.h
index 8fc369abca43..3ddb5a5f70fe 100644
--- a/ext/mysqlnd/mysqlnd_auth.h
+++ b/ext/mysqlnd/mysqlnd_auth.h
@@ -31,26 +31,9 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
unsigned int server_charset_no,
zend_bool use_full_blown_auth_packet,
const char * const auth_protocol,
- const zend_uchar * const auth_plugin_data,
- const size_t auth_plugin_data_len,
- char ** switch_to_auth_protocol,
- size_t * switch_to_auth_protocol_len,
- zend_uchar ** switch_to_auth_protocol_data,
- size_t * switch_to_auth_protocol_data_len
- );
-
-enum_func_status
-mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
- const char * const user,
- const char * const passwd,
- const size_t passwd_len,
- const char * const db,
- const size_t db_len,
- const MYSQLND_SESSION_OPTIONS * const session_options,
- zend_ulong mysql_flags,
- unsigned int server_charset_no,
- zend_bool use_full_blown_auth_packet,
- const char * const auth_protocol,
+ struct st_mysqlnd_authentication_plugin * auth_plugin,
+ const zend_uchar * const orig_auth_plugin_data,
+ const size_t orig_auth_plugin_data_len,
const zend_uchar * const auth_plugin_data,
const size_t auth_plugin_data_len,
char ** switch_to_auth_protocol,
diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c
index 826b47d7173d..8745cc4edc82 100644
--- a/ext/mysqlnd/mysqlnd_connection.c
+++ b/ext/mysqlnd/mysqlnd_connection.c
@@ -666,9 +666,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
{
const MYSQLND_CSTRING scheme = { transport.s, transport.l };
+ /* This will be overwritten below with a copy, but we can use it during authentication */
+ conn->unix_socket.s = (char *)socket_or_pipe.s;
if (FAIL == conn->m->connect_handshake(conn, &scheme, &username, &password, &database, mysql_flags)) {
+ conn->unix_socket.s = NULL;
goto err;
}
+ conn->unix_socket.s = NULL;
}
{
diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h
index 7630a0a98885..21b84ce71f92 100644
--- a/ext/mysqlnd/mysqlnd_enum_n_def.h
+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h
@@ -631,6 +631,7 @@ enum mysqlnd_packet_type
PROT_CHG_USER_RESP_PACKET,
PROT_SHA256_PK_REQUEST_PACKET,
PROT_SHA256_PK_REQUEST_RESPONSE_PACKET,
+ PROT_CACHED_SHA2_RESULT_PACKET,
PROT_LAST /* should always be last */
};
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index a7c892b48d75..858b6620089c 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -963,6 +963,7 @@ struct st_mysqlnd_packet_chg_user_resp;
struct st_mysqlnd_packet_auth_pam;
struct st_mysqlnd_packet_sha256_pk_request;
struct st_mysqlnd_packet_sha256_pk_request_response;
+struct st_mysqlnd_packet_cached_sha2_result;
typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_greet_packet)(struct st_mysqlnd_packet_greet *packet);
typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_auth_packet)(struct st_mysqlnd_packet_auth *packet);
@@ -979,6 +980,7 @@ typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_prepare_respo
typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_change_user_response_packet)(struct st_mysqlnd_packet_chg_user_resp *packet);
typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_packet)(struct st_mysqlnd_packet_sha256_pk_request *packet);
typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_response_packet)(struct st_mysqlnd_packet_sha256_pk_request_response *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_cached_sha2_result_packet)(struct st_mysqlnd_packet_cached_sha2_result *packet);
typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command)(
MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory,
@@ -1034,6 +1036,7 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory)
func_mysqlnd_protocol_payload_decoder_factory__init_change_user_response_packet init_change_user_response_packet;
func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_packet init_sha256_pk_request_packet;
func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_response_packet init_sha256_pk_request_response_packet;
+ func_mysqlnd_protocol_payload_decoder_factory__init_cached_sha2_result_packet init_cached_sha2_result_packet;
func_mysqlnd_protocol_payload_decoder_factory__send_command send_command;
func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response;
@@ -1331,11 +1334,18 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen
const MYSQLND_PFC_DATA * const pfc_data, zend_ulong mysql_flags
);
+typedef void (*func_auth_plugin__handle_server_response)(struct st_mysqlnd_authentication_plugin * self,
+ MYSQLND_CONN_DATA * conn,
+ const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+ const char * const passwd,
+ const size_t passwd_len);
+
struct st_mysqlnd_authentication_plugin
{
struct st_mysqlnd_plugin_header plugin_header;
struct {
func_auth_plugin__get_auth_data get_auth_data;
+ func_auth_plugin__handle_server_response handle_server_response;
} methods;
};
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index 15b64d9f6de2..1b7f4a935e10 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -2123,6 +2123,75 @@ php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet)
}
/* }}} */
+static
+size_t php_mysqlnd_cached_sha2_result_write(MYSQLND_CONN_DATA * conn, void * _packet)
+{
+ MYSQLND_PACKET_CACHED_SHA2_RESULT * packet= (MYSQLND_PACKET_CACHED_SHA2_RESULT *) _packet;
+ MYSQLND_ERROR_INFO * error_info = conn->error_info;
+ MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+ MYSQLND_VIO * vio = conn->vio;
+ MYSQLND_STATS * stats = conn->stats;
+#if HAVE_COMPILER_C99_VLA
+ zend_uchar buffer[MYSQLND_HEADER_SIZE + packet->password_len + 1];
+#else
+ ALLOCA_FLAG(use_heap)
+ zend_uchar *buffer = do_alloca(MYSQLND_HEADER_SIZE + packet->password_len + 1, use_heap);
+#endif
+ size_t sent;
+
+ DBG_ENTER("php_mysqlnd_cached_sha2_result_write");
+
+ if (packet->request == 1) {
+ int1store(buffer + MYSQLND_HEADER_SIZE, '\2');
+ sent = pfc->data->m.send(pfc, vio, buffer, 1, stats, error_info);
+ } else {
+ memcpy(buffer + MYSQLND_HEADER_SIZE, packet->password, packet->password_len);
+ sent = pfc->data->m.send(pfc, vio, buffer, packet->password_len, stats, error_info);
+ }
+
+#if !HAVE_COMPILER_C99_VLA
+ free_alloca(buffer, use_heap);
+#endif
+
+ DBG_RETURN(sent);
+}
+
+static enum_func_status
+php_mysqlnd_cached_sha2_result_read(MYSQLND_CONN_DATA * conn, void * _packet)
+{
+ MYSQLND_PACKET_CACHED_SHA2_RESULT * packet= (MYSQLND_PACKET_CACHED_SHA2_RESULT *) _packet;
+ MYSQLND_ERROR_INFO * error_info = conn->error_info;
+ MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+ MYSQLND_VIO * vio = conn->vio;
+ MYSQLND_STATS * stats = conn->stats;
+ MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
+ zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE];
+ zend_uchar *p = buf;
+ const zend_uchar * const begin = buf;
+
+ DBG_ENTER("php_mysqlnd_cached_sha2_result_read");
+ if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), pfc, vio, stats, error_info, connection_state, buf, sizeof(buf), "PROT_CACHED_SHA2_RESULT_PACKET", PROT_CACHED_SHA2_RESULT_PACKET)) {
+ DBG_RETURN(FAIL);
+ }
+ BAIL_IF_NO_MORE_DATA;
+
+ p++;
+ packet->response_code = uint1korr(p);
+ BAIL_IF_NO_MORE_DATA;
+
+ p++;
+ packet->result = uint1korr(p);
+ BAIL_IF_NO_MORE_DATA;
+
+ DBG_RETURN(PASS);
+
+premature_end:
+ DBG_ERR_FMT("OK packet %d bytes shorter than expected", p - begin - packet->header.size);
+ php_error_docref(NULL, E_WARNING, "SHA256_PK_REQUEST_RESPONSE packet "MYSQLND_SZ_T_SPEC" bytes shorter than expected",
+ p - begin - packet->header.size);
+ DBG_RETURN(FAIL);
+}
+
/* {{{ packet_methods */
static
mysqlnd_packet_methods packet_methods[PROT_LAST] =
@@ -2201,9 +2270,14 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
php_mysqlnd_sha256_pk_request_response_read,
NULL, /* write */
php_mysqlnd_sha256_pk_request_response_free_mem,
- } /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */
+ }, /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */
+ {
+ php_mysqlnd_cached_sha2_result_read,
+ php_mysqlnd_cached_sha2_result_write,
+ NULL
+ } /* PROT_CACHED_SHA2_RESULT_PACKET */
};
-/* }}} */
+/* }}} */
/* {{{ mysqlnd_protocol::init_greet_packet */
@@ -2385,6 +2459,17 @@ MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_response_packet)(struct
}
/* }}} */
+/* {{{ mysqlnd_protocol::init_cached_sha2_result_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_cached_sha2_result_packet)(struct st_mysqlnd_packet_cached_sha2_result *packet)
+{
+ DBG_ENTER("mysqlnd_protocol::init_cached_sha2_result_packet");
+ memset(packet, 0, sizeof(*packet));
+ packet->header.m = &packet_methods[PROT_CACHED_SHA2_RESULT_PACKET];
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
/* {{{ mysqlnd_protocol::send_command */
static enum_func_status
@@ -2603,6 +2688,7 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_protocol_payload_decoder_factory)
MYSQLND_METHOD(mysqlnd_protocol, init_change_user_response_packet),
MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_packet),
MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_response_packet),
+ MYSQLND_METHOD(mysqlnd_protocol, init_cached_sha2_result_packet),
MYSQLND_METHOD(mysqlnd_protocol, send_command),
MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_response),
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h
index 6e531b0e5438..7dfb256eec41 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.h
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.h
@@ -281,6 +281,16 @@ typedef struct st_mysqlnd_packet_sha256_pk_request_response {
size_t public_key_len;
} MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
+typedef struct st_mysqlnd_packet_cached_sha2_result {
+ MYSQLND_PACKET_HEADER header;
+ uint8_t response_code;
+ uint8_t result;
+ uint8_t request;
+ zend_uchar * password;
+ size_t password_len;
+} MYSQLND_PACKET_CACHED_SHA2_RESULT;
+
+
zend_ulong php_mysqlnd_net_field_length(const zend_uchar **packet);
zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length);

View File

@@ -0,0 +1,88 @@
diff -ruN libraries.orig/common.inc.php libraries/common.inc.php
--- libraries.orig/common.inc.php 2017-03-29 07:15:31.000000000 -0500
+++ libraries/common.inc.php 2017-04-08 19:13:32.936610526 -0500
@@ -649,6 +649,9 @@
$auth_plugin = new $fqnAuthClass($plugin_manager);
if (! $auth_plugin->authCheck()) {
+ //DA logging
+ Logging::log_to_file('', "not authenticated");
+
/* Force generating of new session on login */
PMA_secureSession();
$auth_plugin->auth();
diff -ruN libraries.orig/Logging.php libraries/Logging.php
--- libraries.orig/Logging.php 2017-03-29 07:15:31.000000000 -0500
+++ libraries/Logging.php 2017-04-08 19:14:21.119610531 -0500
@@ -9,6 +9,9 @@
*/
namespace PMA\libraries;
+define("PMA\libraries\AUTH_LOG_DIR", "./log");
+define("PMA\libraries\AUTH_LOG_FILE", "./log/auth.log");
+
/**
* Misc logging functions
*
@@ -39,5 +42,61 @@
);
closelog();
}
+ Logging::log_to_file($user, $status);
}
+
+ private static function ensure_log_dir()
+ {
+ $LOG_DIR=AUTH_LOG_DIR;
+ if (is_dir($LOG_DIR))
+ return true;
+
+ if (!mkdir($LOG_DIR, 0770))
+ return false;
+ }
+
+ public static function log_to_file($user, $status)
+ {
+ if (!Logging::ensure_log_dir())
+ return false;
+
+ $LOG_FILE=AUTH_LOG_FILE;
+
+ if ($user == '')
+ {
+ $user = PMA_getenv('PHP_AUTH_USER');
+ }
+
+ if ($user == '')
+ return true;
+
+ //remove any ' characters from $user
+ $user = urlencode($user);
+
+ //check for logout
+ if ($status == 'not authenticated')
+ {
+ if (isset($_GET['old_usr']) && isset($_SERVER['PHP_AUTH_USER']))
+ {
+ if ($_GET['old_usr'] == $_SERVER['PHP_AUTH_USER'])
+ {
+ $status = 'logout';
+ }
+ }
+ }
+
+ $log_str = date('M d H:i:s').":: pma auth user='$user' status='$status' ip='".$_SERVER["REMOTE_ADDR"]."'";
+
+ $fp = fopen($LOG_FILE, 'a');
+ if ($fp === false)
+ {
+ //log to apache error log instead
+ error_log($log_str."\n");
+ return;
+ }
+
+ fwrite($fp, $log_str."\n");
+
+ fclose($fp);
+ }
}

View File

@@ -0,0 +1,14 @@
--- libraries/classes/Logging.php.orig 2018-04-15 18:54:36.973996388 -0600
+++ libraries/classes/Logging.php 2018-04-15 19:03:09.094996350 -0600
@@ -51,9 +51,9 @@
public static function getLogMessage($user, $status)
{
if ($status == 'ok') {
- return 'user authenticated: ' . $user . ' from ' . Core::getIp();
+ return "user authenticated: '" . $user . "' from '" . Core::getIp() ."'";
}
- return 'user denied: ' . $user . ' (' . $status . ') from ' . Core::getIp();
+ return "user denied: '" . $user . "' (" . $status . ") from '" . Core::getIp() ."'";
}
/**

View File

@@ -0,0 +1,89 @@
diff -rupN libraries.orig/common.inc.php libraries/common.inc.php
--- libraries.orig/common.inc.php 2016-03-22 21:46:31.452912951 -0500
+++ libraries/common.inc.php 2016-03-22 21:40:11.699913468 -0500
@@ -728,6 +728,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
$auth_plugin = new $fqnAuthClass($plugin_manager);
if (! $auth_plugin->authCheck()) {
+ //DA logging
+ log_to_file('', "not authenticated");
+
/* Force generating of new session on login */
if ($token_provided) {
PMA_secureSession();
diff -rupN libraries.orig/logging.lib.php libraries/logging.lib.php
--- libraries.orig/logging.lib.php 2016-03-22 21:46:31.455912989 -0500
+++ libraries/logging.lib.php 2016-03-22 21:39:56.640914141 -0500
@@ -8,6 +8,64 @@
* @package PhpMyAdmin
*/
+define("AUTH_LOG_DIR", "./log");
+define("AUTH_LOG_FILE", "./log/auth.log");
+
+function ensure_log_dir()
+{
+ $LOG_DIR=AUTH_LOG_DIR;
+ if (is_dir($LOG_DIR))
+ return true;
+
+ if (!mkdir($LOG_DIR, 0770))
+ return false;
+}
+
+function log_to_file($user, $status)
+{
+ if (!ensure_log_dir())
+ return false;
+
+ $LOG_FILE=AUTH_LOG_FILE;
+
+ if ($user == '')
+ {
+ $user = PMA_getenv('PHP_AUTH_USER');
+ }
+
+ if ($user == '')
+ return true;
+
+ //remove any ' characters from $user
+ $user = urlencode($user);
+
+ //check for logout
+ if ($status == 'not authenticated')
+ {
+ if (isset($_GET['old_usr']) && isset($_SERVER['PHP_AUTH_USER']))
+ {
+ if ($_GET['old_usr'] == $_SERVER['PHP_AUTH_USER'])
+ {
+ $status = 'logout';
+ }
+ }
+ }
+
+ $log_str = date('M d H:i:s').":: pma auth user='$user' status='$status' ip='".$_SERVER["REMOTE_ADDR"]."'";
+
+ $fp = fopen($LOG_FILE, 'a');
+ if ($fp === false)
+ {
+ //log to apache error log instead
+ error_log($log_str."\n");
+ return;
+ }
+
+ fwrite($fp, $log_str."\n");
+
+ fclose($fp);
+}
+
/**
* Logs user information to webserver logs.
*
@@ -22,5 +80,7 @@ function PMA_logUser($user, $status = 'o
apache_note('userID', $user);
apache_note('userStatus', $status);
}
+
+ log_to_file($user, $status);
}

View File

@@ -0,0 +1,81 @@
diff -rupN libraries.orig/common.inc.php libraries/common.inc.php
--- libraries.orig/common.inc.php 2014-12-10 01:51:22.838996733 -0700
+++ libraries/common.inc.php 2014-12-10 01:53:35.109996605 -0700
@@ -869,6 +869,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
$auth_plugin = new $auth_class($plugin_manager);
if (! $auth_plugin->authCheck()) {
+ //DA logging
+ log_to_file('', "not authenticated");
+
/* Force generating of new session on login */
PMA_secureSession();
$auth_plugin->auth();
diff -rupN libraries.orig/logging.lib.php libraries/logging.lib.php
--- libraries.orig/logging.lib.php 2014-12-10 01:51:22.830996865 -0700
+++ libraries/logging.lib.php 2014-12-10 01:57:20.972996510 -0700
@@ -11,6 +11,55 @@ if (! defined('PHPMYADMIN')) {
exit;
}
+$LOG_DIR="./log";
+$LOG_FILE=$LOG_DIR."/auth.log";
+
+function ensure_log_dir()
+{
+ global $LOG_DIR;
+ if (is_dir($LOG_DIR))
+ return true;
+
+ if (!mkdir($LOG_DIR, 0770))
+ return false;
+}
+
+function log_to_file($user, $status)
+{
+ if (!ensure_log_dir())
+ return false;
+
+ global $LOG_FILE;
+
+ if ($user == '')
+ {
+ //global $PHP_AUTH_USER;
+ //$user = $PHP_AUTH_USER;
+
+ $user = PMA_getenv('PHP_AUTH_USER');
+ }
+
+ if ($user == '')
+ return true;
+
+ //remove any ' characters from $user
+ $user = urlencode($user);
+
+ $log_str = date('M d H:i:s').":: pma auth user='$user' status='$status' ip='".$_SERVER["REMOTE_ADDR"]."'";
+
+ $fp = fopen($LOG_FILE, 'a');
+ if ($fp === false)
+ {
+ //log to apache error log instead
+ error_log($log_str."\n");
+ return;
+ }
+
+ fwrite($fp, $log_str."\n");
+
+ fclose($fp);
+}
+
/**
* Logs user information to webserver logs.
*
@@ -25,6 +74,8 @@ function PMA_logUser($user, $status = 'o
apache_note('userID', $user);
apache_note('userStatus', $status);
}
+
+ log_to_file($user, $status);
}
?>

View File

@@ -0,0 +1,93 @@
diff -rupN libraries.orig/common.inc.php libraries/common.inc.php
--- libraries.orig/common.inc.php 2015-01-30 01:21:34.332632729 -0700
+++ libraries/common.inc.php 2015-01-30 01:19:23.856881237 -0700
@@ -868,6 +868,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
$auth_plugin = new $auth_class($plugin_manager);
if (! $auth_plugin->authCheck()) {
+ //DA logging
+ log_to_file('', "not authenticated");
+
/* Force generating of new session on login */
PMA_secureSession();
$auth_plugin->auth();
diff -rupN libraries.orig/logging.lib.php libraries/logging.lib.php
--- libraries.orig/logging.lib.php 2015-01-30 01:21:34.319651116 -0700
+++ libraries/logging.lib.php 2015-01-30 01:25:48.566652817 -0700
@@ -11,6 +11,67 @@ if (! defined('PHPMYADMIN')) {
exit;
}
+$LOG_DIR="./log";
+$LOG_FILE=$LOG_DIR."/auth.log";
+
+function ensure_log_dir()
+{
+ global $LOG_DIR;
+ if (is_dir($LOG_DIR))
+ return true;
+
+ if (!mkdir($LOG_DIR, 0770))
+ return false;
+}
+
+function log_to_file($user, $status)
+{
+ if (!ensure_log_dir())
+ return false;
+
+ global $LOG_FILE;
+
+ if ($user == '')
+ {
+ //global $PHP_AUTH_USER;
+ //$user = $PHP_AUTH_USER;
+
+ $user = PMA_getenv('PHP_AUTH_USER');
+ }
+
+ if ($user == '')
+ return true;
+
+ //remove any ' characters from $user
+ $user = urlencode($user);
+
+ //check for logout
+ if ($status == 'not authenticated')
+ {
+ if (isset($_GET['old_usr']) && isset($_SERVER['PHP_AUTH_USER']))
+ {
+ if ($_GET['old_usr'] == $_SERVER['PHP_AUTH_USER'])
+ {
+ $status = 'logout';
+ }
+ }
+ }
+
+ $log_str = date('M d H:i:s').":: pma auth user='$user' status='$status' ip='".$_SERVER["REMOTE_ADDR"]."'";
+
+ $fp = fopen($LOG_FILE, 'a');
+ if ($fp === false)
+ {
+ //log to apache error log instead
+ error_log($log_str."\n");
+ return;
+ }
+
+ fwrite($fp, $log_str."\n");
+
+ fclose($fp);
+}
+
/**
* Logs user information to webserver logs.
*
@@ -25,6 +86,8 @@ function PMA_logUser($user, $status = 'o
apache_note('userID', $user);
apache_note('userStatus', $status);
}
+
+ log_to_file($user, $status);
}
?>

View File

@@ -0,0 +1,89 @@
diff -rupN libraries.orig/common.inc.php libraries/common.inc.php
--- libraries.orig/common.inc.php 2016-03-22 21:46:31.452912951 -0500
+++ libraries/common.inc.php 2016-03-22 21:40:11.699913468 -0500
@@ -728,6 +728,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
$auth_plugin = new $fqnAuthClass($plugin_manager);
if (! $auth_plugin->authCheck()) {
+ //DA logging
+ log_to_file('', "not authenticated");
+
/* Force generating of new session on login */
if ($token_provided) {
PMA_secureSession();
diff -rupN libraries.orig/logging.lib.php libraries/logging.lib.php
--- libraries.orig/logging.lib.php 2016-03-22 21:46:31.455912989 -0500
+++ libraries/logging.lib.php 2016-03-22 21:39:56.640914141 -0500
@@ -8,6 +8,64 @@
* @package PhpMyAdmin
*/
+define("AUTH_LOG_DIR", "./log");
+define("AUTH_LOG_FILE", "./log/auth.log");
+
+function ensure_log_dir()
+{
+ $LOG_DIR=AUTH_LOG_DIR;
+ if (is_dir($LOG_DIR))
+ return true;
+
+ if (!mkdir($LOG_DIR, 0770))
+ return false;
+}
+
+function log_to_file($user, $status)
+{
+ if (!ensure_log_dir())
+ return false;
+
+ $LOG_FILE=AUTH_LOG_FILE;
+
+ if ($user == '')
+ {
+ $user = PMA_getenv('PHP_AUTH_USER');
+ }
+
+ if ($user == '')
+ return true;
+
+ //remove any ' characters from $user
+ $user = urlencode($user);
+
+ //check for logout
+ if ($status == 'not authenticated')
+ {
+ if (isset($_GET['old_usr']) && isset($_SERVER['PHP_AUTH_USER']))
+ {
+ if ($_GET['old_usr'] == $_SERVER['PHP_AUTH_USER'])
+ {
+ $status = 'logout';
+ }
+ }
+ }
+
+ $log_str = date('M d H:i:s').":: pma auth user='$user' status='$status' ip='".$_SERVER["REMOTE_ADDR"]."'";
+
+ $fp = fopen($LOG_FILE, 'a');
+ if ($fp === false)
+ {
+ //log to apache error log instead
+ error_log($log_str."\n");
+ return;
+ }
+
+ fwrite($fp, $log_str."\n");
+
+ fclose($fp);
+}
+
/**
* Logs user information to webserver logs.
*
@@ -22,5 +80,7 @@ function PMA_logUser($user, $status = 'o
apache_note('userID', $user);
apache_note('userStatus', $status);
}
+
+ log_to_file($user, $status);
}

View File

@@ -0,0 +1,973 @@
diff --git a/src/support.c b/src/support.c
index 45d2126de..293dc7231 100644
--- a/src/support.c
+++ b/src/support.c
@@ -2,7 +2,7 @@
* ProFTPD - FTP server daemon
* Copyright (c) 1997, 1998 Public Flood Software
* Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
- * Copyright (c) 2001-2016 The ProFTPD Project team
+ * Copyright (c) 2001-2017 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -440,6 +440,9 @@ int dir_readlink(pool *p, const char *path, char *buf, size_t bufsz,
return -1;
}
+ pr_trace_msg("fsio", 9,
+ "dir_readlink() read link '%.*s' for path '%s'", (int) len, buf, path);
+
if (len == 0 ||
(size_t) len == bufsz) {
/* If we read nothing in, OR if the given buffer was completely
@@ -530,15 +533,24 @@ int dir_readlink(pool *p, const char *path, char *buf, size_t bufsz,
*/
ptr = strrchr(path, '/');
- if (ptr != NULL &&
- ptr != path) {
- char *parent_dir;
+ if (ptr != NULL) {
+ if (ptr != path) {
+ char *parent_dir;
- parent_dir = pstrndup(tmp_pool, path, (ptr - path));
- dst_path = pdircat(tmp_pool, parent_dir, dst_path, NULL);
+ parent_dir = pstrndup(tmp_pool, path, (ptr - path));
+ dst_path = pdircat(tmp_pool, parent_dir, dst_path, NULL);
- } else {
- dst_path = pdircat(tmp_pool, path, dst_path, NULL);
+ } else {
+ /* Watch out for the case where the destination path might start
+ * with a period.
+ */
+ if (*dst_path != '.') {
+ dst_path = pdircat(tmp_pool, path, dst_path, NULL);
+
+ } else {
+ dst_path = pdircat(tmp_pool, "/", dst_path, NULL);
+ }
+ }
}
}
diff --git a/tests/api/misc.c b/tests/api/misc.c
index 926d9b3e3..122463681 100644
--- a/tests/api/misc.c
+++ b/tests/api/misc.c
@@ -1,6 +1,6 @@
/*
* ProFTPD - FTP server testsuite
- * Copyright (c) 2015-2016 The ProFTPD Project team
+ * Copyright (c) 2015-2017 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -533,6 +533,28 @@ START_TEST (dir_readlink_test) {
fail_unless(strcmp(buf, expected_path) == 0, "Expected '%s', got '%s'",
expected_path, buf);
+ /* Now use a relative path that does not start with '.' */
+ memset(buf, '\0', bufsz);
+ dst_path = "file.txt";
+ dst_pathlen = strlen(dst_path);
+ expected_path = "./file.txt";
+ expected_pathlen = strlen(expected_path);
+
+ (void) unlink(path);
+ res = symlink(dst_path, path);
+ fail_unless(res == 0, "Failed to symlink '%s' to '%s': %s", path, dst_path,
+ strerror(errno));
+
+ session.chroot_path = "/tmp";
+ flags = PR_DIR_READLINK_FL_HANDLE_REL_PATH;
+ res = dir_readlink(p, path, buf, bufsz, flags);
+ fail_if(res < 0, "Failed to read '%s' symlink: %s", path, strerror(errno));
+ fail_unless((size_t) res == expected_pathlen,
+ "Expected length %lu, got %d (%s)", (unsigned long) expected_pathlen, res,
+ buf);
+ fail_unless(strcmp(buf, expected_path) == 0, "Expected '%s', got '%s'",
+ expected_path, buf);
+
(void) unlink(misc_test_readlink);
}
END_TEST
diff --git a/tests/t/lib/ProFTPD/Tests/Commands/LIST.pm b/tests/t/lib/ProFTPD/Tests/Commands/LIST.pm
index 5528a2542..63e93691c 100644
--- a/tests/t/lib/ProFTPD/Tests/Commands/LIST.pm
+++ b/tests/t/lib/ProFTPD/Tests/Commands/LIST.pm
@@ -218,6 +218,21 @@ my $TESTS = {
test_class => [qw(bug forking)],
},
+ list_symlink_rel_path_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
+ list_symlink_rel_path_subdir_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
+ list_symlink_rel_path_subdir_cwd_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
# XXX Plenty of other tests needed: params, maxfiles, maxdirs, depth, etc
};
@@ -6205,4 +6220,389 @@ sub list_option_parsing {
unlink($log_file);
}
+sub list_symlink_rel_path_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir")) {
+ die("Can't chdir to $tmpdir: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+
+ my $conn = $client->list_raw();
+ unless ($conn) {
+ die("LIST failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ my $res = $conn->read($buf, 8192, 25);
+ eval { $conn->close() };
+
+ my $resp_code = $client->response_code();
+ my $resp_msg = $client->response_msg();
+ $self->assert_transfer_ok($resp_code, $resp_msg);
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# LIST:\n$buf\n";
+ }
+
+ $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+ foreach my $line (@$lines) {
+ if ($line =~ /\s+(\S+)$/) {
+ $res->{$1} = 1;
+ }
+ }
+
+ my $list_count = scalar(keys(%$res));
+ my $expected = 8;
+ $self->assert($list_count == $expected,
+ "Expected $expected entries, got $list_count");
+
+ $self->assert($res->{'/domains/test.oxilion.nl/public_html'},
+ "Expected '/domains/test.oxilion.nl/public_html'");
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
+sub list_symlink_rel_path_subdir_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/test.d/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir/test.d")) {
+ die("Can't chdir to $tmpdir: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+
+ my $conn = $client->list_raw('test.d');
+ unless ($conn) {
+ die("LIST test.d failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ my $res = $conn->read($buf, 8192, 25);
+ eval { $conn->close() };
+
+ my $resp_code = $client->response_code();
+ my $resp_msg = $client->response_msg();
+ $self->assert_transfer_ok($resp_code, $resp_msg);
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# LIST:\n$buf\n";
+ }
+
+ $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+ foreach my $line (@$lines) {
+ if ($line =~ /\s+(\S+)$/) {
+ $res->{$1} = 1;
+ }
+ }
+
+ my $list_count = scalar(keys(%$res));
+ my $expected = 2;
+ $self->assert($list_count == $expected,
+ "Expected $expected entries, got $list_count");
+
+ $self->assert($res->{'/domains/test.oxilion.nl/public_html'},
+ "Expected '/domains/test.oxilion.nl/public_html'");
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
+sub list_symlink_rel_path_subdir_cwd_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/test.d/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir/test.d")) {
+ die("Can't chdir to $tmpdir: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+ $client->cwd('test.d');
+
+ my $conn = $client->list_raw();
+ unless ($conn) {
+ die("LIST failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ my $res = $conn->read($buf, 8192, 25);
+ eval { $conn->close() };
+
+ my $resp_code = $client->response_code();
+ my $resp_msg = $client->response_msg();
+ $self->assert_transfer_ok($resp_code, $resp_msg);
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# LIST:\n$buf\n";
+ }
+
+ $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+ foreach my $line (@$lines) {
+ if ($line =~ /\s+(\S+)$/) {
+ $res->{$1} = 1;
+ }
+ }
+
+ my $list_count = scalar(keys(%$res));
+ my $expected = 2;
+ $self->assert($list_count == $expected,
+ "Expected $expected entries, got $list_count");
+
+ $self->assert($res->{'/domains/test.oxilion.nl/public_html'},
+ "Expected '/domains/test.oxilion.nl/public_html'");
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
1;
diff --git a/tests/t/lib/ProFTPD/Tests/Commands/MLSD.pm b/tests/t/lib/ProFTPD/Tests/Commands/MLSD.pm
index 8c343bbfb..410e5c59a 100644
--- a/tests/t/lib/ProFTPD/Tests/Commands/MLSD.pm
+++ b/tests/t/lib/ProFTPD/Tests/Commands/MLSD.pm
@@ -127,6 +127,21 @@ my $TESTS = {
test_class => [qw(bug forking)],
},
+ mlsd_symlink_rel_path_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
+ mlsd_symlink_rel_path_subdir_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
+ mlsd_symlink_rel_path_subdir_cwd_chrooted_bug4322 => {
+ order => ++$order,
+ test_class => [qw(bug forking rootprivs)],
+ },
+
# XXX Plenty of other tests needed: params, maxfiles, maxdirs, depth, etc
};
@@ -625,7 +640,7 @@ sub mlsd_ok_cwd_dir {
# Make sure that the 'type' fact for the current directory is
# "cdir" (Bug#4198).
my $type = $res->{'.'};
- my $expected = 'cdir';
+ $expected = 'cdir';
$self->assert($expected eq $type,
test_msg("Expected type '$expected', got '$type'"));
};
@@ -767,14 +782,14 @@ sub mlsd_ok_other_dir_bug4198 {
# Make sure that the 'type' fact for the current directory is
# "cdir" (Bug#4198).
my $type = $res->{'.'};
- my $expected = 'cdir';
+ $expected = 'cdir';
$self->assert($expected eq $type,
test_msg("Expected type '$expected', got '$type'"));
# Similarly, make sure that the 'type' fact for parent directory
# (by name) is NOT "cdir", but is just "dir" (Bug#4198).
- my $type = $res->{'sub.d'};
- my $expected = 'dir';
+ $type = $res->{'sub.d'};
+ $expected = 'dir';
$self->assert($expected eq $type,
test_msg("Expected type '$expected', got '$type'"));
};
@@ -3150,4 +3165,407 @@ sub mlsd_wide_dir {
test_cleanup($setup->{log_file}, $ex);
}
+sub mlsd_symlink_rel_path_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir")) {
+ die("Can't chdir to $tmpdir: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ ShowSymlinks => 'on',
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+
+ my $conn = $client->mlsd_raw();
+ unless ($conn) {
+ die("MLSD failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ $conn->read($buf, 8192, 30);
+ eval { $conn->close() };
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# MLSD:\n$buf\n";
+ }
+
+ my $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+
+ foreach my $line (@$lines) {
+ if ($line =~ /^modify=\S+;perm=\S+;type=(\S+);unique=(\S+);UNIX\.group=\d+;UNIX\.groupname=\S+;UNIX\.mode=\d+;UNIX\.owner=\d+;UNIX\.ownername=\S+; (.*?)$/) {
+ $res->{$3} = { type => $1, unique => $2 };
+ }
+ }
+
+ my $count = scalar(keys(%$res));
+ my $expected = 10;
+ unless ($count == $expected) {
+ die("MLSD returned wrong number of entries (expected $expected, got $count)");
+ }
+
+ # public_html is a symlink to domains/test.oxilion.nl/public_html.
+ # According to RFC3659, the unique fact for both of these should thus
+ # be the same, since they are the same underlying object.
+
+ $expected = 'OS.unix=symlink';
+ my $got = $res->{'public_html'}->{type};
+ $self->assert(qr/$expected/i, $got,
+ "Expected type fact '$expected', got '$got'");
+
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
+sub mlsd_symlink_rel_path_subdir_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/test.d/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir/test.d")) {
+ die("Can't chdir to $tmpdir/test.d: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ ShowSymlinks => 'on',
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+
+ my $conn = $client->mlsd_raw('test.d');
+ unless ($conn) {
+ die("MLSD test.d failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ $conn->read($buf, 8192, 30);
+ eval { $conn->close() };
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# MLSD:\n$buf\n";
+ }
+
+ my $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+
+ foreach my $line (@$lines) {
+ if ($line =~ /^modify=\S+;perm=\S+;type=(\S+);unique=(\S+);UNIX\.group=\d+;UNIX\.groupname=\S+;UNIX\.mode=\d+;UNIX\.owner=\d+;UNIX\.ownername=\S+; (.*?)$/) {
+ $res->{$3} = { type => $1, unique => $2 };
+ }
+ }
+
+ my $count = scalar(keys(%$res));
+ my $expected = 4;
+ unless ($count == $expected) {
+ die("MLSD returned wrong number of entries (expected $expected, got $count)");
+ }
+
+ # public_html is a symlink to domains/test.oxilion.nl/public_html.
+ # According to RFC3659, the unique fact for both of these should thus
+ # be the same, since they are the same underlying object.
+
+ $expected = 'OS.unix=symlink';
+ my $got = $res->{'public_html'}->{type};
+ $self->assert(qr/$expected/i, $got,
+ "Expected type fact '$expected', got '$got'");
+
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
+sub mlsd_symlink_rel_path_subdir_cwd_chrooted_bug4322 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'cmds');
+
+ my $dst_path = 'domains/test.oxilion.nl/public_html';
+ my $dst_dir = File::Spec->rel2abs("$tmpdir/test.d/$dst_path");
+ mkpath($dst_dir);
+
+ my $cwd = getcwd();
+ unless (chdir("$tmpdir/test.d")) {
+ die("Can't chdir to $tmpdir/test.d: $!");
+ }
+
+ unless (symlink("./$dst_path", 'public_html')) {
+ die("Can't symlink 'public_html' to './$dst_path': $!");
+ }
+
+ unless (chdir($cwd)) {
+ die("Can't chdir to $cwd: $!");
+ }
+
+ if ($< == 0) {
+ unless (chmod(0755, $dst_dir)) {
+ die("Can't set perms on $dst_dir to 0755: $!");
+ }
+
+ unless (chown($setup->{uid}, $setup->{gid}, $dst_dir)) {
+ die("Can't set owner of $dst_dir to $setup->{uid}/$setup->{gid}: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ ShowSymlinks => 'on',
+ DefaultRoot => '~',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+ $client->cwd('test.d');
+
+ my $conn = $client->mlsd_raw();
+ unless ($conn) {
+ die("MLSD failed: " . $client->response_code() . " " .
+ $client->response_msg());
+ }
+
+ my $buf;
+ $conn->read($buf, 8192, 30);
+ eval { $conn->close() };
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# MLSD:\n$buf\n";
+ }
+
+ my $res = {};
+ my $lines = [split(/(\r)?\n/, $buf)];
+
+ foreach my $line (@$lines) {
+ if ($line =~ /^modify=\S+;perm=\S+;type=(\S+);unique=(\S+);UNIX\.group=\d+;UNIX\.groupname=\S+;UNIX\.mode=\d+;UNIX\.owner=\d+;UNIX\.ownername=\S+; (.*?)$/) {
+ $res->{$3} = { type => $1, unique => $2 };
+ }
+ }
+
+ my $count = scalar(keys(%$res));
+ my $expected = 4;
+ unless ($count == $expected) {
+ die("MLSD returned wrong number of entries (expected $expected, got $count)");
+ }
+
+ # public_html is a symlink to domains/test.oxilion.nl/public_html.
+ # According to RFC3659, the unique fact for both of these should thus
+ # be the same, since they are the same underlying object.
+
+ $expected = 'OS.unix=symlink';
+ my $got = $res->{'public_html'}->{type};
+ $self->assert(qr/$expected/i, $got,
+ "Expected type fact '$expected', got '$got'");
+
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
1;

View File

@@ -0,0 +1,11 @@
--- src/tls.c.orig 2019-04-02 14:00:40.000000000 +0000
+++ src/tls.c 2019-04-28 21:41:25.684814865 +0000
@@ -138,7 +138,7 @@
SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
return 0;
#else
-# ifndef SSL_OP_SINGLE_ECDH_USE
+# if !defined(SSL_OP_SINGLE_ECDH_USE) || !defined(EC_KEY)
errno = ENOTSUP;
return -1;
# else

View File

@@ -0,0 +1,11 @@
--- src/tls.c.orig 2015-05-27 00:16:48.000000000 -0600
+++ src/tls.c 2015-05-27 00:23:53.000000000 -0600
@@ -48,7 +48,7 @@
static int tls_init_ecdh_curve(void)
{
-# ifndef SSL_OP_SINGLE_ECDH_USE
+# if !defined(SSL_OP_SINGLE_ECDH_USE) || !defined(EC_KEY)
errno = ENOTSUP;
return -1;
# else

View File

@@ -0,0 +1,11 @@
--- src/tls.c.orig 2019-04-02 14:00:40.000000000 +0000
+++ src/tls.c 2019-04-28 21:41:25.684814865 +0000
@@ -138,7 +138,7 @@
SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
return 0;
#else
-# ifndef SSL_OP_SINGLE_ECDH_USE
+# if !defined(SSL_OP_SINGLE_ECDH_USE) || !defined(EC_KEY)
errno = ENOTSUP;
return -1;
# else

View File

@@ -0,0 +1,15 @@
--- dbm/sdbm/sdbm_private.h.orig 2014-12-15 17:57:23.592996229 -0700
+++ dbm/sdbm/sdbm_private.h 2014-12-15 17:58:11.127996437 -0700
@@ -34,9 +34,9 @@
#define PBLKSIZ 8192
#define PAIRMAX 8008 /* arbitrary on PBLKSIZ-N */
#else
-#define DBLKSIZ 4096
-#define PBLKSIZ 1024
-#define PAIRMAX 1008 /* arbitrary on PBLKSIZ-N */
+#define DBLKSIZ 16384
+#define PBLKSIZ 8192
+#define PAIRMAX 10080 /* arbitrary on PBLKSIZ-N */
#endif
#define SPLTMAX 10 /* maximum allowed splits */

View File

@@ -0,0 +1,11 @@
--- spamc/configure.pl.orig 2017-09-04 17:15:34.577682508 -0600
+++ spamc/configure.pl 2017-09-04 17:15:49.952822059 -0600
@@ -66,7 +66,7 @@
# Do the same thing as for the preprocessor below.
package version_h;
my $Z = $0;
- local $0 = "version.h.pl";
+ local $0 = "./version.h.pl";
local @ARGV = ();
# Got to check for defined because the script returns shell error level!
unless (defined do $0) {

View File

@@ -0,0 +1,112 @@
diff -up httpd-2.2.15/configure.in.suexec-safe httpd-2.2.15/configure.in
--- httpd-2.2.15/configure.in.suexec-safe 2012-01-23 15:45:50.000000000 +0200
+++ httpd-2.2.15/configure.in 2012-01-23 15:58:30.863352802 +0200
@@ -605,6 +605,10 @@ AC_ARG_WITH(suexec-umask,
APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[
AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] )
+AC_ARG_WITH(suexec-safedir,
+APACHE_HELP_STRING(--with-suexec-safedir,Set safe dir),[
+ AC_DEFINE_UNQUOTED(AP_SAFE_DIRECTORY, "$withval", [safe dir] ) ] )
+
dnl APR should go after the other libs, so the right symbols can be picked up
apulinklibs="`$apu_config --link-libtool`"
AP_LIBS="$AP_LIBS $apulinklibs `$apr_config --link-libtool`"
diff -up httpd-2.2.15/support/suexec.c.suexec-safe httpd-2.2.15/support/suexec.c
--- httpd-2.2.15/support/suexec.c.suexec-safe 2012-01-23 15:45:50.179188786 +0200
+++ httpd-2.2.15/support/suexec.c 2012-01-23 15:45:50.184187935 +0200
@@ -319,6 +319,9 @@ int main(int argc, char *argv[])
#ifdef AP_USERDIR_SUFFIX
fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX);
#endif
+#ifdef AP_SAFE_DIRECTORY
+ fprintf(stderr, " -D AP_SAFE_DIRECTORY=\"%s\"\n", AP_SAFE_DIRECTORY);
+#endif
exit(0);
}
/*
@@ -512,11 +515,32 @@ int main(int argc, char *argv[])
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
*/
+
if (getcwd(cwd, AP_MAXPATH) == NULL) {
log_err("cannot get current working directory\n");
exit(111);
}
+ /* Check for safe directory existence */
+#ifdef AP_SAFE_DIRECTORY
+ char safe_dr[AP_MAXPATH];
+ int is_safe_dir_present = 0;
+ struct stat safe_dir_info;
+ if (((lstat(AP_SAFE_DIRECTORY, &safe_dir_info)) == 0) && (S_ISDIR(safe_dir_info.st_mode))) {
+ is_safe_dir_present = 1;
+ }
+
+ if(is_safe_dir_present){
+ if (((chdir(AP_SAFE_DIRECTORY)) != 0) ||
+ ((getcwd(safe_dr, AP_MAXPATH)) == NULL) ||
+ ((chdir(cwd)) != 0)) {
+ log_err("cannot get safe directory information (%s)\n", AP_SAFE_DIRECTORY);
+ exit(200);
+ }
+ }
+#endif
+
+
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(AP_USERDIR_SUFFIX)) != 0) ||
@@ -535,10 +559,28 @@ int main(int argc, char *argv[])
}
}
- if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
- log_err("command not in docroot (%s/%s)\n", cwd, cmd);
- exit(114);
+#ifdef AP_SAFE_DIRECTORY
+ int safe_work = 0;
+ if(is_safe_dir_present){
+ if ((strncmp(cwd, safe_dr, strlen(safe_dr))) != 0){
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+ } else {
+ safe_work = 1;
+ }
+ } else {
+#endif
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+#ifdef AP_SAFE_DIRECTORY
}
+#endif
+
+
/*
* Stat the cwd and verify it is a directory, or error out.
@@ -584,6 +626,9 @@ int main(int argc, char *argv[])
* Error out if the target name/group is different from
* the name/group of the cwd or the program.
*/
+#ifdef AP_SAFE_DIRECTORY
+ if (!safe_work){
+#endif
if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
@@ -595,6 +640,9 @@ int main(int argc, char *argv[])
prg_info.st_uid, prg_info.st_gid);
exit(120);
}
+#ifdef AP_SAFE_DIRECTORY
+ }
+#endif
/*
* Error out if the program is not executable for the user.
* Otherwise, she won't find any error in the logs except for

View File

@@ -0,0 +1,113 @@
diff -rupN httpd-2.4.6.orig/configure.in httpd-2.4.6/configure.in
--- httpd-2.4.6.orig/configure.in 2013-06-26 07:01:00.000000000 -0600
+++ httpd-2.4.6/configure.in 2013-08-07 01:48:05.000000000 -0600
@@ -740,6 +740,10 @@ AC_ARG_WITH(suexec-umask,
APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[
AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] )
+AC_ARG_WITH(suexec-safedir,
+APACHE_HELP_STRING(--with-suexec-safedir,Set safe dir),[
+ AC_DEFINE_UNQUOTED(AP_SAFE_DIRECTORY, "$withval", [safe dir] ) ] )
+
dnl APR should go after the other libs, so the right symbols can be picked up
if test x${apu_found} != xobsolete; then
AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
Files httpd-2.4.6.orig/patched.tar.gz and httpd-2.4.6/patched.tar.gz differ
diff -rupN httpd-2.4.6.orig/support/suexec.c httpd-2.4.6/support/suexec.c
--- httpd-2.4.6.orig/support/suexec.c 2013-03-11 10:38:39.000000000 -0600
+++ httpd-2.4.6/support/suexec.c 2013-08-07 01:48:05.000000000 -0600
@@ -314,6 +314,9 @@ int main(int argc, char *argv[])
#ifdef AP_USERDIR_SUFFIX
fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX);
#endif
+#ifdef AP_SAFE_DIRECTORY
+ fprintf(stderr, " -D AP_SAFE_DIRECTORY=\"%s\"\n", AP_SAFE_DIRECTORY);
+#endif
exit(0);
}
/*
@@ -497,11 +500,32 @@ int main(int argc, char *argv[])
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
*/
+
if (getcwd(cwd, AP_MAXPATH) == NULL) {
log_err("cannot get current working directory\n");
exit(111);
}
+ /* Check for safe directory existence */
+#ifdef AP_SAFE_DIRECTORY
+ char safe_dr[AP_MAXPATH];
+ int is_safe_dir_present = 0;
+ struct stat safe_dir_info;
+ if (((lstat(AP_SAFE_DIRECTORY, &safe_dir_info)) == 0) && (S_ISDIR(safe_dir_info.st_mode))) {
+ is_safe_dir_present = 1;
+ }
+
+ if(is_safe_dir_present){
+ if (((chdir(AP_SAFE_DIRECTORY)) != 0) ||
+ ((getcwd(safe_dr, AP_MAXPATH)) == NULL) ||
+ ((chdir(cwd)) != 0)) {
+ log_err("cannot get safe directory information (%s)\n", AP_SAFE_DIRECTORY);
+ exit(200);
+ }
+ }
+#endif
+
+
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(AP_USERDIR_SUFFIX)) != 0) ||
@@ -520,10 +544,28 @@ int main(int argc, char *argv[])
}
}
- if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
- log_err("command not in docroot (%s/%s)\n", cwd, cmd);
- exit(114);
+#ifdef AP_SAFE_DIRECTORY
+ int safe_work = 0;
+ if(is_safe_dir_present){
+ if ((strncmp(cwd, safe_dr, strlen(safe_dr))) != 0){
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+ } else {
+ safe_work = 1;
+ }
+ } else {
+#endif
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+#ifdef AP_SAFE_DIRECTORY
}
+#endif
+
+
/*
* Stat the cwd and verify it is a directory, or error out.
@@ -569,6 +611,9 @@ int main(int argc, char *argv[])
* Error out if the target name/group is different from
* the name/group of the cwd or the program.
*/
+#ifdef AP_SAFE_DIRECTORY
+ if (!safe_work){
+#endif
if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
@@ -580,6 +625,9 @@ int main(int argc, char *argv[])
(unsigned long)prg_info.st_uid, (unsigned long)prg_info.st_gid);
exit(120);
}
+#ifdef AP_SAFE_DIRECTORY
+ }
+#endif
/*
* Error out if the program is not executable for the user.
* Otherwise, she won't find any error in the logs except for

View File

@@ -0,0 +1,113 @@
diff -rupN httpd-2.4.6.orig/configure.in httpd-2.4.6/configure.in
--- httpd-2.4.6.orig/configure.in 2013-06-26 07:01:00.000000000 -0600
+++ httpd-2.4.6/configure.in 2013-08-07 01:48:05.000000000 -0600
@@ -740,6 +740,10 @@ AC_ARG_WITH(suexec-umask,
APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[
AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] )
+AC_ARG_WITH(suexec-safedir,
+APACHE_HELP_STRING(--with-suexec-safedir,Set safe dir),[
+ AC_DEFINE_UNQUOTED(AP_SAFE_DIRECTORY, "$withval", [safe dir] ) ] )
+
dnl APR should go after the other libs, so the right symbols can be picked up
if test x${apu_found} != xobsolete; then
AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
Files httpd-2.4.6.orig/patched.tar.gz and httpd-2.4.6/patched.tar.gz differ
diff -rupN httpd-2.4.6.orig/support/suexec.c httpd-2.4.6/support/suexec.c
--- httpd-2.4.6.orig/support/suexec.c 2013-03-11 10:38:39.000000000 -0600
+++ httpd-2.4.6/support/suexec.c 2013-08-07 01:48:05.000000000 -0600
@@ -314,6 +314,9 @@ int main(int argc, char *argv[])
#ifdef AP_USERDIR_SUFFIX
fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX);
#endif
+#ifdef AP_SAFE_DIRECTORY
+ fprintf(stderr, " -D AP_SAFE_DIRECTORY=\"%s\"\n", AP_SAFE_DIRECTORY);
+#endif
exit(0);
}
/*
@@ -497,11 +500,32 @@ int main(int argc, char *argv[])
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
*/
+
if (getcwd(cwd, AP_MAXPATH) == NULL) {
log_err("cannot get current working directory\n");
exit(111);
}
+ /* Check for safe directory existence */
+#ifdef AP_SAFE_DIRECTORY
+ char safe_dr[AP_MAXPATH];
+ int is_safe_dir_present = 0;
+ struct stat safe_dir_info;
+ if (((lstat(AP_SAFE_DIRECTORY, &safe_dir_info)) == 0) && (S_ISDIR(safe_dir_info.st_mode))) {
+ is_safe_dir_present = 1;
+ }
+
+ if(is_safe_dir_present){
+ if (((chdir(AP_SAFE_DIRECTORY)) != 0) ||
+ ((getcwd(safe_dr, AP_MAXPATH)) == NULL) ||
+ ((chdir(cwd)) != 0)) {
+ log_err("cannot get safe directory information (%s)\n", AP_SAFE_DIRECTORY);
+ exit(200);
+ }
+ }
+#endif
+
+
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(AP_USERDIR_SUFFIX)) != 0) ||
@@ -520,10 +544,28 @@ int main(int argc, char *argv[])
}
}
- if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
- log_err("command not in docroot (%s/%s)\n", cwd, cmd);
- exit(114);
+#ifdef AP_SAFE_DIRECTORY
+ int safe_work = 0;
+ if(is_safe_dir_present){
+ if ((strncmp(cwd, safe_dr, strlen(safe_dr))) != 0){
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+ } else {
+ safe_work = 1;
+ }
+ } else {
+#endif
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+#ifdef AP_SAFE_DIRECTORY
}
+#endif
+
+
/*
* Stat the cwd and verify it is a directory, or error out.
@@ -569,6 +611,9 @@ int main(int argc, char *argv[])
* Error out if the target name/group is different from
* the name/group of the cwd or the program.
*/
+#ifdef AP_SAFE_DIRECTORY
+ if (!safe_work){
+#endif
if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
@@ -580,6 +625,9 @@ int main(int argc, char *argv[])
(unsigned long)prg_info.st_uid, (unsigned long)prg_info.st_gid);
exit(120);
}
+#ifdef AP_SAFE_DIRECTORY
+ }
+#endif
/*
* Error out if the program is not executable for the user.
* Otherwise, she won't find any error in the logs except for

View File

@@ -0,0 +1,47 @@
diff -u --recursive suphp-0.7.1/configure.ac suphp-0.7.1-fixed/configure.ac
--- suphp-0.7.1/configure.ac 2009-03-14 13:58:11.000000000 -0400
+++ suphp-0.7.1-fixed/configure.ac 2012-03-27 00:22:45.282086238 -0400
@@ -241,7 +241,7 @@
# Conditionally include UserGroup support
AM_CONDITIONAL([COND_APUSERGROUP], [test \( x"$SETID_MODE" = xparanoid \) -o \( x"$SETID_MODE" = xforce \) ])
-AC_CONFIG_FILES([Makefile src/Makefile src/apache/Makefile src/apache2/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile src/apache2/Makefile])
AC_OUTPUT
if test "$APXS" = "/notfound/"; then
diff -u --recursive suphp-0.7.1/src/Makefile.am suphp-0.7.1-fixed/src/Makefile.am
--- suphp-0.7.1/src/Makefile.am 2008-03-29 09:02:36.000000000 -0400
+++ suphp-0.7.1-fixed/src/Makefile.am 2012-03-27 00:23:10.262087138 -0400
@@ -1,13 +1,10 @@
AM_CXXFLAGS=-DOPT_CONFIGFILE=\"${sysconfdir}/suphp.conf\"
-if COND_AP13
- MAYBE_AP = apache
-endif
if COND_AP20
MAYBE_AP = apache2
endif
-SUBDIRS = $(MAYBE_AP)
-DIST_SUBDIRS = apache apache2
+SUBDIRS = apache2
+DIST_SUBDIRS = apache2
sbin_PROGRAMS = suphp
diff -u --recursive suphp-0.7.1/src/Makefile.in suphp-0.7.1-fixed/src/Makefile.in
--- suphp-0.7.1/src/Makefile.in 2009-03-14 14:08:17.000000000 -0400
+++ suphp-0.7.1-fixed/src/Makefile.in 2012-03-27 00:22:58.958086739 -0400
@@ -214,10 +214,9 @@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CXXFLAGS = -DOPT_CONFIGFILE=\"${sysconfdir}/suphp.conf\"
-@COND_AP13_TRUE@MAYBE_AP = apache
@COND_AP20_TRUE@MAYBE_AP = apache2
-SUBDIRS = $(MAYBE_AP)
-DIST_SUBDIRS = apache apache2
+SUBDIRS = apache2
+DIST_SUBDIRS = apache2
suphp_SOURCES = API.cpp API.hpp API_Helper.cpp API_Helper.hpp API_Linux.cpp API_Linux.hpp API_Linux_Logger.cpp API_Linux_Logger.hpp Application.cpp Application.hpp CommandLine.cpp CommandLine.hpp Configuration.cpp Configuration.hpp Environment.cpp Environment.hpp Exception.cpp Exception.hpp File.cpp File.hpp GroupInfo.cpp GroupInfo.hpp IOException.cpp IOException.hpp IniFile.cpp IniFile.hpp IniSection.cpp IniSection.hpp KeyNotFoundException.cpp KeyNotFoundException.hpp Logger.cpp Logger.hpp LookupException.cpp LookupException.hpp OutOfRangeException.cpp OutOfRangeException.hpp PathMatcher.hpp PathMatcher.cpp ParsingException.cpp ParsingException.hpp PointerException.cpp PointerException.hpp SecurityException.cpp SecurityException.hpp SmartPtr.hpp SoftException.cpp SoftException.hpp SystemException.cpp SystemException.hpp UserInfo.cpp UserInfo.hpp Util.cpp Util.hpp
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive

View File

@@ -0,0 +1,23 @@
diff -Nru a/src/apache2/mod_suphp.c b/src/apache2/mod_suphp.c
--- a/src/apache2/mod_suphp.c 2009-08-03 14:38:38.000000000 +0000
+++ b/src/apache2/mod_suphp.c 2012-09-06 21:36:51.290474099 +0000
@@ -523,17 +523,8 @@
static void suphp_discard_output(apr_bucket_brigade *bb) {
apr_bucket *b;
- const char *buf;
- apr_size_t len;
- apr_status_t rv;
- for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
- if (APR_BUCKET_IS_EOS(b)) {
- break;
- }
- rv = apr_bucket_read(b, &buf, &len, APR_BLOCK_READ);
- if (rv != APR_SUCCESS) {
- break;
- }
+ while ((b = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
+ APR_BUCKET_REMOVE(b);
}
}

View File

@@ -0,0 +1,28 @@
--- a/src/Application.cpp 2009-03-14 19:55:25.000000000 +0200
+++ b/src/Application.cpp 2011-01-25 14:55:25.000000000 +0300
@@ -169,11 +169,6 @@ void suPHP::Application::printAboutMessa
void suPHP::Application::checkProcessPermissions(Configuration& config)
throw (SecurityException, LookupException) {
API& api = API_Helper::getSystemAPI();
- if (api.getRealProcessUser() !=
- api.getUserInfo(config.getWebserverUser())) {
- throw SecurityException("Calling user is not webserver user!",
- __FILE__, __LINE__);
- }
if (!api.getEffectiveProcessUser().isSuperUser()) {
throw SecurityException(
@@ -392,6 +387,13 @@ void suPHP::Application::checkProcessPer
targetGroup = scriptFile.getGroup();
#endif // OPT_USERGROUP_OWNER
+ if (api.getRealProcessUser() !=
+ api.getUserInfo(config.getWebserverUser()) &&
+ api.getRealProcessUser() != targetUser) {
+ throw SecurityException("Calling user is not webserver user!",
+ __FILE__, __LINE__);
+ }
+
// Paranoid mode only
#ifdef OPT_USERGROUP_PARANOID

View File

@@ -0,0 +1,10 @@
--- a/src/Application.cpp 2012-10-26 02:03:17.813538136 -0600
+++ b/src/Application.cpp 2012-10-26 02:09:30.747843504 -0600
@@ -526,6 +526,7 @@
std::string interpreterPath = interpreter.substr(4);
CommandLine cline;
cline.putArgument(interpreterPath);
+ cline.putArgument(scriptFilename);
API_Helper::getSystemAPI().execute(interpreterPath, cline, env);
} else if (mode == TARGETMODE_SELFEXECUTE) {
CommandLine cline;

View File

@@ -0,0 +1,27 @@
--- ./src/nxt_process.c_original 2021-02-04 17:22:33.000000000 +0200
+++ ./src/nxt_process.c 2021-02-28 15:46:34.595278821 +0200
@@ -76,6 +76,24 @@
/* Clean inherited cached thread tid. */
task->thread->tid = 0;
+ char user_slice[128];
+ snprintf(user_slice, sizeof(user_slice), "/sys/fs/cgroup/user.slice/user-%d.slice", process->user_cred->uid);
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/unit-exec.scope");
+ if (mkdir(user_slice, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0 || errno == EEXIST) {
+ strcat(user_slice, "/cgroup.procs");
+ FILE *fp = fopen(user_slice, "a");
+ if (fp == NULL) {
+ nxt_alert(task, "Error opening %s for writing: %s", user_slice, strerror(errno));
+ } else {
+ nxt_debug(task, "cgroupv2 user-slice %s, %s: %PI", user_slice, process->name, process->pid);
+ fprintf(fp, "%d\n", (int) process->pid);
+ fclose(fp);
+ }
+ }
+ }
+
+
#if (NXT_HAVE_CLONE && NXT_HAVE_CLONE_NEWPID)
if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWPID)) {
ssize_t pidsz;

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php53/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php53 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php53/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm53.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php54/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php54 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php54/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm54.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php55/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php55 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php55/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm55.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php56/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php56 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php56/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm56.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php70/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php70 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php70/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm70.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php71/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php71 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php71/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm71.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php72/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php72 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php72/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm72.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php73/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php73 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php73/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm73.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php74/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php74 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php74/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm74.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php80/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php80 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php80/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm80.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php81/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php81 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php81/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm81.conf

View File

@@ -0,0 +1,68 @@
[global]
error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
[webapps]
user = $pool
group = $pool
listen = /usr/local/php82/sockets/$pool.sock
listen.owner = $pool
listen.group = apache
listen.mode = 660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 60
pm.max_requests = 1000
;pm.status_path = /status
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_terminate_timeout = 30s
security.limit_extensions = .php .php5 .php82 .inc .phtml
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
;php_admin_value[open_basedir] = /tmp:/var/tmp:/var/www/html:/usr/local/php82/lib/php
; Load all DA User configs
include=/usr/local/directadmin/data/users/*/php/php-fpm82.conf

View File

@@ -0,0 +1,117 @@
imap:2007f:
cwaf_rules:1.233:
litespeed:6.0.12:
letsencrypt_sh:2.0.30:
apache2.4:2.4.54:
fts-xapian:1.5.5:
xapian-core:1.4.20:
imapsync:2.178:
msmtp:1.8.19:
bubblewrap:0.6.2:
jailshell_sh:0.6:
apr:1.7.0:
apr-util:1.6.1:
modsecurity:2.9.6:
modsecurity3:3.0.8:
modsecurity3_apache:v0.0.9-beta1:
modsecurity3_nginx:v1.0.3:
modsec-sdbm-util:1.0:
owasp3_rules:3.3.2:
libmaxminddb:1.6.0:
geoipupdate:3.1.1:
nginx:1.23.1:
nginx_mainline:1.23.1:
ngx_cache_purge:2.3:
mod_aclr2:1.0.0:
unit:1.28.0:
openlitespeed:1.7.16:
openlitespeed_src:1.7.16:
composer:2.4.1:
wp-cli:2.6.0:
lego:953d5c85145b6a2b9a52f2d919faf23e04a359b3:
lego_arm64:953d5c85145b6a2b9a52f2d919faf23e04a359b3:
dnsproviders:4.5.3:
lua:5.3.5:
s-nail:14.9.23:
awstats:7.8:
awstats_process:2.9:
curl:7.85.0:
dovecot:2.3.19.1:
pigeonhole23:0.5.19:
libspf2:1.2.11:
exim:4.96:
system_filter_exim:1.3:
eximspamconf:1.4:
eximclamavconf:1.4:
eximclamavloadconf:1.1:
clamav:0.104.4:
exim_conf_45:4.5.42:
blockcracking:1.12:
easy_spam_figther:1.32:
exim_pl_45:32:
exim_dkim_conf:1.7:
imagick:3.7.0:
phalcon:4.1.2:
snuffleupagus:0.7.1:
igbinary:3.2.7:
phpredis:5.3.7:
xmlrpc:1.0.0RC3:
psr:1.2.0:
imagemagick:7.1.0-24:
redis:7.0.4:
libzip:1.7.3:
mysql5.5:5.5.62:
mysql5.6:5.6.51:
mysql5.7:5.7.39:
mysql8.0:8.0.30:
mariadb5.5:5.5.68:
mariadb10.0:10.0.38:
mariadb10.1:10.1.48:
mariadb10.2:10.2.44:
mariadb10.3:10.3.36:
mariadb10.4:10.4.26:
mariadb10.5:10.5.17:
mariadb10.6:10.6.9:
jemalloc_versions:3.6.0:
galera_versions:26.4.8:
php53:5.3.29:
php54:5.4.45:
php55:5.5.38:
php56:5.6.40:
php70:7.0.33:
php71:7.1.33:
php72:7.2.34:
php73:7.3.33:
php74:7.4.30:
php80:8.0.23:
php81:8.1.10:
php82:8.2.3:
phpmyadmin4:4.9.10-all-languages:
phpmyadmin5:5.2.0-all-languages:
proftpd:1.3.7e:
ncftp:3.2.6:
pureftpd:1.0.49:
roundcubemail:1.6.0:
rc_direct_login:0.8:
pma_direct_login:0.5:
spamassassin:3.4.6:
sa-update-sh:1.5:
spamassassin_rules:3.4.6.r1888502:
rspamd:1.8.1:
rspamd_conf:0.4:
squirrelmail:1.4.22:
squirrelmail_svn:1.4.23-20220318_0200:
squirrelmail_locale:1.4.18-20090526:
squirrel_logger:2.3.1-1.2.7:
mod_fcgid:2.3.9:
fcgid_sh:1.0:
htscanner:1.0.1-enhanced:
mod_ruid2:0.9.8:
curl_cacert:20161102:
suphp:0.7.1:
suphp_current:0.7.2:
webalizer:2.23-09:
zendopcache:7.0.5:
ioncube_loaders_lin_x86-64:12.0.2:
ioncube_loaders_lin_aarch64:12.0.2:
suhosin:0.9.38: