The branch, master has been updated via df75d82c9de classicupgrade: treat old never expires value right via d8fa464a2df s3:pysmbd: fix fd leak in py_smbd_create_file() via ab943babc3e third_party: Update socket_wrapper to version 1.3.2 via 9178e72dccc selftest/gdb_backtrace: use 'unset LD_PRELOAD' via cc6102915b2 examples/fuse/smb2mount: fix compiler warning on ubuntu20.04 with -O3 from d0529682605 samba-tool: Add a gpo command for setting VGP OpenSSH Group Policy
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit df75d82c9de6977c466ee9f01886cb012a9c5fef Author: Björn Jacke <b...@sernet.de> Date: Fri Feb 5 12:47:01 2021 +0100 classicupgrade: treat old never expires value right BUG: https://bugzilla.samba.org/show_bug.cgi?id=14624 Signed-off-by: Bjoern Jacke <bja...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Wed Feb 10 15:06:49 UTC 2021 on sn-devel-184 commit d8fa464a2dfb11df4e1db4ebffe8bd28ff118c75 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Feb 9 13:48:36 2021 +0100 s3:pysmbd: fix fd leak in py_smbd_create_file() Various 'samba-tool domain backup' commands use this and will fail if there's over ~1000 files in the sysvol folder. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13898 Signed-off-by: Stefan Metzmacher <me...@samba.org> commit ab943babc3eb454186558f6e863996dfcf7a20ea Author: Stefan Metzmacher <me...@samba.org> Date: Tue Feb 9 08:56:42 2021 +0100 third_party: Update socket_wrapper to version 1.3.2 This brings support for fd-passing of INET sockets. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11899 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 9178e72dccc548f2e2e573f97f78a834f35b142d Author: Stefan Metzmacher <me...@samba.org> Date: Tue Feb 9 16:22:37 2021 +0100 selftest/gdb_backtrace: use 'unset LD_PRELOAD' We may have bugs in socket_wrapper and others, we don't want to inject these bugs into the debugger. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit cc6102915b20088cfadb9d63b3c4784d8b3d9717 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Feb 3 17:55:14 2021 +0100 examples/fuse/smb2mount: fix compiler warning on ubuntu20.04 with -O3 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: buildtools/wafsamba/samba_third_party.py | 2 +- examples/fuse/smb2mount.c | 2 +- python/samba/upgrade.py | 2 +- selftest/gdb_backtrace | 2 + source3/smbd/pysmbd.c | 3 + third_party/socket_wrapper/socket_wrapper.c | 1605 ++++++++++++++++++++++----- third_party/socket_wrapper/wscript | 7 +- 7 files changed, 1356 insertions(+), 267 deletions(-) Changeset truncated at 500 lines: diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py index bc2b21f2a55..d4d8f7a8dd0 100644 --- a/buildtools/wafsamba/samba_third_party.py +++ b/buildtools/wafsamba/samba_third_party.py @@ -24,7 +24,7 @@ Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA @conf def CHECK_SOCKET_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.5') + return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.2') Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER @conf diff --git a/examples/fuse/smb2mount.c b/examples/fuse/smb2mount.c index c64be573462..aefa90c4c78 100644 --- a/examples/fuse/smb2mount.c +++ b/examples/fuse/smb2mount.c @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) } share = strchr_m(server,'\\'); if (!share) { - fprintf(stderr, "Invalid argument: %s\n", share); + fprintf(stderr, "Invalid argument: %s\n", server); return -1; } diff --git a/python/samba/upgrade.py b/python/samba/upgrade.py index 8511bed2868..dff856a8d7c 100644 --- a/python/samba/upgrade.py +++ b/python/samba/upgrade.py @@ -74,7 +74,7 @@ def import_sam_policy(samdb, policy, logger): if 'maximum password age' in policy: max_pw_age_unix = policy['maximum password age'] - if max_pw_age_unix == -1 or max_pw_age_unix == 0: + if max_pw_age_unix == -1 or max_pw_age_unix == 0 or max_pw_age_unix == 0xFFFFFFFF: max_pw_age_nt = -0x8000000000000000 else: max_pw_age_nt = int(-max_pw_age_unix * (1e7)) diff --git a/selftest/gdb_backtrace b/selftest/gdb_backtrace index ef02e784efc..4fe5f57353a 100755 --- a/selftest/gdb_backtrace +++ b/selftest/gdb_backtrace @@ -2,6 +2,8 @@ BASENAME=`basename $0` +unset LD_PRELOAD + if [ -n "$VALGRIND" -o -n "$SMBD_VALGRIND" ]; then echo "${BASENAME}: Not running debugger under valgrind" exit 1 diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index c78aefd32f7..ecbdd7a29e8 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -1185,9 +1185,12 @@ static PyObject *py_smbd_create_file(PyObject *self, PyObject *args, PyObject *k if (!NT_STATUS_IS_OK(status)) { DBG_ERR("init_files_struct failed: %s\n", nt_errstr(status)); + } else if (fsp != NULL) { + SMB_VFS_CLOSE(fsp); } TALLOC_FREE(frame); + PyErr_NTSTATUS_NOT_OK_RAISE(status); Py_RETURN_NONE; } diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c index ffdd31a51bf..a950a0a0dbc 100644 --- a/third_party/socket_wrapper/socket_wrapper.c +++ b/third_party/socket_wrapper/socket_wrapper.c @@ -178,24 +178,67 @@ enum swrap_dbglvl_e { # endif #endif +#define socket_wrapper_init_mutex(m) \ + _socket_wrapper_init_mutex(m, #m) + /* Add new global locks here please */ -# define SWRAP_LOCK_ALL \ - swrap_mutex_lock(&libc_symbol_binding_mutex); \ +# define SWRAP_REINIT_ALL do { \ + int ret; \ + ret = socket_wrapper_init_mutex(&sockets_mutex); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&socket_reset_mutex); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&first_free_mutex); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&sockets_si_global); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&autobind_start_mutex); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \ + if (ret != 0) exit(-1); \ + ret = socket_wrapper_init_mutex(&mtu_update_mutex); \ + if (ret != 0) exit(-1); \ +} while(0) + +# define SWRAP_LOCK_ALL do { \ + swrap_mutex_lock(&sockets_mutex); \ + swrap_mutex_lock(&socket_reset_mutex); \ + swrap_mutex_lock(&first_free_mutex); \ + swrap_mutex_lock(&sockets_si_global); \ + swrap_mutex_lock(&autobind_start_mutex); \ + swrap_mutex_lock(&pcap_dump_mutex); \ + swrap_mutex_lock(&mtu_update_mutex); \ +} while(0) -# define SWRAP_UNLOCK_ALL \ - swrap_mutex_unlock(&libc_symbol_binding_mutex); \ +# define SWRAP_UNLOCK_ALL do { \ + swrap_mutex_unlock(&mtu_update_mutex); \ + swrap_mutex_unlock(&pcap_dump_mutex); \ + swrap_mutex_unlock(&autobind_start_mutex); \ + swrap_mutex_unlock(&sockets_si_global); \ + swrap_mutex_unlock(&first_free_mutex); \ + swrap_mutex_unlock(&socket_reset_mutex); \ + swrap_mutex_unlock(&sockets_mutex); \ +} while(0) #define SOCKET_INFO_CONTAINER(si) \ (struct socket_info_container *)(si) #define SWRAP_LOCK_SI(si) do { \ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \ - swrap_mutex_lock(&sic->meta.mutex); \ + if (sic != NULL) { \ + swrap_mutex_lock(&sockets_si_global); \ + } else { \ + abort(); \ + } \ } while(0) #define SWRAP_UNLOCK_SI(si) do { \ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \ - swrap_mutex_unlock(&sic->meta.mutex); \ + if (sic != NULL) { \ + swrap_mutex_unlock(&sockets_si_global); \ + } else { \ + abort(); \ + } \ } while(0) #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) @@ -253,10 +296,15 @@ struct swrap_address { } sa; }; -int first_free; +static int first_free; struct socket_info { + /* + * Remember to update swrap_unix_scm_right_magic + * on any change. + */ + int family; int type; int protocol; @@ -268,6 +316,7 @@ struct socket_info int pktinfo; int tcp_nodelay; int listening; + int fd_passed; /* The unix path so we can unlink it on close() */ struct sockaddr_un un_addr; @@ -286,7 +335,13 @@ struct socket_info_meta { unsigned int refcount; int next_free; - pthread_mutex_t mutex; + /* + * As long as we don't use shared memory + * for the sockets array, we use + * sockets_si_global as a single mutex. + * + * pthread_mutex_t mutex; + */ }; struct socket_info_container @@ -309,32 +364,44 @@ static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT; /* Hash table to map fds to corresponding socket_info index */ static int *socket_fds_idx; -/* Mutex to synchronize access to global libc.symbols */ -static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; - /* Mutex for syncronizing port selection during swrap_auto_bind() */ -static pthread_mutex_t autobind_start_mutex; +static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER; /* Mutex to guard the initialization of array of socket_info structures */ -static pthread_mutex_t sockets_mutex; +static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER; /* Mutex to guard the socket reset in swrap_close() and swrap_remove_stale() */ -static pthread_mutex_t socket_reset_mutex; +static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER; /* Mutex to synchronize access to first free index in socket_info array */ -static pthread_mutex_t first_free_mutex; +static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* + * Mutex to synchronize access to to socket_info structures + * We use a single global mutex in order to avoid leaking + * ~ 38M copy on write memory per fork. + * max_sockets=65535 * sizeof(struct socket_info_container)=592 = 38796720 + */ +static pthread_mutex_t sockets_si_global = PTHREAD_MUTEX_INITIALIZER; /* Mutex to synchronize access to packet capture dump file */ -static pthread_mutex_t pcap_dump_mutex; +static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER; /* Mutex for synchronizing mtu value fetch*/ -static pthread_mutex_t mtu_update_mutex; +static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER; /* Function prototypes */ bool socket_wrapper_enabled(void); +#if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT) +/* xlC and other oldschool compilers support (only) this */ +#pragma init (swrap_constructor) +#endif void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE; +#if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI) +#pragma fini (swrap_destructor) +#endif void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE; #ifndef HAVE_GETPROGNAME @@ -565,7 +632,6 @@ static char *socket_wrapper_dir(void); enum swrap_lib { SWRAP_LIBC, - SWRAP_LIBNSL, SWRAP_LIBSOCKET, }; @@ -574,8 +640,6 @@ static const char *swrap_str_lib(enum swrap_lib lib) switch (lib) { case SWRAP_LIBC: return "libc"; - case SWRAP_LIBNSL: - return "libnsl"; case SWRAP_LIBSOCKET: return "libsocket"; } @@ -613,7 +677,6 @@ static void *swrap_load_lib_handle(enum swrap_lib lib) #endif switch (lib) { - case SWRAP_LIBNSL: case SWRAP_LIBSOCKET: #ifdef HAVE_LIBSOCKET handle = swrap.libc.socket_handle; @@ -695,25 +758,29 @@ static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name) return func; } -static void swrap_mutex_lock(pthread_mutex_t *mutex) +#define swrap_mutex_lock(m) _swrap_mutex_lock(m, #m, __func__, __LINE__) +static void _swrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line) { int ret; ret = pthread_mutex_lock(mutex); if (ret != 0) { - SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't lock pthread mutex - %s", - strerror(ret)); + SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s", + getpid(), getppid(), caller, line, name, strerror(ret)); + abort(); } } -static void swrap_mutex_unlock(pthread_mutex_t *mutex) +#define swrap_mutex_unlock(m) _swrap_mutex_unlock(m, #m, __func__, __LINE__) +static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line) { int ret; ret = pthread_mutex_unlock(mutex); if (ret != 0) { - SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't unlock pthread mutex - %s", - strerror(ret)); + SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s", + getpid(), getppid(), caller, line, name, strerror(ret)); + abort(); } } @@ -723,35 +790,18 @@ static void swrap_mutex_unlock(pthread_mutex_t *mutex) * This is an optimization to avoid locking each time we check if the symbol is * bound. */ +#define _swrap_bind_symbol_generic(lib, sym_name) do { \ + swrap.libc.symbols._libc_##sym_name.obj = \ + _swrap_bind_symbol(lib, #sym_name); \ +} while(0); + #define swrap_bind_symbol_libc(sym_name) \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap_mutex_lock(&libc_symbol_binding_mutex); \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \ - } \ - swrap_mutex_unlock(&libc_symbol_binding_mutex); \ - } + _swrap_bind_symbol_generic(SWRAP_LIBC, sym_name) #define swrap_bind_symbol_libsocket(sym_name) \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap_mutex_lock(&libc_symbol_binding_mutex); \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \ - } \ - swrap_mutex_unlock(&libc_symbol_binding_mutex); \ - } + _swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name) -#define swrap_bind_symbol_libnsl(sym_name) \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap_mutex_lock(&libc_symbol_binding_mutex); \ - if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \ - } \ - swrap_mutex_unlock(&libc_symbol_binding_mutex); \ - } +static void swrap_bind_symbol_all(void); /**************************************************************************** * IMPORTANT @@ -770,7 +820,7 @@ static int libc_accept4(int sockfd, socklen_t *addrlen, int flags) { - swrap_bind_symbol_libsocket(accept4); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags); } @@ -779,7 +829,7 @@ static int libc_accept4(int sockfd, static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - swrap_bind_symbol_libsocket(accept); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen); } @@ -789,14 +839,14 @@ static int libc_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - swrap_bind_symbol_libsocket(bind); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen); } static int libc_close(int fd) { - swrap_bind_symbol_libc(close); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_close.f(fd); } @@ -805,21 +855,21 @@ static int libc_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - swrap_bind_symbol_libsocket(connect); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen); } static int libc_dup(int fd) { - swrap_bind_symbol_libc(dup); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_dup.f(fd); } static int libc_dup2(int oldfd, int newfd) { - swrap_bind_symbol_libc(dup2); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_dup2.f(oldfd, newfd); } @@ -827,7 +877,7 @@ static int libc_dup2(int oldfd, int newfd) #ifdef HAVE_EVENTFD static int libc_eventfd(int count, int flags) { - swrap_bind_symbol_libc(eventfd); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_eventfd.f(count, flags); } @@ -839,7 +889,7 @@ static int libc_vfcntl(int fd, int cmd, va_list ap) void *arg; int rc; - swrap_bind_symbol_libc(fcntl); + swrap_bind_symbol_all(); arg = va_arg(ap, void *); @@ -852,7 +902,7 @@ static int libc_getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - swrap_bind_symbol_libsocket(getpeername); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen); } @@ -861,7 +911,7 @@ static int libc_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - swrap_bind_symbol_libsocket(getsockname); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen); } @@ -872,7 +922,7 @@ static int libc_getsockopt(int sockfd, void *optval, socklen_t *optlen) { - swrap_bind_symbol_libsocket(getsockopt); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_getsockopt.f(sockfd, level, @@ -887,7 +937,7 @@ static int libc_vioctl(int d, unsigned long int request, va_list ap) void *arg; int rc; - swrap_bind_symbol_libc(ioctl); + swrap_bind_symbol_all(); arg = va_arg(ap, void *); @@ -898,14 +948,14 @@ static int libc_vioctl(int d, unsigned long int request, va_list ap) static int libc_listen(int sockfd, int backlog) { - swrap_bind_symbol_libsocket(listen); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_listen.f(sockfd, backlog); } static FILE *libc_fopen(const char *name, const char *mode) { - swrap_bind_symbol_libc(fopen); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_fopen.f(name, mode); } @@ -913,7 +963,7 @@ static FILE *libc_fopen(const char *name, const char *mode) #ifdef HAVE_FOPEN64 static FILE *libc_fopen64(const char *name, const char *mode) { - swrap_bind_symbol_libc(fopen64); + swrap_bind_symbol_all(); return swrap.libc.symbols._libc_fopen64.f(name, mode); } @@ -924,7 +974,7 @@ static int libc_vopen(const char *pathname, int flags, va_list ap) int mode = 0; int fd; - swrap_bind_symbol_libc(open); + swrap_bind_symbol_all(); if (flags & O_CREAT) { mode = va_arg(ap, int); @@ -952,7 +1002,7 @@ static int libc_vopen64(const char *pathname, int flags, va_list ap) int mode = 0; int fd; - swrap_bind_symbol_libc(open64); -- Samba Shared Repository