diff --git a/NEWS b/NEWS index cef4c1b0060..9116699c92d 100644 --- a/NEWS +++ b/NEWS @@ -67,6 +67,7 @@ PHP NEWS (David Carlier) . Added TCP_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT socket options. (David Carlier) + . Added ancillary data support for FreeBSD. (David Carlier) - Sodium: . Added sodium_crypto_stream_xchacha20_xor_ic(). (Scott) diff --git a/UPGRADING b/UPGRADING index b56754f713d..2991dc8ba8c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -246,6 +246,8 @@ PHP 8.2 UPGRADE NOTES . TCP_KEEPIDLE (Linux, others) . TCP_KEEPINTVL (Linux, others) . TCP_NOTSENT_LOWAT + . LOCAL_CREDS_PERSISTENT (FreeBSD) + . SCM_CREDS2 (FreeBSD) ======================================== 11. Changes to INI File Handling diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 90a79b83985..35538217e6f 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -435,7 +435,7 @@ static void from_zval_write_sa_family(const zval *arr_value, char *field, ser_co memcpy(field, &ival, sizeof(ival)); } -#ifdef SO_PASSCRED +#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) static void from_zval_write_pid_t(const zval *arr_value, char *field, ser_context *ctx) { zend_long lval; @@ -522,7 +522,7 @@ static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx) ZVAL_LONG(zv, (zend_long)ival); } #endif -#ifdef SO_PASSCRED +#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx) { pid_t ival; @@ -1301,19 +1301,24 @@ void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx) } #endif -/* CONVERSIONS for struct ucred/cmsgcred */ -#ifdef SO_PASSCRED +/* CONVERSIONS for struct ucred */ +#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) static const field_descriptor descriptors_ucred[] = { -#if defined(ANC_CREDS_UCRED) - {"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t}, - {"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t}, - /* assume the type gid_t is the same as uid_t: */ - {"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t}, +#if defined(LOCAL_CREDS_PERSISTENT) + {"pid", sizeof("pid"), 1, offsetof(struct sockcred2, sc_pid), from_zval_write_pid_t, to_zval_read_pid_t}, + {"uid", sizeof("uid"), 1, offsetof(struct sockcred2, sc_euid), from_zval_write_uid_t, to_zval_read_uid_t}, + /* the type gid_t is the same as uid_t: */ + {"gid", sizeof("gid"), 1, offsetof(struct sockcred2, sc_egid), from_zval_write_uid_t, to_zval_read_uid_t}, #elif defined(ANC_CREDS_CMSGCRED) {"pid", sizeof("pid"), 1, offsetof(struct cmsgcred, cmcred_pid), from_zval_write_pid_t, to_zval_read_pid_t}, {"uid", sizeof("uid"), 1, offsetof(struct cmsgcred, cmcred_uid), from_zval_write_uid_t, to_zval_read_uid_t}, /* assume the type gid_t is the same as uid_t: */ {"gid", sizeof("gid"), 1, offsetof(struct cmsgcred, cmcred_gid), from_zval_write_uid_t, to_zval_read_uid_t}, +#elif defined(SO_PASSCRED) + {"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t}, + {"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t}, + /* assume the type gid_t is the same as uid_t: */ + {"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t}, #endif {0} }; diff --git a/ext/sockets/conversions.h b/ext/sockets/conversions.h index 0ae6b6d853e..fa51d610f0d 100644 --- a/ext/sockets/conversions.h +++ b/ext/sockets/conversions.h @@ -6,6 +6,9 @@ #ifndef PHP_WIN32 # include # include +# ifdef __FreeBSD__ +# include +# endif #else # include #endif @@ -51,7 +54,7 @@ void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx); #endif -#ifdef SO_PASSCRED +#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx); void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx); #endif diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index 01cb773acb1..2019a762e3a 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -134,6 +134,11 @@ static void init_ancillary_registry(void) #endif #endif +#ifdef LOCAL_CREDS_PERSISTENT + PUT_ENTRY(SOCKCRED2SIZE(1), 1, 0, from_zval_write_ucred, + to_zval_read_ucred, SOL_SOCKET, SCM_CREDS2); +#endif + #ifdef SCM_RIGHTS PUT_ENTRY(0, sizeof(int), calculate_scm_rights_space, from_zval_write_fd_array, to_zval_read_fd_array, SOL_SOCKET, SCM_RIGHTS); @@ -452,6 +457,10 @@ void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS) #endif REGISTER_LONG_CONSTANT("SO_PASSCRED", SO_PASSCRED, CONST_CS | CONST_PERSISTENT); #endif +#ifdef LOCAL_CREDS_PERSISTENT + REGISTER_LONG_CONSTANT("SCM_CREDS2", SCM_CREDS2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOCAL_CREDS_PERSISTENT", LOCAL_CREDS_PERSISTENT, CONST_CS | CONST_PERSISTENT); +#endif #ifdef ZTS ancillary_mutex = tsrm_mutex_alloc(); diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index fec1e5159c5..67c2038324a 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -638,6 +638,9 @@ static PHP_MINIT_FUNCTION(sockets) #ifdef AI_NUMERICSERV REGISTER_LONG_CONSTANT("AI_NUMERICSERV", AI_NUMERICSERV, CONST_CS | CONST_PERSISTENT); #endif +#ifdef SOL_LOCAL + REGISTER_LONG_CONSTANT("SOL_LOCAL", SOL_LOCAL, CONST_CS | CONST_PERSISTENT); +#endif php_socket_sendrecvmsg_init(INIT_FUNC_ARGS_PASSTHRU); diff --git a/ext/sockets/tests/socket_cmsg_credentials_fbsd.phpt b/ext/sockets/tests/socket_cmsg_credentials_fbsd.phpt new file mode 100644 index 00000000000..3a4984f924d --- /dev/null +++ b/ext/sockets/tests/socket_cmsg_credentials_fbsd.phpt @@ -0,0 +1,92 @@ +--TEST-- +recvmsg(): receive SCM_CREDS messages +--EXTENSIONS-- +sockets +--SKIPIF-- + [], + "buffer_size" => 2000, + "controllen" => socket_cmsg_space(SOL_SOCKET, SCM_CREDS2, 1) +]; +if (!socket_recvmsg($s, $data, 0)) die("recvmsg"); +print_r($data); + +$pid = getmypid(); +var_dump($data['control'][0]['data']['pid'] === $pid); +?> +--CLEAN-- + Array + ( + [family] => %d + [path] => + ) + + [control] => Array + ( + [0] => Array + ( + [level] => %d + [type] => %d + [data] => Array + ( + [pid] => %d + [uid] => %d + [gid] => %d + ) + + ) + + ) + + [iov] => Array + ( + [0] => dread + ) + + [flags] => 0 +) +bool(true)