The branch, master has been updated via 25aa870fed5 third_party: Update uid_wrapper to version 1.3.0 via 77110bc9e8a third_party: Update socket_wrapper to version 1.4.0 via 35ee3e0231a ctdb: Fix the build on FreeBSD via 99de0cf6ff0 smbd: Modernize DBG statements in smbXsrv_open_global_store() via c6f1e3a6a20 smbd: Make smbXsrv_open_global_id_to_key() a bit more type-safe via 824b54174d8 smbd: Directly initialize key in smbXsrv_open_global_fetch_locked() via 6deee159f1d smbd: Remove unused smbXsrv_open_global_key_to_id() via a39a3400ba6 smbd: Slightly simplify smbXsrv_open_create() via b88db811db9 smbd: Remove smbXsrv_open_global_destructor() via d55880d93dc smbd: Slightly simplify smb2srv_open_recreate() from 8fbadada8c0 lib/tsocket: fix a typo in the tsocket guide doc
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 25aa870fed548805a8cf64037a01ce0c87c6a01f Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jan 16 22:14:03 2023 +0100 third_party: Update uid_wrapper to version 1.3.0 This is mainly needed in order to have some interaction with socket_wrapper 1.4.0 regarding the implementation of syscall(). Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Wed Jan 18 12:47:48 UTC 2023 on sn-devel-184 commit 77110bc9e8a09ebefaa42eb4fd3a7449373fec9a Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jan 16 22:13:35 2023 +0100 third_party: Update socket_wrapper to version 1.4.0 The key feature is support for sendmmsg and recvmmsg, which is required by modern libuv versions, e.g. nsupdate -g makes use of libuv, so we need this for samba. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 35ee3e0231ac95cc81dee32eb8efd97e0c3016f9 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 18 08:59:17 2023 +0100 ctdb: Fix the build on FreeBSD "basename" is define in libgen.h included from system/dir.h Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 99de0cf6ff085476191d6f3e63327c5068a233f8 Author: Volker Lendecke <v...@samba.org> Date: Thu Jan 5 16:06:40 2023 +0100 smbd: Modernize DBG statements in smbXsrv_open_global_store() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c6f1e3a6a201429e1c9abf027b7abd7eb8fe2f1b Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 4 20:09:32 2023 +0100 smbd: Make smbXsrv_open_global_id_to_key() a bit more type-safe Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 824b54174d842a2e9e7a0f5f60998b478b6d82f2 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 11 14:07:42 2023 +0100 smbd: Directly initialize key in smbXsrv_open_global_fetch_locked() Don't leave the key.dptr pointer uninitialized Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 6deee159f1d7fd4876f774d435998d16b89da37d Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 4 16:50:01 2023 +0100 smbd: Remove unused smbXsrv_open_global_key_to_id() This isn't exactly rocket science we would need to keep around Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit a39a3400ba65b4357d3608d2e423576d2b6ed1e3 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 4 14:30:28 2023 +0100 smbd: Slightly simplify smbXsrv_open_create() Move allocation of smbXsrv_open_global0 out of smbXsrv_open_global_allocate() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit b88db811db9d2c12838e7ca33352b68abf7c64ad Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 11 14:01:29 2023 +0100 smbd: Remove smbXsrv_open_global_destructor() This did not do much. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit d55880d93dc46bf09b4de1a848a1c46e5de2302d Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 4 14:05:55 2023 +0100 smbd: Slightly simplify smb2srv_open_recreate() This moves the bit-fiddling right next to the check we do, "global_zeros" was only used for this one purpose and its assignment was a few lines away. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: ctdb/server/ctdb_mutex_fcntl_helper.c | 1 + source3/smbd/smbXsrv_open.c | 120 ++-- third_party/socket_wrapper/socket_wrapper.c | 887 +++++++++++++++++++++++++++- third_party/socket_wrapper/wscript | 14 + third_party/uid_wrapper/uid_wrapper.c | 600 ++++++++++++++++--- 5 files changed, 1454 insertions(+), 168 deletions(-) Changeset truncated at 500 lines: diff --git a/ctdb/server/ctdb_mutex_fcntl_helper.c b/ctdb/server/ctdb_mutex_fcntl_helper.c index 84d3790db57..aac98eaeead 100644 --- a/ctdb/server/ctdb_mutex_fcntl_helper.c +++ b/ctdb/server/ctdb_mutex_fcntl_helper.c @@ -25,6 +25,7 @@ #include "system/filesys.h" #include "system/network.h" #include "system/wait.h" +#include "system/dir.h" #include <tevent.h> diff --git a/source3/smbd/smbXsrv_open.c b/source3/smbd/smbXsrv_open.c index c67556545be..6aa44ec4fcc 100644 --- a/source3/smbd/smbXsrv_open.c +++ b/source3/smbd/smbXsrv_open.c @@ -94,47 +94,28 @@ NTSTATUS smbXsrv_open_global_init(void) * TODO: implement string based key */ -#define SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE sizeof(uint32_t) +struct smbXsrv_open_global_key_buf { uint8_t buf[sizeof(uint32_t)]; }; -static TDB_DATA smbXsrv_open_global_id_to_key(uint32_t id, - uint8_t *key_buf) +static TDB_DATA smbXsrv_open_global_id_to_key( + uint32_t id, struct smbXsrv_open_global_key_buf *key_buf) { - TDB_DATA key; - - RSIVAL(key_buf, 0, id); - - key = make_tdb_data(key_buf, SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE); - - return key; -} - -#if 0 -static NTSTATUS smbXsrv_open_global_key_to_id(TDB_DATA key, uint32_t *id) -{ - if (id == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (key.dsize != SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + RSIVAL(key_buf->buf, 0, id); - *id = RIVAL(key.dptr, 0); - - return NT_STATUS_OK; + return (TDB_DATA) { + .dptr = key_buf->buf, + .dsize = sizeof(key_buf->buf), + }; } -#endif static struct db_record *smbXsrv_open_global_fetch_locked( struct db_context *db, uint32_t id, TALLOC_CTX *mem_ctx) { - TDB_DATA key; - uint8_t key_buf[SMBXSRV_OPEN_GLOBAL_TDB_KEY_SIZE]; + struct smbXsrv_open_global_key_buf key_buf; + TDB_DATA key = smbXsrv_open_global_id_to_key(id, &key_buf); struct db_record *rec = NULL; - key = smbXsrv_open_global_id_to_key(id, key_buf); rec = dbwrap_fetch_locked(db, mem_ctx, key); @@ -244,41 +225,19 @@ static NTSTATUS smbXsrv_open_local_lookup(struct smbXsrv_open_table *table, return NT_STATUS_OK; } -static int smbXsrv_open_global_destructor(struct smbXsrv_open_global0 *global) -{ - return 0; -} - static void smbXsrv_open_global_verify_record(struct db_record *db_rec, bool *is_free, bool *was_free, TALLOC_CTX *mem_ctx, struct smbXsrv_open_global0 **_g); -static NTSTATUS smbXsrv_open_global_allocate(struct db_context *db, - TALLOC_CTX *mem_ctx, - struct smbXsrv_open_global0 **_global) +static NTSTATUS smbXsrv_open_global_allocate( + struct db_context *db, struct smbXsrv_open_global0 *global) { uint32_t i; - struct smbXsrv_open_global0 *global = NULL; uint32_t last_free = 0; const uint32_t min_tries = 3; - *_global = NULL; - - global = talloc_zero(mem_ctx, struct smbXsrv_open_global0); - if (global == NULL) { - return NT_STATUS_NO_MEMORY; - } - talloc_set_destructor(global, smbXsrv_open_global_destructor); - - /* - * We mark every slot as invalid using 0xFF. - * Valid values are masked with 0xF. - */ - memset(global->lock_sequence_array, 0xFF, - sizeof(global->lock_sequence_array)); - /* * Here we just randomly try the whole 32-bit space * @@ -302,9 +261,9 @@ static NTSTATUS smbXsrv_open_global_allocate(struct db_context *db, id--; } - global->db_rec = smbXsrv_open_global_fetch_locked(db, id, mem_ctx); + global->db_rec = smbXsrv_open_global_fetch_locked( + db, id, global); if (global->db_rec == NULL) { - talloc_free(global); return NT_STATUS_INSUFFICIENT_RESOURCES; } @@ -338,12 +297,10 @@ static NTSTATUS smbXsrv_open_global_allocate(struct db_context *db, global->open_global_id = id; - *_global = global; return NT_STATUS_OK; } /* should not be reached */ - talloc_free(global); return NT_STATUS_INTERNAL_ERROR; } @@ -472,28 +429,26 @@ static NTSTATUS smbXsrv_open_global_store(struct smbXsrv_open_global0 *global) ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &global_blob, (ndr_push_flags_fn_t)ndr_push_smbXsrv_open_globalB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(1,("smbXsrv_open_global_store: key '%s' ndr_push - %s\n", - tdb_data_dbg(key), - nt_errstr(status))); + DBG_WARNING("key '%s' ndr_push - %s\n", + tdb_data_dbg(key), + ndr_map_error2string(ndr_err)); TALLOC_FREE(global->db_rec); - return status; + return ndr_map_error2ntstatus(ndr_err); } val = make_tdb_data(blob.data, blob.length); status = dbwrap_record_store(global->db_rec, val, TDB_REPLACE); TALLOC_FREE(blob.data); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1,("smbXsrv_open_global_store: key '%s' store - %s\n", - tdb_data_dbg(key), - nt_errstr(status))); + DBG_WARNING("key '%s' store - %s\n", + tdb_data_dbg(key), + nt_errstr(status)); TALLOC_FREE(global->db_rec); return status; } if (CHECK_DEBUGLVL(10)) { - DEBUG(10,("smbXsrv_open_global_store: key '%s' stored\n", - tdb_data_dbg(key))); + DBG_DEBUG("key '%s' stored\n", tdb_data_dbg(key)); NDR_PRINT_DEBUG(smbXsrv_open_globalB, &global_blob); } @@ -536,8 +491,6 @@ static NTSTATUS smbXsrv_open_global_lookup(struct smbXsrv_open_table *table, (*_global)->db_rec = talloc_move(*_global, &global_rec); - talloc_set_destructor(*_global, smbXsrv_open_global_destructor); - return NT_STATUS_OK; } @@ -599,13 +552,25 @@ NTSTATUS smbXsrv_open_create(struct smbXsrv_connection *conn, op->status = NT_STATUS_OK; /* TODO: start with INTERNAL_ERROR */ op->idle_time = now; - status = smbXsrv_open_global_allocate(table->global.db_ctx, - op, &global); + global = talloc_zero(op, struct smbXsrv_open_global0); + if (global == NULL) { + TALLOC_FREE(op); + return NT_STATUS_NO_MEMORY; + } + op->global = global; + + /* + * We mark every slot as invalid using 0xFF. + * Valid values are masked with 0xF. + */ + memset(global->lock_sequence_array, 0xFF, + sizeof(global->lock_sequence_array)); + + status = smbXsrv_open_global_allocate(table->global.db_ctx, global); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(op); return status; } - op->global = global; local_id = idr_get_new_random( table->local.idr, @@ -1211,8 +1176,7 @@ NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn, { struct smbXsrv_open_table *table = conn->client->open_table; struct smbXsrv_open *op = NULL; - uint32_t global_id = persistent_id & UINT32_MAX; - uint64_t global_zeros = persistent_id & 0xFFFFFFFF00000000LLU; + uint32_t global_id; NTSTATUS status; struct security_token *current_token = NULL; int local_id; @@ -1228,10 +1192,14 @@ NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn, return NT_STATUS_INVALID_HANDLE; } - if (global_zeros != 0) { - DEBUG(10, ("global_zeros!=0\n")); + if ((persistent_id & 0xFFFFFFFF00000000LLU) != 0) { + /* + * We only use 32 bit for the persistent ID + */ + DBG_DEBUG("persistent_id=%"PRIx64"\n", persistent_id); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + global_id = persistent_id & UINT32_MAX; /* truncate to 32 bit */ op = talloc_zero(table, struct smbXsrv_open); if (op == NULL) { diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c index bedda07a72b..bf4a976eaee 100644 --- a/third_party/socket_wrapper/socket_wrapper.c +++ b/third_party/socket_wrapper/socket_wrapper.c @@ -47,6 +47,12 @@ #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> +#ifdef HAVE_SYS_SYSCALL_H +#include <sys/syscall.h> +#endif +#ifdef HAVE_SYSCALL_H +#include <syscall.h> +#endif #include <sys/socket.h> #include <sys/ioctl.h> #ifdef HAVE_SYS_FILIO_H @@ -537,8 +543,29 @@ typedef int (*__libc_recvfrom)(int sockfd, struct sockaddr *src_addr, socklen_t *addrlen); typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags); +#ifdef HAVE_RECVMMSG +#if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT) +/* FreeBSD */ +typedef ssize_t (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout); +#elif defined(HAVE_RECVMMSG_CONST_TIMEOUT) +/* Linux legacy glibc < 2.21 */ +typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout); +#else +/* Linux glibc >= 2.21 */ +typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); +#endif +#endif /* HAVE_RECVMMSG */ typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags); typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags); +#ifdef HAVE_SENDMMSG +#if defined(HAVE_SENDMMSG_SSIZE_T) +/* FreeBSD */ +typedef ssize_t (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags); +#else +/* Linux */ +typedef int (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags); +#endif +#endif /* HAVE_SENDMMSG */ typedef int (*__libc_sendto)(int sockfd, const void *buf, size_t len, @@ -560,6 +587,9 @@ typedef int (*__libc_timerfd_create)(int clockid, int flags); #endif typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count); typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt); +#ifdef HAVE_SYSCALL +typedef long int (*__libc_syscall)(long int sysno, ...); +#endif #define SWRAP_SYMBOL_ENTRY(i) \ union { \ @@ -605,8 +635,14 @@ struct swrap_libc_symbols { SWRAP_SYMBOL_ENTRY(recv); SWRAP_SYMBOL_ENTRY(recvfrom); SWRAP_SYMBOL_ENTRY(recvmsg); +#ifdef HAVE_RECVMMSG + SWRAP_SYMBOL_ENTRY(recvmmsg); +#endif SWRAP_SYMBOL_ENTRY(send); SWRAP_SYMBOL_ENTRY(sendmsg); +#ifdef HAVE_SENDMMSG + SWRAP_SYMBOL_ENTRY(sendmmsg); +#endif SWRAP_SYMBOL_ENTRY(sendto); SWRAP_SYMBOL_ENTRY(setsockopt); #ifdef HAVE_SIGNALFD @@ -619,7 +655,32 @@ struct swrap_libc_symbols { #endif SWRAP_SYMBOL_ENTRY(write); SWRAP_SYMBOL_ENTRY(writev); +#ifdef HAVE_SYSCALL + SWRAP_SYMBOL_ENTRY(syscall); +#endif }; +#undef SWRAP_SYMBOL_ENTRY + +#define SWRAP_SYMBOL_ENTRY(i) \ + union { \ + __rtld_default_##i f; \ + void *obj; \ + } _rtld_default_##i + +#ifdef HAVE_SYSCALL +typedef bool (*__rtld_default_uid_wrapper_syscall_valid)(long int sysno); +typedef long int (*__rtld_default_uid_wrapper_syscall_va)(long int sysno, va_list va); +#endif + +struct swrap_rtld_default_symbols { +#ifdef HAVE_SYSCALL + SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_valid); + SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_va); +#else + uint8_t dummy; +#endif +}; +#undef SWRAP_SYMBOL_ENTRY struct swrap { struct { @@ -627,6 +688,10 @@ struct swrap { void *socket_handle; struct swrap_libc_symbols symbols; } libc; + + struct { + struct swrap_rtld_default_symbols symbols; + } rtld_default; }; static struct swrap swrap; @@ -807,6 +872,11 @@ static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const #define swrap_bind_symbol_libsocket(sym_name) \ _swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name) +#define swrap_bind_symbol_rtld_default_optional(sym_name) do { \ + swrap.rtld_default.symbols._rtld_default_##sym_name.obj = \ + dlsym(RTLD_DEFAULT, #sym_name); \ +} while(0); + static void swrap_bind_symbol_all(void); /**************************************************************************** @@ -1131,6 +1201,24 @@ static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags) return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags); } +#ifdef HAVE_RECVMMSG +#if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT) +/* FreeBSD */ +static ssize_t libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout) +#elif defined(HAVE_RECVMMSG_CONST_TIMEOUT) +/* Linux legacy glibc < 2.21 */ +static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout) +#else +/* Linux glibc >= 2.21 */ +static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) +#endif +{ + swrap_bind_symbol_all(); + + return swrap.libc.symbols._libc_recvmmsg.f(sockfd, msgvec, vlen, flags, timeout); +} +#endif + static int libc_send(int sockfd, const void *buf, size_t len, int flags) { swrap_bind_symbol_all(); @@ -1145,6 +1233,21 @@ static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags) return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags); } +#ifdef HAVE_SENDMMSG +#if defined(HAVE_SENDMMSG_SSIZE_T) +/* FreeBSD */ +static ssize_t libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags) +#else +/* Linux */ +static int libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags) +#endif +{ + swrap_bind_symbol_all(); + + return swrap.libc.symbols._libc_sendmmsg.f(sockfd, msgvec, vlen, flags); +} +#endif + static int libc_sendto(int sockfd, const void *buf, size_t len, @@ -1223,6 +1326,64 @@ static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt) return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt); } +#ifdef HAVE_SYSCALL +DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE +static long int libc_vsyscall(long int sysno, va_list va) +{ + long int args[8]; + long int rc; + int i; + + swrap_bind_symbol_all(); + + for (i = 0; i < 8; i++) { + args[i] = va_arg(va, long int); + } + + rc = swrap.libc.symbols._libc_syscall.f(sysno, + args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + args[7]); + + return rc; +} + +static bool swrap_uwrap_syscall_valid(long int sysno) +{ + swrap_bind_symbol_all(); + + if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f == NULL) { + return false; + } + + return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f( + sysno); +} + +DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE +static long int swrap_uwrap_syscall_va(long int sysno, va_list va) +{ + swrap_bind_symbol_all(); + + if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f == NULL) { + /* + * Fallback to libc, if uid_wrapper_syscall_va is not + * available. + */ + return libc_vsyscall(sysno, va); + } + + return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f( + sysno, + va); +} +#endif /* HAVE_SYSCALL */ + /* DO NOT call this function during library initialization! */ static void __swrap_bind_symbol_all_once(void) { @@ -1263,8 +1424,14 @@ static void __swrap_bind_symbol_all_once(void) swrap_bind_symbol_libsocket(recv); swrap_bind_symbol_libsocket(recvfrom); swrap_bind_symbol_libsocket(recvmsg); +#ifdef HAVE_RECVMMSG + swrap_bind_symbol_libsocket(recvmmsg); +#endif swrap_bind_symbol_libsocket(send); swrap_bind_symbol_libsocket(sendmsg); +#ifdef HAVE_SENDMMSG + swrap_bind_symbol_libsocket(sendmmsg); +#endif swrap_bind_symbol_libsocket(sendto); swrap_bind_symbol_libsocket(setsockopt); #ifdef HAVE_SIGNALFD -- Samba Shared Repository