[PATCHSET] Add support for FALL_THROUGH in switch statements

Andreas Schneider asn at samba.org
Fri Oct 13 15:09:31 UTC 2017


On Friday, 13 October 2017 11:55:10 CEST Andreas Schneider via samba-technical 
wrote:
> On Friday, 13 October 2017 11:33:42 CEST Andreas Schneider via
> samba-technical
> wrote:
> > Hi,
> > 
> > gcc offers a new flag to detect unwanted "fall through" in switch
> > statements. The flag is -Wimplicit-fallthrough and we should make use of
> > it
> > (if available).
> > 
> > To mark a *wanted* fall trough in a switch statement there is an attribute
> > in gcc now.
> > 
> > The attached patchset makes use of it! It also updates socket_wrapper to
> > version 1.1.8 which got support for FALL_THROUGH first!
> > 
> > 
> > Please review and push if appropriate.
> 
> Metze asked to always turn it on in developer mode not only in picky-
> developer. So the last patch got updated.

Forgot to bump the socket_wrapper version number. Attached patch does this 
now.


Please review.


Thanks,


	Andreas

-- 
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             asn at samba.org
www.samba.org
-------------- next part --------------
>From d7186730d0f5ecc9f4e3bd0bcd377c9ef8c7e8d6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:16:43 +0200
Subject: [PATCH 01/60] s4:lib:com: Fix function declartions

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/lib/com/classes/simple.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/source4/lib/com/classes/simple.c b/source4/lib/com/classes/simple.c
index 7d0573372e3..4d28a158102 100644
--- a/source4/lib/com/classes/simple.c
+++ b/source4/lib/com/classes/simple.c
@@ -43,13 +43,22 @@ static uint32_t simple_IUnknown_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx
 	return 1;
 }
 
-static WERROR simple_IStream_Read (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *pv, uint32_t num_requested, uint32_t *num_readx, uint32_t num_read)
+static WERROR simple_IStream_Read(struct IStream *d,
+				  TALLOC_CTX *mem_ctx,
+				  uint8_t *pv,
+				  uint32_t num_requested,
+				  uint32_t *num_readx,
+				  uint32_t *num_read)
 {
-	printf("%d bytes are being read\n", num_read);
+	printf("%d bytes are being read\n", *num_read);
 	return WERR_OK;
 }
 
-static WERROR simple_IStream_Write (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *data, uint32_t num_requested, uint32_t num_written)
+static WERROR simple_IStream_Write(struct IStream *d,
+				   TALLOC_CTX *mem_ctx,
+				   uint8_t *data,
+				   uint32_t num_requested,
+				   uint32_t *num_written)
 {
 	printf("%d bytes are being written\n", num_requested);
 	return WERR_OK;
@@ -62,7 +71,11 @@ static WERROR simpleclass_IUnknown_QueryInterface (struct IUnknown *d, TALLOC_CT
 	return WERR_OK;
 }
 
-static WERROR simpleclass_IClassFactory_CreateInstance (struct IClassFactory *d, TALLOC_CTX *mem_ctx, struct IUnknown *iunk, struct GUID *iid, struct IUnknown **ppv)
+static WERROR simpleclass_IClassFactory_CreateInstance(struct IClassFactory *d,
+						       TALLOC_CTX *mem_ctx,
+						       struct MInterfacePointer *pUnknown,
+						       struct GUID *iid,
+						       struct MInterfacePointer *ppv)
 {
 	struct IStream *ret;
 	/* FIXME: Check whether IID == ISTREAM_IID */
@@ -71,8 +84,8 @@ static WERROR simpleclass_IClassFactory_CreateInstance (struct IClassFactory *d,
 	ret->vtable = &simple_IStream_vtable;
 	ret->object_data = NULL;
 
-	*ppv = (struct IUnknown *)ret;
-	
+	ppv = (struct MInterfacePointer *)ret;
+
 	return WERR_OK;
 }
 
-- 
2.14.2


>From 53bc116bea6d3820addccc4922864a93210eac70 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:33:10 +0200
Subject: [PATCH 02/60] lib:replace: Add FALL_THROUGH support

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 .ycm_extra_conf.py    |  1 +
 lib/replace/replace.h |  9 +++++++++
 lib/replace/wscript   | 31 +++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
index 580669bddeb..76f4c8e14bf 100644
--- a/.ycm_extra_conf.py
+++ b/.ycm_extra_conf.py
@@ -47,6 +47,7 @@ flags = [
     '-D_XOPEN_SOURCE_EXTENDED=1',
     '-DAD_DC_BUILD_IS_ENABLED=1',
     '-DHAVE_IPV6=1',
+    '-DFALL_THROUGH',
     '-I/usr/local/include',
     '-I.',
     '-Iinclude',
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 128978c561e..e142dd1dbea 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -922,6 +922,15 @@ void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
 #define setproctitle_init rep_setproctitle_init
 void rep_setproctitle_init(int argc, char *argv[], char *envp[]);
 #endif
+
+#ifndef FALL_THROUGH
+# ifdef HAVE_FALLTHROUGH_ATTRIBUTE
+#  define FALL_THROUGH __attribute__ ((fallthrough))
+# else /* HAVE_FALLTHROUGH_ATTRIBUTE */
+#  define FALL_THROUGH
+# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
+#endif /* FALL_THROUGH */
+
 bool nss_wrapper_enabled(void);
 bool nss_wrapper_hosts_enabled(void);
 bool socket_wrapper_enabled(void);
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 952663257fa..a86124d50af 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -219,6 +219,37 @@ def configure(conf):
                     headers='stdint.h sys/atomic.h',
                     msg='Checking for atomic_add_32 compiler builtin')
 
+    conf.CHECK_CODE('''
+                    #define FALL_THROUGH __attribute__((fallthrough))
+
+                    enum direction_e {
+                        UP = 0,
+                        DOWN,
+                    };
+
+                    int main(void) {
+                        enum direction_e key = UP;
+                        int i = 10;
+                        int j = 0;
+
+                        switch (key) {
+                        case UP:
+                            i = 5;
+                            FALL_THROUGH;
+                        case DOWN:
+                            j = i * 2;
+                            break;
+                        default:
+                            break;
+                        }
+
+                        return 0;
+                    }
+                    ''',
+                    'HAVE_FALLTHROUGH_ATTRIBUTE',
+                    addmain=False,
+                    msg='Checking for fallthrough attribute')
+
     # these may be builtins, so we need the link=False strategy
     conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False)
 
-- 
2.14.2


>From e780fb0bc932a35d365a2ef2b1f7ca480f110057 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:01:04 +0200
Subject: [PATCH 03/60] swrap: Update socket_wrapper to 1.1.8

  * Added support for openat()
  * Added support for open64() and fopen64()
  * Always enabled logging support
  * Increased maximum for wrapped interfaces to 64
  * Improved fd duplication code
  * Fixed strict-aliasing issues
  * Fixed some use after free issues
  * Fixed issues on ppc64le

  * This also adds FALL_TROUGH!

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/socket_wrapper/socket_wrapper.c | 1221 +++++++++++++++++++++++++----------
 lib/socket_wrapper/wscript          |    2 +-
 2 files changed, 883 insertions(+), 340 deletions(-)

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index ba289e6fbaf..ccbe67f0970 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -79,6 +79,7 @@
 #ifdef HAVE_RPC_RPC_H
 #include <rpc/rpc.h>
 #endif
+#include <pthread.h>
 
 enum swrap_dbglvl_e {
 	SWRAP_LOG_ERROR = 0,
@@ -94,12 +95,26 @@ enum swrap_dbglvl_e {
 #define PRINTF_ATTRIBUTE(a,b)
 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
 
+#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
+#define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
+#else
+#define CONSTRUCTOR_ATTRIBUTE
+#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
+
 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
 #else
 #define DESTRUCTOR_ATTRIBUTE
 #endif
 
+#ifndef FALL_THROUGH
+# ifdef HAVE_FALLTHROUGH_ATTRIBUTE
+#  define FALL_THROUGH __attribute__ ((fallthrough))
+# else /* HAVE_FALLTHROUGH_ATTRIBUTE */
+#  define FALL_THROUGH
+# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
+#endif /* FALL_THROUGH */
+
 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
 #else
@@ -135,6 +150,8 @@ enum swrap_dbglvl_e {
 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
 #endif
 
+#define UNUSED(x) (void)(x)
+
 #ifdef IPV6_PKTINFO
 # ifndef IPV6_RECVPKTINFO
 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
@@ -152,6 +169,22 @@ enum swrap_dbglvl_e {
 # endif
 #endif
 
+/* Macros for accessing mutexes */
+# define SWRAP_LOCK(m) do { \
+	pthread_mutex_lock(&(m ## _mutex)); \
+} while(0)
+
+# define SWRAP_UNLOCK(m) do { \
+	pthread_mutex_unlock(&(m ## _mutex)); \
+} while(0)
+
+/* Add new global locks here please */
+# define SWRAP_LOCK_ALL \
+	SWRAP_LOCK(libc_symbol_binding); \
+
+# define SWRAP_UNLOCK_ALL \
+	SWRAP_UNLOCK(libc_symbol_binding); \
+
 
 #define SWRAP_DLIST_ADD(list,item) do { \
 	if (!(list)) { \
@@ -184,6 +217,20 @@ enum swrap_dbglvl_e {
 	(item)->next	= NULL; \
 } while (0)
 
+#define SWRAP_DLIST_ADD_AFTER(list, item, el) \
+do { \
+	if ((list) == NULL || (el) == NULL) { \
+		SWRAP_DLIST_ADD(list, item); \
+	} else { \
+		(item)->prev = (el); \
+		(item)->next = (el)->next; \
+		(el)->next = (item); \
+		if ((item)->next != NULL) { \
+			(item)->next->prev = (item); \
+		} \
+	} \
+} while (0)
+
 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
 #else
@@ -212,10 +259,20 @@ enum swrap_dbglvl_e {
 
 #define SOCKET_MAX_SOCKETS 1024
 
+
+/*
+ * Maximum number of socket_info structures that can
+ * be used. Can be overriden by the environment variable
+ * SOCKET_WRAPPER_MAX_SOCKETS.
+ */
+#define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
+
+#define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 256000
+
 /* This limit is to avoid broadcast sendto() needing to stat too many
  * files.  It may be raised (with a performance cost) to up to 254
  * without changing the format above */
-#define MAX_WRAPPED_INTERFACES 40
+#define MAX_WRAPPED_INTERFACES 64
 
 struct swrap_address {
 	socklen_t sa_socklen;
@@ -233,11 +290,21 @@ struct swrap_address {
 struct socket_info_fd {
 	struct socket_info_fd *prev, *next;
 	int fd;
+
+	/*
+	 * Points to corresponding index in array of
+	 * socket_info structures
+	 */
+	int si_index;
 };
 
+int first_free;
+
 struct socket_info
 {
-	struct socket_info_fd *fds;
+	unsigned int refcount;
+
+	int next_free;
 
 	int family;
 	int type;
@@ -261,24 +328,27 @@ struct socket_info
 		unsigned long pck_snd;
 		unsigned long pck_rcv;
 	} io;
-
-	struct socket_info *prev, *next;
 };
 
+static struct socket_info *sockets;
+static size_t max_sockets = 0;
+
 /*
- * File descriptors are shared between threads so we should share socket
- * information too.
+ * While socket file descriptors are passed among different processes, the
+ * numerical value gets changed. So its better to store it locally to each
+ * process rather than including it within socket_info which will be shared.
  */
-struct socket_info *sockets;
+static struct socket_info_fd *socket_fds;
+
+/* The mutex for accessing the global libc.symbols */
+static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Function prototypes */
 
 bool socket_wrapper_enabled(void);
-void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
 
-#ifdef NDEBUG
-# define SWRAP_LOG(...)
-#else
+void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
+void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
 
 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
@@ -291,42 +361,40 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl,
 	va_list va;
 	const char *d;
 	unsigned int lvl = 0;
+	const char *prefix = "SWRAP";
 
 	d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
 	if (d != NULL) {
 		lvl = atoi(d);
 	}
 
+	if (lvl < dbglvl) {
+		return;
+	}
+
 	va_start(va, format);
 	vsnprintf(buffer, sizeof(buffer), format, va);
 	va_end(va);
 
-	if (lvl >= dbglvl) {
-		switch (dbglvl) {
-			case SWRAP_LOG_ERROR:
-				fprintf(stderr,
-					"SWRAP_ERROR(%d) - %s: %s\n",
-					(int)getpid(), func, buffer);
-				break;
-			case SWRAP_LOG_WARN:
-				fprintf(stderr,
-					"SWRAP_WARN(%d) - %s: %s\n",
-					(int)getpid(), func, buffer);
-				break;
-			case SWRAP_LOG_DEBUG:
-				fprintf(stderr,
-					"SWRAP_DEBUG(%d) - %s: %s\n",
-					(int)getpid(), func, buffer);
-				break;
-			case SWRAP_LOG_TRACE:
-				fprintf(stderr,
-					"SWRAP_TRACE(%d) - %s: %s\n",
-					(int)getpid(), func, buffer);
-				break;
-		}
+	switch (dbglvl) {
+		case SWRAP_LOG_ERROR:
+			prefix = "SWRAP_ERROR";
+			break;
+		case SWRAP_LOG_WARN:
+			prefix = "SWRAP_WARN";
+			break;
+		case SWRAP_LOG_DEBUG:
+			prefix = "SWRAP_DEBUG";
+			break;
+		case SWRAP_LOG_TRACE:
+			prefix = "SWRAP_TRACE";
+			break;
 	}
+
+	fprintf(stderr,
+		"%s(%d) - %s: %s\n",
+		prefix, (int)getpid(), func, buffer);
 }
-#endif
 
 /*********************************************************
  * SWRAP LOADING LIBC FUNCTIONS
@@ -334,91 +402,149 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl,
 
 #include <dlfcn.h>
 
-struct swrap_libc_fns {
 #ifdef HAVE_ACCEPT4
-	int (*libc_accept4)(int sockfd,
-			   struct sockaddr *addr,
-			   socklen_t *addrlen,
-			   int flags);
+typedef int (*__libc_accept4)(int sockfd,
+			      struct sockaddr *addr,
+			      socklen_t *addrlen,
+			      int flags);
 #else
-	int (*libc_accept)(int sockfd,
-			   struct sockaddr *addr,
-			   socklen_t *addrlen);
+typedef int (*__libc_accept)(int sockfd,
+			     struct sockaddr *addr,
+			     socklen_t *addrlen);
+#endif
+typedef int (*__libc_bind)(int sockfd,
+			   const struct sockaddr *addr,
+			   socklen_t addrlen);
+typedef int (*__libc_close)(int fd);
+typedef int (*__libc_connect)(int sockfd,
+			      const struct sockaddr *addr,
+			      socklen_t addrlen);
+typedef int (*__libc_dup)(int fd);
+typedef int (*__libc_dup2)(int oldfd, int newfd);
+typedef int (*__libc_fcntl)(int fd, int cmd, ...);
+typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
+#ifdef HAVE_FOPEN64
+typedef FILE *(*__libc_fopen64)(const char *name, const char *mode);
 #endif
-	int (*libc_bind)(int sockfd,
-			 const struct sockaddr *addr,
-			 socklen_t addrlen);
-	int (*libc_close)(int fd);
-	int (*libc_connect)(int sockfd,
-			    const struct sockaddr *addr,
-			    socklen_t addrlen);
-	int (*libc_dup)(int fd);
-	int (*libc_dup2)(int oldfd, int newfd);
-	int (*libc_fcntl)(int fd, int cmd, ...);
-	FILE *(*libc_fopen)(const char *name, const char *mode);
 #ifdef HAVE_EVENTFD
-	int (*libc_eventfd)(int count, int flags);
+typedef int (*__libc_eventfd)(int count, int flags);
 #endif
-	int (*libc_getpeername)(int sockfd,
-				struct sockaddr *addr,
-				socklen_t *addrlen);
-	int (*libc_getsockname)(int sockfd,
-				struct sockaddr *addr,
-				socklen_t *addrlen);
-	int (*libc_getsockopt)(int sockfd,
+typedef int (*__libc_getpeername)(int sockfd,
+				  struct sockaddr *addr,
+				  socklen_t *addrlen);
+typedef int (*__libc_getsockname)(int sockfd,
+				  struct sockaddr *addr,
+				  socklen_t *addrlen);
+typedef int (*__libc_getsockopt)(int sockfd,
 			       int level,
 			       int optname,
 			       void *optval,
 			       socklen_t *optlen);
-	int (*libc_ioctl)(int d, unsigned long int request, ...);
-	int (*libc_listen)(int sockfd, int backlog);
-	int (*libc_open)(const char *pathname, int flags, mode_t mode);
-	int (*libc_pipe)(int pipefd[2]);
-	int (*libc_read)(int fd, void *buf, size_t count);
-	ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
-	int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
-	int (*libc_recvfrom)(int sockfd,
+typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
+typedef int (*__libc_listen)(int sockfd, int backlog);
+typedef int (*__libc_open)(const char *pathname, int flags, ...);
+#ifdef HAVE_OPEN64
+typedef int (*__libc_open64)(const char *pathname, int flags, ...);
+#endif /* HAVE_OPEN64 */
+typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
+typedef int (*__libc_pipe)(int pipefd[2]);
+typedef int (*__libc_read)(int fd, void *buf, size_t count);
+typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
+typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
+typedef int (*__libc_recvfrom)(int sockfd,
 			     void *buf,
 			     size_t len,
 			     int flags,
 			     struct sockaddr *src_addr,
 			     socklen_t *addrlen);
-	int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
-	int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
-	int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
-	int (*libc_sendto)(int sockfd,
+typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
+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);
+typedef int (*__libc_sendto)(int sockfd,
 			   const void *buf,
 			   size_t len,
 			   int flags,
 			   const  struct sockaddr *dst_addr,
 			   socklen_t addrlen);
-	int (*libc_setsockopt)(int sockfd,
+typedef int (*__libc_setsockopt)(int sockfd,
 			       int level,
 			       int optname,
 			       const void *optval,
 			       socklen_t optlen);
 #ifdef HAVE_SIGNALFD
-	int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
+typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
 #endif
-	int (*libc_socket)(int domain, int type, int protocol);
-	int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
+typedef int (*__libc_socket)(int domain, int type, int protocol);
+typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
 #ifdef HAVE_TIMERFD_CREATE
-	int (*libc_timerfd_create)(int clockid, int flags);
+typedef int (*__libc_timerfd_create)(int clockid, int flags);
 #endif
-	ssize_t (*libc_write)(int fd, const void *buf, size_t count);
-	ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
-};
-
-struct swrap {
-	void *libc_handle;
-	void *libsocket_handle;
+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);
 
-	bool initialised;
-	bool enabled;
+#define SWRAP_SYMBOL_ENTRY(i) \
+	union { \
+		__libc_##i f; \
+		void *obj; \
+	} _libc_##i
 
-	char *socket_dir;
+struct swrap_libc_symbols {
+#ifdef HAVE_ACCEPT4
+	SWRAP_SYMBOL_ENTRY(accept4);
+#else
+	SWRAP_SYMBOL_ENTRY(accept);
+#endif
+	SWRAP_SYMBOL_ENTRY(bind);
+	SWRAP_SYMBOL_ENTRY(close);
+	SWRAP_SYMBOL_ENTRY(connect);
+	SWRAP_SYMBOL_ENTRY(dup);
+	SWRAP_SYMBOL_ENTRY(dup2);
+	SWRAP_SYMBOL_ENTRY(fcntl);
+	SWRAP_SYMBOL_ENTRY(fopen);
+#ifdef HAVE_FOPEN64
+	SWRAP_SYMBOL_ENTRY(fopen64);
+#endif
+#ifdef HAVE_EVENTFD
+	SWRAP_SYMBOL_ENTRY(eventfd);
+#endif
+	SWRAP_SYMBOL_ENTRY(getpeername);
+	SWRAP_SYMBOL_ENTRY(getsockname);
+	SWRAP_SYMBOL_ENTRY(getsockopt);
+	SWRAP_SYMBOL_ENTRY(ioctl);
+	SWRAP_SYMBOL_ENTRY(listen);
+	SWRAP_SYMBOL_ENTRY(open);
+#ifdef HAVE_OPEN64
+	SWRAP_SYMBOL_ENTRY(open64);
+#endif
+	SWRAP_SYMBOL_ENTRY(openat);
+	SWRAP_SYMBOL_ENTRY(pipe);
+	SWRAP_SYMBOL_ENTRY(read);
+	SWRAP_SYMBOL_ENTRY(readv);
+	SWRAP_SYMBOL_ENTRY(recv);
+	SWRAP_SYMBOL_ENTRY(recvfrom);
+	SWRAP_SYMBOL_ENTRY(recvmsg);
+	SWRAP_SYMBOL_ENTRY(send);
+	SWRAP_SYMBOL_ENTRY(sendmsg);
+	SWRAP_SYMBOL_ENTRY(sendto);
+	SWRAP_SYMBOL_ENTRY(setsockopt);
+#ifdef HAVE_SIGNALFD
+	SWRAP_SYMBOL_ENTRY(signalfd);
+#endif
+	SWRAP_SYMBOL_ENTRY(socket);
+	SWRAP_SYMBOL_ENTRY(socketpair);
+#ifdef HAVE_TIMERFD_CREATE
+	SWRAP_SYMBOL_ENTRY(timerfd_create);
+#endif
+	SWRAP_SYMBOL_ENTRY(write);
+	SWRAP_SYMBOL_ENTRY(writev);
+};
 
-	struct swrap_libc_fns fns;
+struct swrap {
+	struct {
+		void *handle;
+		void *socket_handle;
+		struct swrap_libc_symbols symbols;
+	} libc;
 };
 
 static struct swrap swrap;
@@ -434,7 +560,6 @@ enum swrap_lib {
     SWRAP_LIBSOCKET,
 };
 
-#ifndef NDEBUG
 static const char *swrap_str_lib(enum swrap_lib lib)
 {
 	switch (lib) {
@@ -449,7 +574,6 @@ static const char *swrap_str_lib(enum swrap_lib lib)
 	/* Compiler would warn us about unhandled enum value if we get here */
 	return "unknown";
 }
-#endif
 
 static void *swrap_load_lib_handle(enum swrap_lib lib)
 {
@@ -463,10 +587,10 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 
 	switch (lib) {
 	case SWRAP_LIBNSL:
-		/* FALL TROUGH */
+		FALL_THROUGH;
 	case SWRAP_LIBSOCKET:
 #ifdef HAVE_LIBSOCKET
-		handle = swrap.libsocket_handle;
+		handle = swrap.libc.socket_handle;
 		if (handle == NULL) {
 			for (i = 10; i >= 0; i--) {
 				char soname[256] = {0};
@@ -478,18 +602,18 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 				}
 			}
 
-			swrap.libsocket_handle = handle;
+			swrap.libc.socket_handle = handle;
 		}
 		break;
 #endif
-		/* FALL TROUGH */
+		FALL_THROUGH;
 	case SWRAP_LIBC:
-		handle = swrap.libc_handle;
+		handle = swrap.libc.handle;
 #ifdef LIBC_SO
 		if (handle == NULL) {
 			handle = dlopen(LIBC_SO, flags);
 
-			swrap.libc_handle = handle;
+			swrap.libc.handle = handle;
 		}
 #endif
 		if (handle == NULL) {
@@ -503,14 +627,14 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 				}
 			}
 
-			swrap.libc_handle = handle;
+			swrap.libc.handle = handle;
 		}
 		break;
 	}
 
 	if (handle == NULL) {
 #ifdef RTLD_NEXT
-		handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
+		handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
 #else
 		SWRAP_LOG(SWRAP_LOG_ERROR,
 			  "Failed to dlopen library: %s\n",
@@ -522,7 +646,7 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 	return handle;
 }
 
-static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
+static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
 {
 	void *handle;
 	void *func;
@@ -532,24 +656,43 @@ static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
 	func = dlsym(handle, fn_name);
 	if (func == NULL) {
 		SWRAP_LOG(SWRAP_LOG_ERROR,
-				"Failed to find %s: %s\n",
-				fn_name, dlerror());
+			  "Failed to find %s: %s\n",
+			  fn_name,
+			  dlerror());
 		exit(-1);
 	}
 
 	SWRAP_LOG(SWRAP_LOG_TRACE,
-			"Loaded %s from %s",
-			fn_name, swrap_str_lib(lib));
+		  "Loaded %s from %s",
+		  fn_name,
+		  swrap_str_lib(lib));
+
 	return func;
 }
 
-#define swrap_load_lib_function(lib, fn_name) \
-	if (swrap.fns.libc_##fn_name == NULL) { \
-		void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); \
-		*(void **) (&swrap.fns.libc_##fn_name) = \
-			swrap_cast_ptr; \
-	}
+#define swrap_bind_symbol_libc(sym_name) \
+	SWRAP_LOCK(libc_symbol_binding); \
+	if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+		swrap.libc.symbols._libc_##sym_name.obj = \
+			_swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
+	} \
+	SWRAP_UNLOCK(libc_symbol_binding)
 
+#define swrap_bind_symbol_libsocket(sym_name) \
+	SWRAP_LOCK(libc_symbol_binding); \
+	if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+		swrap.libc.symbols._libc_##sym_name.obj = \
+			_swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \
+	} \
+	SWRAP_UNLOCK(libc_symbol_binding)
+
+#define swrap_bind_symbol_libnsl(sym_name) \
+	SWRAP_LOCK(libc_symbol_binding); \
+	if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+		swrap.libc.symbols._libc_##sym_name.obj = \
+			_swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \
+	} \
+	SWRAP_UNLOCK(libc_symbol_binding)
 
 /*
  * IMPORTANT
@@ -565,18 +708,18 @@ static int libc_accept4(int sockfd,
 			socklen_t *addrlen,
 			int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, accept4);
+	swrap_bind_symbol_libsocket(accept4);
 
-	return swrap.fns.libc_accept4(sockfd, addr, addrlen, flags);
+	return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
 }
 
 #else /* HAVE_ACCEPT4 */
 
 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
+	swrap_bind_symbol_libsocket(accept);
 
-	return swrap.fns.libc_accept(sockfd, addr, addrlen);
+	return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
 }
 #endif /* HAVE_ACCEPT4 */
 
@@ -584,69 +727,61 @@ static int libc_bind(int sockfd,
 		     const struct sockaddr *addr,
 		     socklen_t addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
+	swrap_bind_symbol_libsocket(bind);
 
-	return swrap.fns.libc_bind(sockfd, addr, addrlen);
+	return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
 }
 
 static int libc_close(int fd)
 {
-	swrap_load_lib_function(SWRAP_LIBC, close);
+	swrap_bind_symbol_libc(close);
 
-	return swrap.fns.libc_close(fd);
+	return swrap.libc.symbols._libc_close.f(fd);
 }
 
 static int libc_connect(int sockfd,
 			const struct sockaddr *addr,
 			socklen_t addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
+	swrap_bind_symbol_libsocket(connect);
 
-	return swrap.fns.libc_connect(sockfd, addr, addrlen);
+	return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
 }
 
 static int libc_dup(int fd)
 {
-	swrap_load_lib_function(SWRAP_LIBC, dup);
+	swrap_bind_symbol_libc(dup);
 
-	return swrap.fns.libc_dup(fd);
+	return swrap.libc.symbols._libc_dup.f(fd);
 }
 
 static int libc_dup2(int oldfd, int newfd)
 {
-	swrap_load_lib_function(SWRAP_LIBC, dup2);
+	swrap_bind_symbol_libc(dup2);
 
-	return swrap.fns.libc_dup2(oldfd, newfd);
+	return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
 }
 
 #ifdef HAVE_EVENTFD
 static int libc_eventfd(int count, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBC, eventfd);
+	swrap_bind_symbol_libc(eventfd);
 
-	return swrap.fns.libc_eventfd(count, flags);
+	return swrap.libc.symbols._libc_eventfd.f(count, flags);
 }
 #endif
 
 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
 static int libc_vfcntl(int fd, int cmd, va_list ap)
 {
-	long int args[4];
+	void *arg;
 	int rc;
-	int i;
 
-	swrap_load_lib_function(SWRAP_LIBC, fcntl);
+	swrap_bind_symbol_libc(fcntl);
 
-	for (i = 0; i < 4; i++) {
-		args[i] = va_arg(ap, long int);
-	}
+	arg = va_arg(ap, void *);
 
-	rc = swrap.fns.libc_fcntl(fd,
-				  cmd,
-				  args[0],
-				  args[1],
-				  args[2],
-				  args[3]);
+	rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
 
 	return rc;
 }
@@ -655,18 +790,18 @@ static int libc_getpeername(int sockfd,
 			    struct sockaddr *addr,
 			    socklen_t *addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
+	swrap_bind_symbol_libsocket(getpeername);
 
-	return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
+	return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen);
 }
 
 static int libc_getsockname(int sockfd,
 			    struct sockaddr *addr,
 			    socklen_t *addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
+	swrap_bind_symbol_libsocket(getsockname);
 
-	return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
+	return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen);
 }
 
 static int libc_getsockopt(int sockfd,
@@ -675,58 +810,64 @@ static int libc_getsockopt(int sockfd,
 			   void *optval,
 			   socklen_t *optlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
+	swrap_bind_symbol_libsocket(getsockopt);
 
-	return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
+	return swrap.libc.symbols._libc_getsockopt.f(sockfd,
+						     level,
+						     optname,
+						     optval,
+						     optlen);
 }
 
 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
 static int libc_vioctl(int d, unsigned long int request, va_list ap)
 {
-	long int args[4];
+	void *arg;
 	int rc;
-	int i;
 
-	swrap_load_lib_function(SWRAP_LIBC, ioctl);
+	swrap_bind_symbol_libc(ioctl);
 
-	for (i = 0; i < 4; i++) {
-		args[i] = va_arg(ap, long int);
-	}
+	arg = va_arg(ap, void *);
 
-	rc = swrap.fns.libc_ioctl(d,
-				  request,
-				  args[0],
-				  args[1],
-				  args[2],
-				  args[3]);
+	rc = swrap.libc.symbols._libc_ioctl.f(d, request, arg);
 
 	return rc;
 }
 
 static int libc_listen(int sockfd, int backlog)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
+	swrap_bind_symbol_libsocket(listen);
 
-	return swrap.fns.libc_listen(sockfd, backlog);
+	return swrap.libc.symbols._libc_listen.f(sockfd, backlog);
 }
 
 static FILE *libc_fopen(const char *name, const char *mode)
 {
-	swrap_load_lib_function(SWRAP_LIBC, fopen);
+	swrap_bind_symbol_libc(fopen);
 
-	return swrap.fns.libc_fopen(name, mode);
+	return swrap.libc.symbols._libc_fopen.f(name, mode);
 }
 
+#ifdef HAVE_FOPEN64
+static FILE *libc_fopen64(const char *name, const char *mode)
+{
+	swrap_bind_symbol_libc(fopen64);
+
+	return swrap.libc.symbols._libc_fopen64.f(name, mode);
+}
+#endif /* HAVE_FOPEN64 */
+
 static int libc_vopen(const char *pathname, int flags, va_list ap)
 {
-	long int mode = 0;
+	int mode = 0;
 	int fd;
 
-	swrap_load_lib_function(SWRAP_LIBC, open);
+	swrap_bind_symbol_libc(open);
 
-	mode = va_arg(ap, long int);
-
-	fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
+	if (flags & O_CREAT) {
+		mode = va_arg(ap, int);
+	}
+	fd = swrap.libc.symbols._libc_open.f(pathname, flags, (mode_t)mode);
 
 	return fd;
 }
@@ -743,32 +884,81 @@ static int libc_open(const char *pathname, int flags, ...)
 	return fd;
 }
 
+#ifdef HAVE_OPEN64
+static int libc_vopen64(const char *pathname, int flags, va_list ap)
+{
+	int mode = 0;
+	int fd;
+
+	swrap_bind_symbol_libc(open64);
+
+	if (flags & O_CREAT) {
+		mode = va_arg(ap, int);
+	}
+	fd = swrap.libc.symbols._libc_open64.f(pathname, flags, (mode_t)mode);
+
+	return fd;
+}
+#endif /* HAVE_OPEN64 */
+
+static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
+{
+	int mode = 0;
+	int fd;
+
+	swrap_bind_symbol_libc(openat);
+
+	if (flags & O_CREAT) {
+		mode = va_arg(ap, int);
+	}
+	fd = swrap.libc.symbols._libc_openat.f(dirfd,
+					       path,
+					       flags,
+					       (mode_t)mode);
+
+	return fd;
+}
+
+#if 0
+static int libc_openat(int dirfd, const char *path, int flags, ...)
+{
+	va_list ap;
+	int fd;
+
+	va_start(ap, flags);
+	fd = libc_vopenat(dirfd, path, flags, ap);
+	va_end(ap);
+
+	return fd;
+}
+#endif
+
 static int libc_pipe(int pipefd[2])
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
+	swrap_bind_symbol_libsocket(pipe);
 
-	return swrap.fns.libc_pipe(pipefd);
+	return swrap.libc.symbols._libc_pipe.f(pipefd);
 }
 
 static int libc_read(int fd, void *buf, size_t count)
 {
-	swrap_load_lib_function(SWRAP_LIBC, read);
+	swrap_bind_symbol_libc(read);
 
-	return swrap.fns.libc_read(fd, buf, count);
+	return swrap.libc.symbols._libc_read.f(fd, buf, count);
 }
 
 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
+	swrap_bind_symbol_libsocket(readv);
 
-	return swrap.fns.libc_readv(fd, iov, iovcnt);
+	return swrap.libc.symbols._libc_readv.f(fd, iov, iovcnt);
 }
 
 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
+	swrap_bind_symbol_libsocket(recv);
 
-	return swrap.fns.libc_recv(sockfd, buf, len, flags);
+	return swrap.libc.symbols._libc_recv.f(sockfd, buf, len, flags);
 }
 
 static int libc_recvfrom(int sockfd,
@@ -778,30 +968,35 @@ static int libc_recvfrom(int sockfd,
 			 struct sockaddr *src_addr,
 			 socklen_t *addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
+	swrap_bind_symbol_libsocket(recvfrom);
 
-	return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
+	return swrap.libc.symbols._libc_recvfrom.f(sockfd,
+						   buf,
+						   len,
+						   flags,
+						   src_addr,
+						   addrlen);
 }
 
 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
+	swrap_bind_symbol_libsocket(recvmsg);
 
-	return swrap.fns.libc_recvmsg(sockfd, msg, flags);
+	return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags);
 }
 
 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, send);
+	swrap_bind_symbol_libsocket(send);
 
-	return swrap.fns.libc_send(sockfd, buf, len, flags);
+	return swrap.libc.symbols._libc_send.f(sockfd, buf, len, flags);
 }
 
 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
+	swrap_bind_symbol_libsocket(sendmsg);
 
-	return swrap.fns.libc_sendmsg(sockfd, msg, flags);
+	return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags);
 }
 
 static int libc_sendto(int sockfd,
@@ -811,9 +1006,14 @@ static int libc_sendto(int sockfd,
 		       const  struct sockaddr *dst_addr,
 		       socklen_t addrlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
+	swrap_bind_symbol_libsocket(sendto);
 
-	return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
+	return swrap.libc.symbols._libc_sendto.f(sockfd,
+						 buf,
+						 len,
+						 flags,
+						 dst_addr,
+						 addrlen);
 }
 
 static int libc_setsockopt(int sockfd,
@@ -822,55 +1022,59 @@ static int libc_setsockopt(int sockfd,
 			   const void *optval,
 			   socklen_t optlen)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
+	swrap_bind_symbol_libsocket(setsockopt);
 
-	return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
+	return swrap.libc.symbols._libc_setsockopt.f(sockfd,
+						     level,
+						     optname,
+						     optval,
+						     optlen);
 }
 
 #ifdef HAVE_SIGNALFD
 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
+	swrap_bind_symbol_libsocket(signalfd);
 
-	return swrap.fns.libc_signalfd(fd, mask, flags);
+	return swrap.libc.symbols._libc_signalfd.f(fd, mask, flags);
 }
 #endif
 
 static int libc_socket(int domain, int type, int protocol)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
+	swrap_bind_symbol_libsocket(socket);
 
-	return swrap.fns.libc_socket(domain, type, protocol);
+	return swrap.libc.symbols._libc_socket.f(domain, type, protocol);
 }
 
 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
+	swrap_bind_symbol_libsocket(socketpair);
 
-	return swrap.fns.libc_socketpair(domain, type, protocol, sv);
+	return swrap.libc.symbols._libc_socketpair.f(domain, type, protocol, sv);
 }
 
 #ifdef HAVE_TIMERFD_CREATE
 static int libc_timerfd_create(int clockid, int flags)
 {
-	swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
+	swrap_bind_symbol_libc(timerfd_create);
 
-	return swrap.fns.libc_timerfd_create(clockid, flags);
+	return swrap.libc.symbols._libc_timerfd_create.f(clockid, flags);
 }
 #endif
 
 static ssize_t libc_write(int fd, const void *buf, size_t count)
 {
-	swrap_load_lib_function(SWRAP_LIBC, write);
+	swrap_bind_symbol_libc(write);
 
-	return swrap.fns.libc_write(fd, buf, count);
+	return swrap.libc.symbols._libc_write.f(fd, buf, count);
 }
 
 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
 {
-	swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
+	swrap_bind_symbol_libsocket(writev);
 
-	return swrap.fns.libc_writev(fd, iov, iovcnt);
+	return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt);
 }
 
 /*********************************************************
@@ -975,11 +1179,78 @@ done:
 	return max_mtu;
 }
 
+static size_t socket_wrapper_max_sockets(void)
+{
+	const char *s;
+	unsigned long tmp;
+	char *endp;
+
+	if (max_sockets != 0) {
+		return max_sockets;
+	}
+
+	max_sockets = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
+
+	s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
+	if (s == NULL || s[0] == '\0') {
+		goto done;
+	}
+
+	tmp = strtoul(s, &endp, 10);
+	if (s == endp) {
+		goto done;
+	}
+	if (tmp == 0 || tmp > SOCKET_WRAPPER_MAX_SOCKETS_LIMIT) {
+		SWRAP_LOG(SWRAP_LOG_ERROR,
+			  "Invalid number of sockets specified, using default.");
+		goto done;
+	}
+
+	max_sockets = tmp;
+
+done:
+	return max_sockets;
+}
+
+static void socket_wrapper_init_sockets(void)
+{
+	size_t i;
+
+	if (sockets != NULL) {
+		return;
+	}
+
+	max_sockets = socket_wrapper_max_sockets();
+
+	sockets = (struct socket_info *)calloc(max_sockets,
+					       sizeof(struct socket_info));
+
+	if (sockets == NULL) {
+		SWRAP_LOG(SWRAP_LOG_ERROR,
+			  "Failed to allocate sockets array.\n");
+		exit(-1);
+	}
+
+	first_free = 0;
+
+	for (i = 0; i < max_sockets; i++) {
+		sockets[i].next_free = i+1;
+	}
+
+	sockets[max_sockets-1].next_free = -1;
+}
+
 bool socket_wrapper_enabled(void)
 {
 	const char *s = socket_wrapper_dir();
 
-	return s != NULL ? true : false;
+	if (s == NULL) {
+		return false;
+	}
+
+	socket_wrapper_init_sockets();
+
+	return true;
 }
 
 static unsigned int socket_wrapper_default_iface(void)
@@ -997,6 +1268,25 @@ static unsigned int socket_wrapper_default_iface(void)
 	return 1;/* 127.0.0.1 */
 }
 
+/*
+ * Return the first free entry (if any) and make
+ * it re-usable again (by nulling it out)
+ */
+static int socket_wrapper_first_free_index(void)
+{
+	int next_free;
+
+	if (first_free == -1) {
+		return -1;
+	}
+
+	next_free = sockets[first_free].next_free;
+	ZERO_STRUCT(sockets[first_free]);
+	sockets[first_free].next_free = next_free;
+
+	return first_free;
+}
+
 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
 {
 	unsigned int iface;
@@ -1364,26 +1654,46 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 	return 0;
 }
 
-static struct socket_info *find_socket_info(int fd)
+static struct socket_info_fd *find_socket_info_fd(int fd)
 {
-	struct socket_info *i;
+	struct socket_info_fd *f;
 
-	for (i = sockets; i; i = i->next) {
-		struct socket_info_fd *f;
-		for (f = i->fds; f; f = f->next) {
-			if (f->fd == fd) {
-				return i;
-			}
+	for (f = socket_fds; f; f = f->next) {
+		if (f->fd == fd) {
+			return f;
 		}
 	}
 
 	return NULL;
 }
 
+static int find_socket_info_index(int fd)
+{
+	struct socket_info_fd *fi = find_socket_info_fd(fd);
+
+	if (fi == NULL) {
+		return -1;
+	}
+
+	return fi->si_index;
+}
+
+static struct socket_info *find_socket_info(int fd)
+{
+	int idx = find_socket_info_index(fd);
+
+	if (idx == -1) {
+		return NULL;
+	}
+
+	return &sockets[idx];
+}
+
 #if 0 /* FIXME */
 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
 {
-	struct socket_info *s;
+	struct socket_info_fd *f;
+	const struct socket_info *last_s = NULL;
 
 	/* first catch invalid input */
 	switch (sa->sa_family) {
@@ -1404,7 +1714,14 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
 		break;
 	}
 
-	for (s = sockets; s != NULL; s = s->next) {
+	for (f = socket_fds; f; f = f->next) {
+		struct socket_info *s = &sockets[f->si_index];
+
+		if (s == last_s) {
+			continue;
+		}
+		last_s = s;
+
 		if (s->myname == NULL) {
 			continue;
 		}
@@ -1466,27 +1783,33 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
 
 static void swrap_remove_stale(int fd)
 {
-	struct socket_info *si = find_socket_info(fd);
-	struct socket_info_fd *fi;
+	struct socket_info_fd *fi = find_socket_info_fd(fd);
+	struct socket_info *si;
+	int si_index;
 
-	if (si != NULL) {
-		for (fi = si->fds; fi; fi = fi->next) {
-			if (fi->fd == fd) {
-				SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
-				SWRAP_DLIST_REMOVE(si->fds, fi);
-				free(fi);
-				break;
-			}
-		}
+	if (fi == NULL) {
+		return;
+	}
 
-		if (si->fds == NULL) {
-			SWRAP_DLIST_REMOVE(sockets, si);
-			if (si->un_addr.sun_path[0] != '\0') {
-				unlink(si->un_addr.sun_path);
-			}
-			free(si);
-		}
+	si_index = fi->si_index;
+
+	SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+	SWRAP_DLIST_REMOVE(socket_fds, fi);
+	free(fi);
+
+	si = &sockets[si_index];
+	si->refcount--;
+
+	if (si->refcount > 0) {
+		return;
 	}
+
+	if (si->un_addr.sun_path[0] != '\0') {
+		unlink(si->un_addr.sun_path);
+	}
+
+	si->next_free = first_free;
+	first_free = si_index;
 }
 
 static int sockaddr_convert_to_un(struct socket_info *si,
@@ -1528,7 +1851,7 @@ static int sockaddr_convert_to_un(struct socket_info *si,
 		 * AF_UNSPEC is mapped to AF_INET and must be treated here.
 		 */
 
-		/* FALL THROUGH */
+		FALL_THROUGH;
 	}
 	case AF_INET:
 #ifdef HAVE_IPV6
@@ -2013,7 +2336,9 @@ static int swrap_pcap_get_fd(const char *fname)
 {
 	static int fd = -1;
 
-	if (fd != -1) return fd;
+	if (fd != -1) {
+		return fd;
+	}
 
 	fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
 	if (fd != -1) {
@@ -2066,7 +2391,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 
 	switch (type) {
 	case SWRAP_CONNECT_SEND:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		src_addr  = &si->myname.sa.s;
 		dest_addr = addr;
@@ -2080,7 +2407,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CONNECT_RECV:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		dest_addr = &si->myname.sa.s;
 		src_addr = addr;
@@ -2094,7 +2423,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CONNECT_UNREACH:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		dest_addr = &si->myname.sa.s;
 		src_addr  = addr;
@@ -2108,7 +2439,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CONNECT_ACK:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		src_addr  = &si->myname.sa.s;
 		dest_addr = addr;
@@ -2120,7 +2453,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_ACCEPT_SEND:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		dest_addr = &si->myname.sa.s;
 		src_addr = addr;
@@ -2134,7 +2469,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_ACCEPT_RECV:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		src_addr = &si->myname.sa.s;
 		dest_addr = addr;
@@ -2148,7 +2485,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_ACCEPT_ACK:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		dest_addr = &si->myname.sa.s;
 		src_addr = addr;
@@ -2255,7 +2594,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CLOSE_SEND:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		src_addr  = &si->myname.sa.s;
 		dest_addr = &si->peername.sa.s;
@@ -2269,7 +2610,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CLOSE_RECV:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		dest_addr = &si->myname.sa.s;
 		src_addr  = &si->peername.sa.s;
@@ -2283,7 +2626,9 @@ static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
 		break;
 
 	case SWRAP_CLOSE_ACK:
-		if (si->type != SOCK_STREAM) return NULL;
+		if (si->type != SOCK_STREAM) {
+			return NULL;
+		}
 
 		src_addr  = &si->myname.sa.s;
 		dest_addr = &si->peername.sa.s;
@@ -2380,6 +2725,7 @@ static int swrap_socket(int family, int type, int protocol)
 	struct socket_info *si;
 	struct socket_info_fd *fi;
 	int fd;
+	int idx;
 	int real_type = type;
 
 	/*
@@ -2434,12 +2780,12 @@ static int swrap_socket(int family, int type, int protocol)
 		if (real_type == SOCK_STREAM) {
 			break;
 		}
-		/*fall through*/
+		FALL_THROUGH;
 	case 17:
 		if (real_type == SOCK_DGRAM) {
 			break;
 		}
-		/*fall through*/
+		FALL_THROUGH;
 	default:
 		errno = EPROTONOSUPPORT;
 		return -1;
@@ -2456,17 +2802,16 @@ static int swrap_socket(int family, int type, int protocol)
 	}
 
 	/* Check if we have a stale fd and remove it */
-	si = find_socket_info(fd);
-	if (si != NULL) {
-		swrap_remove_stale(fd);
-	}
+	swrap_remove_stale(fd);
 
-	si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
-	if (si == NULL) {
+	idx = socket_wrapper_first_free_index();
+	if (idx == -1) {
 		errno = ENOMEM;
 		return -1;
 	}
 
+	si = &sockets[idx];
+
 	si->family = family;
 
 	/* however, the rest of the socket_wrapper code expects just
@@ -2498,22 +2843,24 @@ static int swrap_socket(int family, int type, int protocol)
 		break;
 	}
 	default:
-		free(si);
 		errno = EINVAL;
 		return -1;
 	}
 
 	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
 	if (fi == NULL) {
-		free(si);
 		errno = ENOMEM;
 		return -1;
 	}
 
+	si->refcount = 1;
+	first_free = si->next_free;
+	si->next_free = 0;
+
 	fi->fd = fd;
+	fi->si_index = idx;
 
-	SWRAP_DLIST_ADD(si->fds, fi);
-	SWRAP_DLIST_ADD(sockets, si);
+	SWRAP_DLIST_ADD(socket_fds, fi);
 
 	SWRAP_LOG(SWRAP_LOG_TRACE,
 		  "Created %s socket for protocol %s",
@@ -2607,6 +2954,7 @@ static int swrap_accept(int s,
 	struct socket_info *parent_si, *child_si;
 	struct socket_info_fd *child_fi;
 	int fd;
+	int idx;
 	struct swrap_address un_addr = {
 		.sa_socklen = sizeof(struct sockaddr_un),
 	};
@@ -2626,6 +2974,7 @@ static int swrap_accept(int s,
 #ifdef HAVE_ACCEPT4
 		return libc_accept4(s, addr, addrlen, flags);
 #else
+		UNUSED(flags);
 		return libc_accept(s, addr, addrlen);
 #endif
 	}
@@ -2643,6 +2992,7 @@ static int swrap_accept(int s,
 #ifdef HAVE_ACCEPT4
 	ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
 #else
+	UNUSED(flags);
 	ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
 #endif
 	if (ret == -1) {
@@ -2666,16 +3016,16 @@ static int swrap_accept(int s,
 		return ret;
 	}
 
-	child_si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
-	if (child_si == NULL) {
-		close(fd);
+	idx = socket_wrapper_first_free_index();
+	if (idx == -1) {
 		errno = ENOMEM;
 		return -1;
 	}
 
+	child_si = &sockets[idx];
+
 	child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
 	if (child_fi == NULL) {
-		free(child_si);
 		close(fd);
 		errno = ENOMEM;
 		return -1;
@@ -2683,8 +3033,6 @@ static int swrap_accept(int s,
 
 	child_fi->fd = fd;
 
-	SWRAP_DLIST_ADD(child_si->fds, child_fi);
-
 	child_si->family = parent_si->family;
 	child_si->type = parent_si->type;
 	child_si->protocol = parent_si->protocol;
@@ -2710,7 +3058,6 @@ static int swrap_accept(int s,
 			       &un_my_addr.sa_socklen);
 	if (ret == -1) {
 		free(child_fi);
-		free(child_si);
 		close(fd);
 		return ret;
 	}
@@ -2723,7 +3070,6 @@ static int swrap_accept(int s,
 				       &in_my_addr.sa_socklen);
 	if (ret == -1) {
 		free(child_fi);
-		free(child_si);
 		close(fd);
 		return ret;
 	}
@@ -2737,7 +3083,13 @@ static int swrap_accept(int s,
 	};
 	memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
 
-	SWRAP_DLIST_ADD(sockets, child_si);
+	child_si->refcount = 1;
+	first_free = child_si->next_free;
+	child_si->next_free = 0;
+
+	child_fi->si_index = idx;
+
+	SWRAP_DLIST_ADD(socket_fds, child_fi);
 
 	if (addr != NULL) {
 		swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
@@ -2805,8 +3157,9 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 			type = SOCKET_TYPE_CHAR_UDP;
 			break;
 		default:
-		    errno = ESOCKTNOSUPPORT;
-		    return -1;
+			errno = ESOCKTNOSUPPORT;
+			ret = -1;
+			goto done;
 		}
 
 		memset(&in, 0, sizeof(in));
@@ -2826,7 +3179,8 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 
 		if (si->family != family) {
 			errno = ENETUNREACH;
-			return -1;
+			ret = -1;
+			goto done;
 		}
 
 		switch (si->type) {
@@ -2838,7 +3192,8 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 			break;
 		default:
 			errno = ESOCKTNOSUPPORT;
-			return -1;
+			ret = -1;
+			goto done;
 		}
 
 		memset(&in6, 0, sizeof(in6));
@@ -2855,7 +3210,8 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 #endif
 	default:
 		errno = ESOCKTNOSUPPORT;
-		return -1;
+		ret = -1;
+		goto done;
 	}
 
 	if (autobind_start > 60000) {
@@ -2870,7 +3226,9 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 		if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
 
 		ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
-		if (ret == -1) return ret;
+		if (ret == -1) {
+			goto done;
+		}
 
 		si->un_addr = un_addr.sa.un;
 
@@ -2886,13 +3244,17 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 					   socket_wrapper_default_iface(),
 					   0);
 		errno = ENFILE;
-		return -1;
+		ret = -1;
+		goto done;
 	}
 
 	si->family = family;
 	set_port(si->family, port, &si->myname);
 
-	return 0;
+	ret = 0;
+
+done:
+	return ret;
 }
 
 /****************************************************************************
@@ -2915,21 +3277,27 @@ static int swrap_connect(int s, const struct sockaddr *serv_addr,
 
 	if (si->bound == 0) {
 		ret = swrap_auto_bind(s, si, serv_addr->sa_family);
-		if (ret == -1) return -1;
+		if (ret == -1) {
+			goto done;
+		}
 	}
 
 	if (si->family != serv_addr->sa_family) {
 		errno = EINVAL;
-		return -1;
+		ret = -1;
+		goto done;
 	}
 
 	ret = sockaddr_convert_to_un(si, serv_addr,
 				     addrlen, &un_addr.sa.un, 0, &bcast);
-	if (ret == -1) return -1;
+	if (ret == -1) {
+		goto done;
+	}
 
 	if (bcast) {
 		errno = ENETUNREACH;
-		return -1;
+		ret = -1;
+		goto done;
 	}
 
 	if (si->type == SOCK_DGRAM) {
@@ -2989,6 +3357,7 @@ static int swrap_connect(int s, const struct sockaddr *serv_addr,
 		swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
 	}
 
+done:
 	return ret;
 }
 
@@ -3084,7 +3453,9 @@ static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 				     &un_addr.sa.un,
 				     1,
 				     &si->bcast);
-	if (ret == -1) return -1;
+	if (ret == -1) {
+		return -1;
+	}
 
 	unlink(un_addr.sa.un.sun_path);
 
@@ -3242,6 +3613,31 @@ FILE *fopen(const char *name, const char *mode)
 	return swrap_fopen(name, mode);
 }
 
+/****************************************************************************
+ *   FOPEN64
+ ***************************************************************************/
+
+#ifdef HAVE_FOPEN64
+static FILE *swrap_fopen64(const char *name, const char *mode)
+{
+	FILE *fp;
+
+	fp = libc_fopen64(name, mode);
+	if (fp != NULL) {
+		int fd = fileno(fp);
+
+		swrap_remove_stale(fd);
+	}
+
+	return fp;
+}
+
+FILE *fopen64(const char *name, const char *mode)
+{
+	return swrap_fopen64(name, mode);
+}
+#endif /* HAVE_FOPEN64 */
+
 /****************************************************************************
  *   OPEN
  ***************************************************************************/
@@ -3275,6 +3671,75 @@ int open(const char *pathname, int flags, ...)
 	return fd;
 }
 
+/****************************************************************************
+ *   OPEN64
+ ***************************************************************************/
+
+#ifdef HAVE_OPEN64
+static int swrap_vopen64(const char *pathname, int flags, va_list ap)
+{
+	int ret;
+
+	ret = libc_vopen64(pathname, flags, ap);
+	if (ret != -1) {
+		/*
+		 * There are methods for closing descriptors (libc-internal code
+		 * paths, direct syscalls) which close descriptors in ways that
+		 * we can't intercept, so try to recover when we notice that
+		 * that's happened
+		 */
+		swrap_remove_stale(ret);
+	}
+	return ret;
+}
+
+int open64(const char *pathname, int flags, ...)
+{
+	va_list ap;
+	int fd;
+
+	va_start(ap, flags);
+	fd = swrap_vopen64(pathname, flags, ap);
+	va_end(ap);
+
+	return fd;
+}
+#endif /* HAVE_OPEN64 */
+
+/****************************************************************************
+ *   OPENAT
+ ***************************************************************************/
+
+static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
+{
+	int ret;
+
+	ret = libc_vopenat(dirfd, path, flags, ap);
+	if (ret != -1) {
+		/*
+		 * There are methods for closing descriptors (libc-internal code
+		 * paths, direct syscalls) which close descriptors in ways that
+		 * we can't intercept, so try to recover when we notice that
+		 * that's happened
+		 */
+		swrap_remove_stale(ret);
+	}
+
+	return ret;
+}
+
+int openat(int dirfd, const char *path, int flags, ...)
+{
+	va_list ap;
+	int fd;
+
+	va_start(ap, flags);
+	fd = swrap_vopenat(dirfd, path, flags, ap);
+	va_end(ap);
+
+	return fd;
+}
+
 /****************************************************************************
  *   GETPEERNAME
  ***************************************************************************/
@@ -3361,6 +3826,7 @@ static int swrap_getsockopt(int s, int level, int optname,
 			    void *optval, socklen_t *optlen)
 {
 	struct socket_info *si = find_socket_info(s);
+	int ret;
 
 	if (!si) {
 		return libc_getsockopt(s,
@@ -3377,12 +3843,14 @@ static int swrap_getsockopt(int s, int level, int optname,
 			if (optval == NULL || optlen == NULL ||
 			    *optlen < (socklen_t)sizeof(int)) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 
 			*optlen = sizeof(int);
 			*(int *)optval = si->family;
-			return 0;
+			ret = 0;
+			goto done;
 #endif /* SO_DOMAIN */
 
 #ifdef SO_PROTOCOL
@@ -3390,29 +3858,34 @@ static int swrap_getsockopt(int s, int level, int optname,
 			if (optval == NULL || optlen == NULL ||
 			    *optlen < (socklen_t)sizeof(int)) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 
 			*optlen = sizeof(int);
 			*(int *)optval = si->protocol;
-			return 0;
+			ret = 0;
+			goto done;
 #endif /* SO_PROTOCOL */
 		case SO_TYPE:
 			if (optval == NULL || optlen == NULL ||
 			    *optlen < (socklen_t)sizeof(int)) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 
 			*optlen = sizeof(int);
 			*(int *)optval = si->type;
-			return 0;
+			ret = 0;
+			goto done;
 		default:
-			return libc_getsockopt(s,
-					       level,
-					       optname,
-					       optval,
-					       optlen);
+			ret = libc_getsockopt(s,
+					      level,
+					      optname,
+					      optval,
+					      optlen);
+			goto done;
 		}
 	} else if (level == IPPROTO_TCP) {
 		switch (optname) {
@@ -3426,13 +3899,15 @@ static int swrap_getsockopt(int s, int level, int optname,
 			if (optval == NULL || optlen == NULL ||
 			    *optlen < (socklen_t)sizeof(int)) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 
 			*optlen = sizeof(int);
 			*(int *)optval = si->tcp_nodelay;
 
-			return 0;
+			ret = 0;
+			goto done;
 #endif /* TCP_NODELAY */
 		default:
 			break;
@@ -3440,7 +3915,10 @@ static int swrap_getsockopt(int s, int level, int optname,
 	}
 
 	errno = ENOPROTOOPT;
-	return -1;
+	ret = -1;
+
+done:
+	return ret;
 }
 
 #ifdef HAVE_ACCEPT_PSOCKLEN_T
@@ -3460,6 +3938,7 @@ static int swrap_setsockopt(int s, int level, int optname,
 			    const void *optval, socklen_t optlen)
 {
 	struct socket_info *si = find_socket_info(s);
+	int ret;
 
 	if (!si) {
 		return libc_setsockopt(s,
@@ -3488,17 +3967,20 @@ static int swrap_setsockopt(int s, int level, int optname,
 			if (optval == NULL || optlen == 0 ||
 			    optlen < (socklen_t)sizeof(int)) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 
 			i = *discard_const_p(int, optval);
 			if (i != 0 && i != 1) {
 				errno = EINVAL;
-				return -1;
+				ret = -1;
+				goto done;
 			}
 			si->tcp_nodelay = i;
 
-			return 0;
+			ret = 0;
+			goto done;
 		}
 #endif /* TCP_NODELAY */
 		default:
@@ -3515,7 +3997,8 @@ static int swrap_setsockopt(int s, int level, int optname,
 			}
 #endif /* IP_PKTINFO */
 		}
-		return 0;
+		ret = 0;
+		goto done;
 #ifdef HAVE_IPV6
 	case AF_INET6:
 		if (level == IPPROTO_IPV6) {
@@ -3525,12 +4008,17 @@ static int swrap_setsockopt(int s, int level, int optname,
 			}
 #endif /* IPV6_PKTINFO */
 		}
-		return 0;
+		ret = 0;
+		goto done;
 #endif
 	default:
 		errno = ENOPROTOOPT;
-		return -1;
+		ret = -1;
+		goto done;
 	}
+
+done:
+	return ret;
 }
 
 int setsockopt(int s, int level, int optname,
@@ -3944,7 +4432,9 @@ static ssize_t swrap_sendmsg_before(int fd,
 
 			ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
 						     tmp_un, 0, bcast);
-			if (ret == -1) return -1;
+			if (ret == -1) {
+				return -1;
+			}
 
 			if (to_un) {
 				*to_un = tmp_un;
@@ -3979,7 +4469,9 @@ static ssize_t swrap_sendmsg_before(int fd,
 					     tmp_un,
 					     0,
 					     NULL);
-		if (ret == -1) return -1;
+		if (ret == -1) {
+			return -1;
+		}
 
 		ret = libc_connect(fd,
 				   (struct sockaddr *)(void *)tmp_un,
@@ -5085,35 +5577,34 @@ ssize_t writev(int s, const struct iovec *vector, int count)
 
 static int swrap_close(int fd)
 {
-	struct socket_info *si = find_socket_info(fd);
-	struct socket_info_fd *fi;
+	struct socket_info_fd *fi = find_socket_info_fd(fd);
+	struct socket_info *si = NULL;
+	int si_index;
 	int ret;
 
-	if (!si) {
+	if (fi == NULL) {
 		return libc_close(fd);
 	}
 
-	for (fi = si->fds; fi; fi = fi->next) {
-		if (fi->fd == fd) {
-			SWRAP_DLIST_REMOVE(si->fds, fi);
-			free(fi);
-			break;
-		}
-	}
+	si_index = fi->si_index;
+
+	SWRAP_DLIST_REMOVE(socket_fds, fi);
+	free(fi);
 
-	if (si->fds) {
+	ret = libc_close(fd);
+
+	si = &sockets[si_index];
+	si->refcount--;
+
+	if (si->refcount > 0) {
 		/* there are still references left */
-		return libc_close(fd);
+		return ret;
 	}
 
-	SWRAP_DLIST_REMOVE(sockets, si);
-
 	if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
 		swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
 	}
 
-	ret = libc_close(fd);
-
 	if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
 		swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
 		swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
@@ -5122,7 +5613,9 @@ static int swrap_close(int fd)
 	if (si->un_addr.sun_path[0] != '\0') {
 		unlink(si->un_addr.sun_path);
 	}
-	free(si);
+
+	si->next_free = first_free;
+	first_free = si_index;
 
 	return ret;
 }
@@ -5139,14 +5632,15 @@ int close(int fd)
 static int swrap_dup(int fd)
 {
 	struct socket_info *si;
-	struct socket_info_fd *fi;
-
-	si = find_socket_info(fd);
+	struct socket_info_fd *src_fi, *fi;
 
-	if (!si) {
+	src_fi = find_socket_info_fd(fd);
+	if (src_fi == NULL) {
 		return libc_dup(fd);
 	}
 
+	si = &sockets[src_fi->si_index];
+
 	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
 	if (fi == NULL) {
 		errno = ENOMEM;
@@ -5161,10 +5655,13 @@ static int swrap_dup(int fd)
 		return -1;
 	}
 
+	si->refcount++;
+	fi->si_index = src_fi->si_index;
+
 	/* Make sure we don't have an entry for the fd */
 	swrap_remove_stale(fi->fd);
 
-	SWRAP_DLIST_ADD(si->fds, fi);
+	SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
 	return fi->fd;
 }
 
@@ -5180,14 +5677,25 @@ int dup(int fd)
 static int swrap_dup2(int fd, int newfd)
 {
 	struct socket_info *si;
-	struct socket_info_fd *fi;
-
-	si = find_socket_info(fd);
+	struct socket_info_fd *src_fi, *fi;
 
-	if (!si) {
+	src_fi = find_socket_info_fd(fd);
+	if (src_fi == NULL) {
 		return libc_dup2(fd, newfd);
 	}
 
+	si = &sockets[src_fi->si_index];
+
+	if (fd == newfd) {
+		/*
+		 * According to the manpage:
+		 *
+		 * "If oldfd is a valid file descriptor, and newfd has the same
+		 * value as oldfd, then dup2() does nothing, and returns newfd."
+		 */
+		return newfd;
+	}
+
 	if (find_socket_info(newfd)) {
 		/* dup2() does an implicit close of newfd, which we
 		 * need to emulate */
@@ -5208,10 +5716,13 @@ static int swrap_dup2(int fd, int newfd)
 		return -1;
 	}
 
+	si->refcount++;
+	fi->si_index = src_fi->si_index;
+
 	/* Make sure we don't have an entry for the fd */
 	swrap_remove_stale(fi->fd);
 
-	SWRAP_DLIST_ADD(si->fds, fi);
+	SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
 	return fi->fd;
 }
 
@@ -5226,17 +5737,17 @@ int dup2(int fd, int newfd)
 
 static int swrap_vfcntl(int fd, int cmd, va_list va)
 {
-	struct socket_info_fd *fi;
+	struct socket_info_fd *src_fi, *fi;
 	struct socket_info *si;
 	int rc;
 
-	si = find_socket_info(fd);
-	if (si == NULL) {
-		rc = libc_vfcntl(fd, cmd, va);
-
-		return rc;
+	src_fi = find_socket_info_fd(fd);
+	if (src_fi == NULL) {
+		return libc_vfcntl(fd, cmd, va);
 	}
 
+	si = &sockets[src_fi->si_index];
+
 	switch (cmd) {
 	case F_DUPFD:
 		fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
@@ -5253,10 +5764,13 @@ static int swrap_vfcntl(int fd, int cmd, va_list va)
 			return -1;
 		}
 
+		si->refcount++;
+		fi->si_index = src_fi->si_index;
+
 		/* Make sure we don't have an entry for the fd */
 		swrap_remove_stale(fi->fd);
 
-		SWRAP_DLIST_ADD(si->fds, fi);
+		SWRAP_DLIST_ADD_AFTER(socket_fds, fi, src_fi);
 
 		rc = fi->fd;
 		break;
@@ -5319,6 +5833,36 @@ int pledge(const char *promises, const char *paths[])
 }
 #endif /* HAVE_PLEDGE */
 
+static void swrap_thread_prepare(void)
+{
+	SWRAP_LOCK_ALL;
+}
+
+static void swrap_thread_parent(void)
+{
+	SWRAP_UNLOCK_ALL;
+}
+
+static void swrap_thread_child(void)
+{
+	SWRAP_UNLOCK_ALL;
+}
+
+/****************************
+ * CONSTRUCTOR
+ ***************************/
+void swrap_constructor(void)
+{
+	/*
+	* If we hold a lock and the application forks, then the child
+	* is not able to unlock the mutex and we are in a deadlock.
+	* This should prevent such deadlocks.
+	*/
+	pthread_atfork(&swrap_thread_prepare,
+		       &swrap_thread_parent,
+		       &swrap_thread_child);
+}
+
 /****************************
  * DESTRUCTOR
  ***************************/
@@ -5329,20 +5873,19 @@ int pledge(const char *promises, const char *paths[])
  */
 void swrap_destructor(void)
 {
-	struct socket_info *s = sockets;
+	struct socket_info_fd *s = socket_fds;
 
 	while (s != NULL) {
-		struct socket_info_fd *f = s->fds;
-		if (f != NULL) {
-			swrap_close(f->fd);
-		}
-		s = sockets;
+		swrap_close(s->fd);
+		s = socket_fds;
 	}
 
-	if (swrap.libc_handle != NULL) {
-		dlclose(swrap.libc_handle);
+	free(sockets);
+
+	if (swrap.libc.handle != NULL) {
+		dlclose(swrap.libc.handle);
 	}
-	if (swrap.libsocket_handle) {
-		dlclose(swrap.libsocket_handle);
+	if (swrap.libc.socket_handle) {
+		dlclose(swrap.libc.socket_handle);
 	}
 }
diff --git a/lib/socket_wrapper/wscript b/lib/socket_wrapper/wscript
index dbefa83ea33..43af96efbb5 100644
--- a/lib/socket_wrapper/wscript
+++ b/lib/socket_wrapper/wscript
@@ -2,7 +2,7 @@
 
 import os
 
-VERSION="1.1.7"
+VERSION="1.1.8"
 
 def configure(conf):
     if conf.CHECK_BUNDLED_SYSTEM('socket_wrapper', minversion=VERSION, set_target=False):
-- 
2.14.2


>From 56f7d7f719c771a90086bdf4076baebcc844fe3e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:25:46 +0200
Subject: [PATCH 04/60] lib:replace: Add FALL_THROUGH statements in strptime.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/replace/strptime.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/replace/strptime.c b/lib/replace/strptime.c
index 20e5d8c39b6..bbc742277de 100644
--- a/lib/replace/strptime.c
+++ b/lib/replace/strptime.c
@@ -462,7 +462,8 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
 	      *decided = raw;
 	    }
 #endif
-	  /* Fall through.  */
+
+	  FALL_THROUGH;
 	case 'D':
 	  /* Match standard day format.  */
 	  if (!recursive (HERE_D_FMT))
@@ -611,7 +612,8 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
 	      *decided = raw;
 	    }
 #endif
-	  /* Fall through.  */
+
+	  FALL_THROUGH;
 	case 'T':
 	  if (!recursive (HERE_T_FMT))
 	    return NULL;
-- 
2.14.2


>From ed858f4871331e0aa79d264309f63439dfe25f68 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 15:17:21 +0200
Subject: [PATCH 05/60] lib:ldb: Add FALL_THROUGH statements in common/ldb_dn.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/ldb/common/ldb_dn.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c
index b23ee1734cd..dfeb600f56f 100644
--- a/lib/ldb/common/ldb_dn.c
+++ b/lib/ldb/common/ldb_dn.c
@@ -629,7 +629,8 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
 					l++;
 					break;
 				}
-				/* fall through */
+
+				FALL_THROUGH;
 			case '\"':
 			case '<':
 			case '>':
-- 
2.14.2


>From 9dd9bda56cad19767ab8f1af09271485ac040300 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 15:18:28 +0200
Subject: [PATCH 06/60] lib:ldb: Add FALL_THROUGH statements in
 ldb_map/ldb_map_inbound.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/ldb/ldb_map/ldb_map_inbound.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c
index 461e68113ab..861c4c1622d 100644
--- a/lib/ldb/ldb_map/ldb_map_inbound.c
+++ b/lib/ldb/ldb_map/ldb_map_inbound.c
@@ -87,7 +87,8 @@ static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type
 			el = ldb_msg_el_map_local(module, remote, map, old);
 			break;
 		}
-		/* fall through */
+
+		FALL_THROUGH;
 	case LDB_MAP_IGNORE:
 		goto local;
 
@@ -99,7 +100,8 @@ static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type
 				  map->local_name);
 			goto local;
 		}
-		/* fall through */
+
+		FALL_THROUGH;
 	case LDB_MAP_KEEP:
 	case LDB_MAP_RENAME:
 		el = ldb_msg_el_map_local(module, remote, map, old);
-- 
2.14.2


>From 2e3251cc32163aad8cb8e8e6cf6d9c7298343155 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 15:19:23 +0200
Subject: [PATCH 07/60] lib:ldb: Add FALL_THROUGH statements in
 ldb_map/ldb_map.c

---
 lib/ldb/ldb_map/ldb_map.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/ldb/ldb_map/ldb_map.c b/lib/ldb/ldb_map/ldb_map.c
index f2a86fedd45..b453dff80d2 100644
--- a/lib/ldb/ldb_map/ldb_map.c
+++ b/lib/ldb/ldb_map/ldb_map.c
@@ -523,7 +523,8 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
 					  "used in DN!", ldb_dn_get_component_name(dn, i));
 				goto failed;
 			}
-			/* fall through */
+
+			FALL_THROUGH;
 		case LDB_MAP_KEEP:
 		case LDB_MAP_RENAME:
 		case LDB_MAP_RENDROP:
@@ -599,7 +600,8 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
 					  "used in DN!", ldb_dn_get_component_name(dn, i));
 				goto failed;
 			}
-			/* fall through */
+
+			FALL_THROUGH;
 		case LDB_MAP_KEEP:
 		case LDB_MAP_RENAME:
 		case LDB_MAP_RENDROP:
-- 
2.14.2


>From 9196c293a4f08d014f1a85d65c30efd592aefce7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 15:20:04 +0200
Subject: [PATCH 08/60] lib:ldb: Add FALL_THROUGH statements in
 ldb_map/ldb_map_outbound.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/ldb/ldb_map/ldb_map_outbound.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/ldb/ldb_map/ldb_map_outbound.c b/lib/ldb/ldb_map/ldb_map_outbound.c
index fd25c3658da..1f1a7e80142 100644
--- a/lib/ldb/ldb_map/ldb_map_outbound.c
+++ b/lib/ldb/ldb_map/ldb_map_outbound.c
@@ -330,7 +330,8 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
 				  attr_name);
 			return LDB_SUCCESS;
 		}
-		/* fall through */
+
+		FALL_THROUGH;
 	case LDB_MAP_KEEP:
 	case LDB_MAP_RENAME:
 	case LDB_MAP_RENDROP:
-- 
2.14.2


>From 1364864a27bfe3552bf6ebc49ccfaca8bd3b8587 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 15:20:57 +0200
Subject: [PATCH 09/60] lib:param: Add FALL_THROUGH statements in loadparm.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/param/loadparm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index b91f9657f1c..d0775d52379 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2058,7 +2058,8 @@ void lpcfg_print_parameter(struct parm_struct *p, void *ptr, FILE * f)
 
 		case P_CMDLIST:
 			list_sep = " ";
-			/* fall through */
+
+			FALL_THROUGH;
 		case P_LIST:
 			if ((char ***)ptr && *(char ***)ptr) {
 				char **list = *(char ***)ptr;
-- 
2.14.2


>From 4a4be1278a46da640212b957c6ba6c3a40b39ab8 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:51:39 +0200
Subject: [PATCH 10/60] lib:texpect: Avoid some compiler warnings

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/texpect/texpect.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lib/texpect/texpect.c b/lib/texpect/texpect.c
index b553de8ca5c..dd786705e8e 100644
--- a/lib/texpect/texpect.c
+++ b/lib/texpect/texpect.c
@@ -434,6 +434,9 @@ int main(int argc, const char **argv)
 	switch (pid) {
 		case -1:
 			err(1, "Failed to fork");
+
+			/* Never reached */
+			return 1;
 		case 0:
 
 			if(setsid()<0)
@@ -448,6 +451,9 @@ int main(int argc, const char **argv)
 			/* texpect <expect_instructions> <progname> [<args>] */
 			execvp(program, program_args);
 			err(1, "Failed to exec: %s", program);
+
+			/* Never reached */
+			return 1;
 		default:
 			close(slave);
 			{
@@ -462,4 +468,7 @@ int main(int argc, const char **argv)
 
 			return eval_parent(pid);
 	}
+
+	/* Never reached */
+	return 1;
 }
-- 
2.14.2


>From 50b65c7a2ce6da6181588faf292319350605fcc9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:49:50 +0200
Subject: [PATCH 11/60] lib:util: Add FALL_THROUGH statements in substitute.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/substitute.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/util/substitute.c b/lib/util/substitute.c
index 49adeaf178a..2c18257da25 100644
--- a/lib/util/substitute.c
+++ b/lib/util/substitute.c
@@ -84,6 +84,7 @@ static void string_sub2(char *s,const char *pattern, const char *insert, size_t
 					p[i] = insert[i];
 					break;
 				}
+				FALL_THROUGH;
 			case '`':
 			case '"':
 			case '\'':
@@ -98,6 +99,7 @@ static void string_sub2(char *s,const char *pattern, const char *insert, size_t
 					 * not replacing unsafe chars */
 					break;
 				}
+				FALL_THROUGH;
 			default:
 				p[i] = insert[i];
 			}
-- 
2.14.2


>From 82746db510d82022c1c6e1a5a5d512dc535c520c Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:40:14 +0200
Subject: [PATCH 12/60] lib:util: Add FALL_THROUGH statements in
 charset/charset_macosxfs.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/charset/charset_macosxfs.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/lib/util/charset/charset_macosxfs.c b/lib/util/charset/charset_macosxfs.c
index 895277d001a..24e21fd6d2c 100644
--- a/lib/util/charset/charset_macosxfs.c
+++ b/lib/util/charset/charset_macosxfs.c
@@ -457,10 +457,11 @@ static size_t macosxfs_encoding_pull(
 
 	switch(result) {
 	case kCFStringEncodingConversionSuccess:
-		if (*inbytesleft == srcCharsUsed)
+		if (*inbytesleft == srcCharsUsed) {
 			break;
-		else
-			; /*fall through*/
+		}
+
+		FALL_THROUGH;
 	case kCFStringEncodingInsufficientOutputBufferLength:
 		debug_out("String conversion: "
 			  "Output buffer too small\n");
@@ -546,10 +547,11 @@ static size_t macosxfs_encoding_push(
 
 	switch(result) {
 	case kCFStringEncodingConversionSuccess:
-		if (*inbytesleft/2 == srcCharsUsed)
+		if (*inbytesleft/2 == srcCharsUsed) {
 			break;
-		else
-			; /*fall through*/
+		}
+
+		FALL_THROUGH;
 	case kCFStringEncodingInsufficientOutputBufferLength:
 		debug_out("String conversion: "
 			  "Output buffer too small\n");
-- 
2.14.2


>From 01261ef47e4a0ee97a678ca025cfda151f0e0e4d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:41:25 +0200
Subject: [PATCH 13/60] lib:util: Add FALL_THROUGH statements in util_file.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/util_file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/util/util_file.c b/lib/util/util_file.c
index ac8206008a3..499e8c46693 100644
--- a/lib/util/util_file.c
+++ b/lib/util/util_file.c
@@ -130,7 +130,8 @@ char *fgets_slash(TALLOC_CTX *mem_ctx, char *s2, int maxlen, FILE *f)
 			    if (start_of_line) {
 				    break;
 			    }
-			    /* fall through */
+
+			    FALL_THROUGH;
 		    default:
 			    start_of_line = false;
 			    s[len++] = c;
-- 
2.14.2


>From 738c8a2e30a40df5f650392457cd0443b3333eff Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:22:44 +0200
Subject: [PATCH 14/60] s3:lib: Add FALL_THROUGH statements in
 substitute_generic.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/substitute_generic.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/lib/substitute_generic.c b/source3/lib/substitute_generic.c
index f24608eb96c..0498cd03833 100644
--- a/source3/lib/substitute_generic.c
+++ b/source3/lib/substitute_generic.c
@@ -68,6 +68,7 @@ char *realloc_string_sub2(char *string,
 				if (allow_trailing_dollar && (i == li - 1 )) {
 					break;
 				}
+				FALL_THROUGH;
 			case '`':
 			case '"':
 			case '\'':
@@ -79,6 +80,7 @@ char *realloc_string_sub2(char *string,
 					in[i] = '_';
 					break;
 				}
+				FALL_THROUGH;
 			default:
 				/* ok */
 				break;
-- 
2.14.2


>From d24e2c39930e33faf2d5aefe0a10b0d660a78f71 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 16:57:38 +0200
Subject: [PATCH 15/60] s3:lib: Add FALL_THROUGH statements in util_path.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/util_path.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c
index 6f58a03ae58..5b133dfdc78 100644
--- a/source3/lib/util_path.c
+++ b/source3/lib/util_path.c
@@ -204,16 +204,20 @@ char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path)
 			switch(siz) {
 				case 5:
 					*d++ = *s++;
-					/*fall through*/
+
+					FALL_THROUGH;
 				case 4:
 					*d++ = *s++;
-					/*fall through*/
+
+					FALL_THROUGH;
 				case 3:
 					*d++ = *s++;
-					/*fall through*/
+
+					FALL_THROUGH;
 				case 2:
 					*d++ = *s++;
-					/*fall through*/
+
+					FALL_THROUGH;
 				case 1:
 					*d++ = *s++;
 					break;
-- 
2.14.2


>From d3673b8eefd37b8538bfcc1f7bf332387a752397 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:25:20 +0200
Subject: [PATCH 16/60] s3:lib: Add FALL_THROUGH statements in util_str.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/util_str.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 48e434f777e..eb36478d8a2 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -276,6 +276,8 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 				if (allow_trailing_dollar && (i == li - 1 )) {
 					break;
 				}
+
+				FALL_THROUGH;
 			case '`':
 			case '"':
 			case '\'':
@@ -287,6 +289,8 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 					in[i] = '_';
 					break;
 				}
+
+				FALL_THROUGH;
 			default:
 				/* ok */
 				break;
-- 
2.14.2


>From 28e44005cf89b8a6ffeffacae5c547bc6edfaaf4 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:55:10 +0200
Subject: [PATCH 17/60] lib:tdb: Add FALL_THROUGH statements in hash.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/tdb/common/hash.c | 50 +++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/lib/tdb/common/hash.c b/lib/tdb/common/hash.c
index 1eed7221d2a..4de7ba94d2c 100644
--- a/lib/tdb/common/hash.c
+++ b/lib/tdb/common/hash.c
@@ -232,16 +232,16 @@ static uint32_t hashlittle( const void *key, size_t length )
     switch(length)
     {
     case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
-    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
-    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
-    case 9 : c+=k8[8];                   /* fall through */
+    case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH;
+    case 10: c+=((uint32_t)k8[9])<<8;   FALL_THROUGH;
+    case 9 : c+=k8[8];                  FALL_THROUGH;
     case 8 : b+=k[1]; a+=k[0]; break;
-    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
-    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
-    case 5 : b+=k8[4];                   /* fall through */
+    case 7 : b+=((uint32_t)k8[6])<<16;  FALL_THROUGH;
+    case 6 : b+=((uint32_t)k8[5])<<8;   FALL_THROUGH;
+    case 5 : b+=k8[4];                  FALL_THROUGH;
     case 4 : a+=k[0]; break;
-    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
-    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
+    case 3 : a+=((uint32_t)k8[2])<<16;  FALL_THROUGH;
+    case 2 : a+=((uint32_t)k8[1])<<8;   FALL_THROUGH;
     case 1 : a+=k8[0]; break;
     case 0 : return c;
     }
@@ -268,23 +268,23 @@ static uint32_t hashlittle( const void *key, size_t length )
              b+=k[2]+(((uint32_t)k[3])<<16);
              a+=k[0]+(((uint32_t)k[1])<<16);
              break;
-    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
+    case 11: c+=((uint32_t)k8[10])<<16;      FALL_THROUGH;
     case 10: c+=k[4];
              b+=k[2]+(((uint32_t)k[3])<<16);
              a+=k[0]+(((uint32_t)k[1])<<16);
              break;
-    case 9 : c+=k8[8];                      /* fall through */
+    case 9 : c+=k8[8];                       FALL_THROUGH;
     case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
              a+=k[0]+(((uint32_t)k[1])<<16);
              break;
-    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
+    case 7 : b+=((uint32_t)k8[6])<<16;       FALL_THROUGH;
     case 6 : b+=k[2];
              a+=k[0]+(((uint32_t)k[1])<<16);
              break;
-    case 5 : b+=k8[4];                      /* fall through */
+    case 5 : b+=k8[4];                       FALL_THROUGH;
     case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
              break;
-    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
+    case 3 : a+=((uint32_t)k8[2])<<16;       FALL_THROUGH;
     case 2 : a+=k[0];
              break;
     case 1 : a+=k8[0];
@@ -316,19 +316,19 @@ static uint32_t hashlittle( const void *key, size_t length )
     }
 
     /*-------------------------------- last block: affect all 32 bits of (c) */
-    switch(length)                   /* all the case statements fall through */
+    switch(length)
     {
-    case 12: c+=((uint32_t)k[11])<<24;
-    case 11: c+=((uint32_t)k[10])<<16;
-    case 10: c+=((uint32_t)k[9])<<8;
-    case 9 : c+=k[8];
-    case 8 : b+=((uint32_t)k[7])<<24;
-    case 7 : b+=((uint32_t)k[6])<<16;
-    case 6 : b+=((uint32_t)k[5])<<8;
-    case 5 : b+=k[4];
-    case 4 : a+=((uint32_t)k[3])<<24;
-    case 3 : a+=((uint32_t)k[2])<<16;
-    case 2 : a+=((uint32_t)k[1])<<8;
+    case 12: c+=((uint32_t)k[11])<<24; FALL_THROUGH;
+    case 11: c+=((uint32_t)k[10])<<16; FALL_THROUGH;
+    case 10: c+=((uint32_t)k[9])<<8;   FALL_THROUGH;
+    case 9 : c+=k[8];                  FALL_THROUGH;
+    case 8 : b+=((uint32_t)k[7])<<24;  FALL_THROUGH;
+    case 7 : b+=((uint32_t)k[6])<<16;  FALL_THROUGH;
+    case 6 : b+=((uint32_t)k[5])<<8;   FALL_THROUGH;
+    case 5 : b+=k[4];                  FALL_THROUGH;
+    case 4 : a+=((uint32_t)k[3])<<24;  FALL_THROUGH;
+    case 3 : a+=((uint32_t)k[2])<<16;  FALL_THROUGH;
+    case 2 : a+=((uint32_t)k[1])<<8;   FALL_THROUGH;
     case 1 : a+=k[0];
              break;
     case 0 : return c;
-- 
2.14.2


>From e622bdaef0dc5bbe2870ab0e3e8fef99a9781d74 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:58:00 +0200
Subject: [PATCH 18/60] lib:tdb: Add FALL_THROUGH statements in tdbtool.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/tdb/tools/tdbtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/tdb/tools/tdbtool.c b/lib/tdb/tools/tdbtool.c
index e3535b93c7c..d8bacdb61b8 100644
--- a/lib/tdb/tools/tdbtool.c
+++ b/lib/tdb/tools/tdbtool.c
@@ -930,10 +930,13 @@ int main(int argc, char *argv[])
 		break;
 	case 5:
 		arg2 = tdb_convert_string(argv[4],&arg2len);
+		FALL_THROUGH;
 	case 4:
 		arg1 = tdb_convert_string(argv[3],&arg1len);
+		FALL_THROUGH;
 	case 3:
 		cmdname = argv[2];
+		FALL_THROUGH;
 	default:
 		do_command();
 		break;
-- 
2.14.2


>From 54e2f1e6bc4b7db573515fb74a789ace4d2d8759 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:28:12 +0200
Subject: [PATCH 19/60] lib:tdb: Add FALL_THROUGH statements in
 common/summary.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/tdb/common/summary.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/tdb/common/summary.c b/lib/tdb/common/summary.c
index d786132d4a1..c9b5bc4c1d0 100644
--- a/lib/tdb/common/summary.c
+++ b/lib/tdb/common/summary.c
@@ -151,7 +151,8 @@ _PUBLIC_ char *tdb_summary(struct tdb_context *tdb)
 				rec.rec_len = tdb_dead_space(tdb, off)
 					- sizeof(rec);
 			}
-			/* Fall through */
+
+			FALL_THROUGH;
 		case TDB_DEAD_MAGIC:
 			tally_add(&dead, rec.rec_len);
 			break;
-- 
2.14.2


>From a3f3d2e22fde555475cc795372c574035b278921 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:43:53 +0200
Subject: [PATCH 20/60] libgpo: Add FALL_THROUGH statements in gpo_sec.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 libgpo/gpo_sec.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libgpo/gpo_sec.c b/libgpo/gpo_sec.c
index af73697e56e..98ee8eb3cc9 100644
--- a/libgpo/gpo_sec.c
+++ b/libgpo/gpo_sec.c
@@ -47,13 +47,15 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec
 				       &ext_right_apg_guid)) {
 				return true;
 			}
-			/* FALL TROUGH */
+
+			FALL_THROUGH;
 		case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT:
 			if (GUID_equal(&object->inherited_type.inherited_type,
 				       &ext_right_apg_guid)) {
 				return true;
 			}
-			/* FALL TROUGH */
+
+			FALL_THROUGH;
 		default:
 			break;
 	}
-- 
2.14.2


>From 6fb8f6c5e5f0fc65f8a245e7f119bf09d97d9977 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:03:09 +0200
Subject: [PATCH 21/60] librpc:ndr: Add FALL_THROUGH statements in ndr_cab.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 librpc/ndr/ndr_cab.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/librpc/ndr/ndr_cab.c b/librpc/ndr/ndr_cab.c
index 837ed253065..c415bfab34c 100644
--- a/librpc/ndr/ndr_cab.c
+++ b/librpc/ndr/ndr_cab.c
@@ -95,10 +95,13 @@ static uint32_t ndr_cab_compute_checksum(uint8_t *data, uint32_t length, uint32_
 	switch (length % 4) {
 	case 3:
 		ul |= (((uint32_t)(*pb++)) << 16);
+		FALL_THROUGH;
 	case 2:
 		ul |= (((uint32_t)(*pb++)) <<  8);
+		FALL_THROUGH;
 	case 1:
 		ul |= (uint32_t)(*pb++);
+		FALL_THROUGH;
 	default:
 		break;
 	}
-- 
2.14.2


>From 853e6993f96fa6c7601a414e895eda38e2513490 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:35:28 +0200
Subject: [PATCH 22/60] s3:auth: Add FALL_THROUGH statements in auth_sam.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/auth/auth_sam.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 4bcb7926c6e..46958c54d3a 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -88,6 +88,8 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
 					? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
 				return NT_STATUS_NOT_IMPLEMENTED;
 			}
+
+			FALL_THROUGH;
 		case ROLE_DOMAIN_PDC:
 		case ROLE_DOMAIN_BDC:
 			if ( !is_local_name && !is_my_domain ) {
@@ -95,6 +97,8 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
 					user_info->mapped.domain_name));
 				return NT_STATUS_NOT_IMPLEMENTED;
 			}
+
+			FALL_THROUGH;
 		default: /* name is ok */
 			break;
 	}
-- 
2.14.2


>From 19195e3bd463f1b87b0168676914ad0570faa16c Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 16:55:23 +0200
Subject: [PATCH 23/60] s3:auth: Add FALL_THROUGH statements in pampass.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/auth/pampass.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c
index 1a82fe7f203..8cb894482ae 100644
--- a/source3/auth/pampass.c
+++ b/source3/auth/pampass.c
@@ -168,7 +168,7 @@ static int smb_pam_conv(int num_msg,
 				break;
 
 			case PAM_TEXT_INFO:
-				/* fall through */
+				FALL_THROUGH;
 
 			case PAM_ERROR_MSG:
 				/* ignore it... */
@@ -390,7 +390,7 @@ static int smb_pam_passchange_conv(int num_msg,
 			break;
 
 		case PAM_TEXT_INFO:
-			/* fall through */
+			FALL_THROUGH;
 
 		case PAM_ERROR_MSG:
 			/* ignore it... */
-- 
2.14.2


>From 3743bc07b453ffe5911bbb4f814242d5c373dda1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:25:30 +0200
Subject: [PATCH 24/60] s3:lib: Add FALL_THROUGH statements in cbuf.c

---
 source3/lib/cbuf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/lib/cbuf.c b/source3/lib/cbuf.c
index 611aa80609f..426ecdb5a3b 100644
--- a/source3/lib/cbuf.c
+++ b/source3/lib/cbuf.c
@@ -278,7 +278,8 @@ int cbuf_print_quoted_string(cbuf* ost, const char* s)
 		case '\\':
 			cbuf_putc(ost, '\\');
 		        n++;
-			/* no break */
+
+			FALL_THROUGH;
 		default:
 			cbuf_putc(ost, *s);
 			n++;
-- 
2.14.2


>From 6fe0478ccc729208cf35f3dd2b950de671037a71 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:48:34 +0200
Subject: [PATCH 25/60] REVIEW CARFULLY s3:lib: Add missing break in tldap.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/tldap.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index 40064fdeeed..33a852446b9 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -1295,6 +1295,8 @@ static bool tldap_unescape_inplace(char *value, size_t *val_len)
 			case '\\':
 				value[p] = value[i];
 				p++;
+
+				break;
 			default:
 				/* invalid */
 				return false;
-- 
2.14.2


>From 51cceed7bf81c0583ec40c6850c26de91133ad6d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:51:08 +0200
Subject: [PATCH 26/60] s3:lib: Add FALL_THROUGH statements in sysacls.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/sysacls.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index 0bf3c37edfa..c80f8f30c90 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -186,7 +186,8 @@ char *sys_acl_to_text(const struct smb_acl_t *acl_d, ssize_t *len_p)
 
 			case SMB_ACL_USER:
 				id = uidtoname(ap->info.user.uid);
-				/* FALL TROUGH */
+
+				FALL_THROUGH;
 			case SMB_ACL_USER_OBJ:
 				tag = "user";
 				break;
@@ -199,7 +200,8 @@ char *sys_acl_to_text(const struct smb_acl_t *acl_d, ssize_t *len_p)
 				} else {
 					id = gr->gr_name;
 				}
-				/* FALL TROUGH */
+
+				FALL_THROUGH;
 			case SMB_ACL_GROUP_OBJ:
 				tag = "group";
 				break;
-- 
2.14.2


>From 2a457edef347e8abcacecb1ff0720f4863d5ea7e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:54:48 +0200
Subject: [PATCH 27/60] s3:lib: Add FALL_THROUGH statements in util_sd.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/lib/util_sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index aa6d4809fc8..39083b15438 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -394,6 +394,8 @@ static bool parse_ace_flags(const char *str, unsigned int *pflags)
 		switch (*p) {
 		case '|':
 			p++;
+
+			FALL_THROUGH;
 		case '\0':
 			continue;
 		default:
-- 
2.14.2


>From 081659eee5e7807609353b14b3e7009ed6689691 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:36:50 +0200
Subject: [PATCH 28/60] s3:libsmb: Add FALL_THROUGH statements in dsgetdcname.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/libsmb/dsgetdcname.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 92fc312c6a4..4a49931fb3c 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -712,6 +712,8 @@ static void map_dc_and_domain_names(uint32_t flags,
 				*domain_p = domain_name;
 				break;
 			}
+
+			FALL_THROUGH;
 		case DS_RETURN_DNS_NAME:
 		default:
 			if (dns_dc_name && dns_domain_name &&
-- 
2.14.2


>From 286b4e8b76926a166ffdd116f9b18186d8b561bf Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:53:45 +0200
Subject: [PATCH 29/60] s3:modules: Add FALL_THROUGH statements in
 vfs_acl_common.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/modules/vfs_acl_common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 7958fd1ca72..8520b63cf2f 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -727,6 +727,7 @@ static NTSTATUS validate_nt_acl_blob(TALLOC_CTX *mem_ctx,
 		}
 
 		/* Otherwise, fall though and see if the NT ACL hash matches */
+		FALL_THROUGH;
 	}
 	case 3:
 		/* Get the full underlying sd for the hash
-- 
2.14.2


>From 011be2024e476a794c14dc8f6d7186e540d33a1a Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:50:18 +0200
Subject: [PATCH 30/60] s3:smbd: Add FALL_THROUGH statements in nttrans.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/smbd/nttrans.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 7b7f2056099..ca02dbcc3d9 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -2387,6 +2387,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
 
 			start_enum = False;
 
+			FALL_THROUGH;
 		case TRANSACT_GET_USER_QUOTA_LIST_START:
 
 			if (qt_handle->quota_list==NULL &&
-- 
2.14.2


>From 14b954a8a7987831effabd1400d3790a4acf9f41 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:52:06 +0200
Subject: [PATCH 31/60] s3:smbd: Add FALL_THROUGH statements in trans2.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/smbd/trans2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index de6073a973f..4e1312f28e9 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4038,7 +4038,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
 				SIVAL(pdata,84,0x100); /* Don't support mac... */
 				break;
 			}
-			/* drop through */
+
+			FALL_THROUGH;
 		default:
 			return NT_STATUS_INVALID_LEVEL;
 	}
-- 
2.14.2


>From 8e24f6f68ee32e666d1890f43dfb438c21bd6e2f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:55:35 +0200
Subject: [PATCH 32/60] s3:utils: Add FALL_THROUGH statements in regedit.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/utils/regedit.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c
index 14e75c25bfa..27bd6f8f2c2 100644
--- a/source3/utils/regedit.c
+++ b/source3/utils/regedit.c
@@ -507,7 +507,8 @@ static void handle_value_input(struct regedit *regedit, int c)
 	case 'b':
 	case 'B':
 		binmode = true;
-		/* Falthrough... */
+
+		FALL_THROUGH;
 	case '\n':
 	case KEY_ENTER:
 		vitem = value_list_get_current_item(regedit->vl);
-- 
2.14.2


>From 5e4dd7d638e631fa1723a5e211ff791d6291b683 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:57:10 +0200
Subject: [PATCH 33/60] s3:utils: Add FALL_THROUGH statements in net_conf.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/utils/net_conf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 8d9f1e6b99b..097baa1b82e 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -294,6 +294,8 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
 				d_printf(_("error: out of memory!\n"));
 				goto done;
 			}
+
+			FALL_THROUGH;
 		case 1:
 			filename = argv[0];
 			break;
@@ -563,6 +565,8 @@ static int net_conf_addshare(struct net_context *c,
 			goto done;
 		case 5:
 			comment = argv[4];
+
+			FALL_THROUGH;
 		case 4:
 			if (!strnequal(argv[3], "guest_ok=", 9)) {
 				net_conf_addshare_usage(c, argc, argv);
@@ -581,6 +585,8 @@ static int net_conf_addshare(struct net_context *c,
 					net_conf_addshare_usage(c, argc, argv);
 					goto done;
 			}
+
+			FALL_THROUGH;
 		case 3:
 			if (!strnequal(argv[2], "writeable=", 10)) {
 				net_conf_addshare_usage(c, argc, argv);
@@ -599,6 +605,8 @@ static int net_conf_addshare(struct net_context *c,
 					net_conf_addshare_usage(c, argc, argv);
 					goto done;
 			}
+
+			FALL_THROUGH;
 		case 2:
 			path = argv[1];
 			sharename = talloc_strdup(mem_ctx, argv[0]);
-- 
2.14.2


>From 487c9695a786ac9e3ff0339bb444b335e9f648d0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:58:40 +0200
Subject: [PATCH 34/60] s3:utils: Add FALL_THROUGH statements in net_rpc_conf.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/utils/net_rpc_conf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/source3/utils/net_rpc_conf.c b/source3/utils/net_rpc_conf.c
index 0b1b59e3b45..4747da98325 100644
--- a/source3/utils/net_rpc_conf.c
+++ b/source3/utils/net_rpc_conf.c
@@ -1155,6 +1155,8 @@ static NTSTATUS rpc_conf_import_internal(struct net_context *c,
 				d_printf(_("error: out of memory!\n"));
 				goto error;
 			}
+
+			FALL_THROUGH;
 		case 1:
 			filename = argv[0];
 			break;
@@ -1426,6 +1428,8 @@ static NTSTATUS rpc_conf_addshare_internal(struct net_context *c,
 			goto error;
 		case 5:
 			comment = argv[4];
+
+			FALL_THROUGH;
 		case 4:
 			if (!strnequal(argv[3], "guest_ok=", 9)) {
 				rpc_conf_addshare_usage(c, argc, argv);
@@ -1446,6 +1450,8 @@ static NTSTATUS rpc_conf_addshare_internal(struct net_context *c,
 					status = NT_STATUS_INVALID_PARAMETER;
 					goto error;
 			}
+
+			FALL_THROUGH;
 		case 3:
 			if (!strnequal(argv[2], "writeable=", 10)) {
 				rpc_conf_addshare_usage(c, argc, argv);
@@ -1466,6 +1472,8 @@ static NTSTATUS rpc_conf_addshare_internal(struct net_context *c,
 					status = NT_STATUS_INVALID_PARAMETER;
 					goto error;
 			}
+
+			FALL_THROUGH;
 		case 2:
 			path = argv[1];
 			sharename = talloc_strdup(frame, argv[0]);
-- 
2.14.2


>From 2e05ff60a6bc57e119a46f30fe547bb11ce549ae Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:42:46 +0200
Subject: [PATCH 35/60] s3:rpc_server: Add FALL_THROUGH statements in
 rpc_server.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/rpc_server/rpc_server.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
index e15cd205cdc..495209b0d73 100644
--- a/source3/rpc_server/rpc_server.c
+++ b/source3/rpc_server/rpc_server.c
@@ -1065,7 +1065,8 @@ void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
 					}
 				}
 			}
-			/* FALL TROUGH */
+
+			FALL_THROUGH;
 		case NCACN_NP:
 			pipe_name = talloc_strdup(ncacn_conn,
 						  name);
-- 
2.14.2


>From a057102311839492e855a8fb65ea01b76358dea6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:21:02 +0200
Subject: [PATCH 36/60] s4:samdb: Add FALL_THROUGH statements in cracknames.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/dsdb/samdb/cracknames.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index d43f510b949..d8fe0975d15 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -1083,7 +1083,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
 				return WERR_OK;
 			}
 		}
-		/* FALL TROUGH */
+		FALL_THROUGH;
 		default:
 			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
 			return WERR_OK;
-- 
2.14.2


>From 23d70284230cf435e3c0701a4eae85cde5b93e86 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:28:11 +0200
Subject: [PATCH 37/60] s4:samdb: Add FALL_THROUGH statements in
 linked_attributes.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/dsdb/samdb/ldb_modules/linked_attributes.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index c6beb25e58b..57d25076a75 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -573,8 +573,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
 			/* treat as just a normal add the delete part is handled by the callback */
 			store_el = true;
 
-			/* break intentionally missing */
-
+			FALL_THROUGH;
 		case LDB_FLAG_MOD_ADD:
 
 			/* For each value being added, we need to setup the adds */
-- 
2.14.2


>From 4ea16c90b58d857fca696147dd91ae1908088085 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:29:55 +0200
Subject: [PATCH 38/60] s4:auth: Add FALL_THROUGH statements in auth_util.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/auth/ntlm/auth_util.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c
index 7feb20b8f62..5084cc4a929 100644
--- a/source4/auth/ntlm/auth_util.c
+++ b/source4/auth/ntlm/auth_util.c
@@ -62,7 +62,8 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte
 				return nt_status;
 			}
 			user_info_in = user_info_temp2;
-			/* fall through */
+
+			FALL_THROUGH;
 		}
 		case AUTH_PASSWORD_HASH:
 		{
@@ -122,7 +123,8 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte
 			}
 
 			user_info_in = user_info_temp;
-			/* fall through */
+
+			FALL_THROUGH;
 		}
 		case AUTH_PASSWORD_RESPONSE:
 			*user_info_encrypted = user_info_in;
@@ -160,7 +162,8 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte
 			*user_info_temp->password.hash.nt = nt;
 			
 			user_info_in = user_info_temp;
-			/* fall through */
+
+			FALL_THROUGH;
 		}
 		case AUTH_PASSWORD_HASH:
 			*user_info_encrypted = user_info_in;
-- 
2.14.2


>From 62fe6658f1798061a140042dcf1e46d7ba655164 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:30:53 +0200
Subject: [PATCH 39/60] s4:auth: Add FALL_THROUGH statements in auth_sam.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/auth/ntlm/auth_sam.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 24fe1677ed3..bbbb1cb97c7 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -70,7 +70,7 @@ static NTSTATUS authsam_password_ok(struct auth4_context *auth_context,
 		}
 		user_info = user_info_temp;
 
-		/*fall through*/
+		FALL_THROUGH;
 	}
 	case AUTH_PASSWORD_HASH:
 		*lm_sess_key = data_blob(NULL, 0);
-- 
2.14.2


>From ece29981f81595f1eee52b10e7b0042bb66051c8 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:33:12 +0200
Subject: [PATCH 40/60] s4:auth: Add FALL_THROUGH statements in gensec_krb5.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/auth/gensec/gensec_krb5.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 86ec23fe433..0323da87d29 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -407,12 +407,9 @@ static NTSTATUS gensec_krb5_common_client_creds(struct gensec_security *gensec_s
 		/* Too much clock skew - we will need to kinit to re-skew the clock */
 	case KRB5KRB_AP_ERR_SKEW:
 	case KRB5_KDCREP_SKEW:
-	{
 		DEBUG(3, ("kerberos (mk_req) failed: %s\n", 
 			  smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
-		/*fall through*/
-	}
-	
+		FALL_THROUGH;
 	/* just don't print a message for these really ordinary messages */
 	case KRB5_FCC_NOFILE:
 	case KRB5_CC_NOTFOUND:
-- 
2.14.2


>From 5cfa773c2e8f6301819002544236e04427869b1f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:39:04 +0200
Subject: [PATCH 41/60] s4:rpc_server: Add FALL_THROUGH statements in
 dcesrv_srvsvc.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/rpc_server/srvsvc/dcesrv_srvsvc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
index 71f0ac46175..29ec3cf2a08 100644
--- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
+++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
@@ -1127,6 +1127,7 @@ static WERROR dcesrv_srvsvc_fill_share_info(struct share_info *info, int *count,
 		*((int *)info[i].value) = max_users;
 		i++;
 
+		FALL_THROUGH;
 	case 501:
 	case 1:
 		info[i].name = SHARE_TYPE;
@@ -1147,6 +1148,7 @@ static WERROR dcesrv_srvsvc_fill_share_info(struct share_info *info, int *count,
 		W_ERROR_HAVE_NO_MEMORY(info[i].value);
 		i++;
 
+		FALL_THROUGH;
 	case 1004:
 		if (comment) {
 			info[i].name = SHARE_COMMENT;
@@ -1156,6 +1158,8 @@ static WERROR dcesrv_srvsvc_fill_share_info(struct share_info *info, int *count,
 
 			i++;
 		}
+
+		FALL_THROUGH;
 	case 0:
 		if (name &&
 		    strcasecmp(share_name, name) != 0) {
-- 
2.14.2


>From d4fa4d14fd7cb61d180919822fdb997c13a61088 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:39:52 +0200
Subject: [PATCH 42/60] s4:torture: Add FALL_THROUGH statements in basic/misc.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/torture/basic/misc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source4/torture/basic/misc.c b/source4/torture/basic/misc.c
index 68b7cbec812..25ae4560de8 100644
--- a/source4/torture/basic/misc.c
+++ b/source4/torture/basic/misc.c
@@ -985,6 +985,8 @@ bool run_benchrw(struct torture_context *tctx)
 					break;
 				}
 				state[i]->mode=FINISHED;
+
+				FALL_THROUGH;
 			case FINISHED:
 				finished++;
 				break;
-- 
2.14.2


>From 320a81b6755561fd7f3ee9203c0127a5413f7347 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 17:41:26 +0200
Subject: [PATCH 43/60] s4:torture: Add FALL_THROUGH statements in
 rpc/spoolss.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/torture/rpc/spoolss.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 31b9525ee62..91f32692042 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -1402,6 +1402,8 @@ static bool test_SetPrinter_errors(struct torture_context *tctx,
 				/* ignored then */
 				break;
 			}
+
+			FALL_THROUGH;
 		case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */
 		case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */
 		case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */
-- 
2.14.2


>From ec6e18c54b06543032ee1516e06c9540fdb8d635 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:20:53 +0200
Subject: [PATCH 44/60] auth:credentials: Add FALL_THROUGH statements in
 credentials.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 auth/credentials/credentials.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 4f3042e3152..4663185c979 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -1277,17 +1277,21 @@ _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credenti
 				*++p = '\0'; /* advance p, and null-terminate pass */
 				break;
 			}
-			/* fall through */
+
+			FALL_THROUGH;
 		case 0:
 			if (p - pass) {
 				*p = '\0'; /* null-terminate it, just in case... */
 				p = NULL; /* then force the loop condition to become false */
 				break;
-			} else {
-				fprintf(stderr, "Error reading password from file descriptor %d: %s\n", fd, "empty password\n");
-				return false;
 			}
 
+			fprintf(stderr,
+				"Error reading password from file descriptor "
+				"%d: empty password\n",
+				fd);
+			return false;
+
 		default:
 			fprintf(stderr, "Error reading password from file descriptor %d: %s\n",
 					fd, strerror(errno));
-- 
2.14.2


>From b0253fe38dd3431df4c42579eeed185d41cf9867 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:23:31 +0200
Subject: [PATCH 45/60] auth:credentials: Add FALL_THROUGH statements in
 credentials_secrets.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 auth/credentials/credentials_secrets.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index ed148fd3566..23981bd318c 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -369,7 +369,8 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credenti
 				if (security != SEC_ADS) {
 					break;
 				}
-				/* fall through */
+
+				FALL_THROUGH;
 			case ROLE_ACTIVE_DIRECTORY_DC:
 				use_kerberos = CRED_AUTO_USE_KERBEROS;
 				break;
-- 
2.14.2


>From 80efce97133b3772395c15f660bd96e423fd5c7b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 18:24:26 +0200
Subject: [PATCH 46/60] auth:gensec: Add FALL_THROUGH statements in spnego.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 auth/gensec/spnego.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c
index 9857e78184b..7913466e14c 100644
--- a/auth/gensec/spnego.c
+++ b/auth/gensec/spnego.c
@@ -1646,7 +1646,7 @@ static struct tevent_req *gensec_spnego_update_send(TALLOC_CTX *mem_ctx,
 			return tevent_req_post(req, ev);
 		}
 
-		/* fall through */
+		FALL_THROUGH;
 	case SPNEGO_CLIENT_START:
 	case SPNEGO_SERVER_START:
 
-- 
2.14.2


>From dd7e26dd658e955bae22f19d70cdff616a3b47d6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 16:56:27 +0200
Subject: [PATCH 47/60] nsswitch: Add FALL_THROUGH statements in pam_winbind.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 nsswitch/pam_winbind.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index 4ae646442f8..25ca6555645 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -2872,7 +2872,8 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
 			ret = atoi(tmp);
 			switch (ret) {
 			case PAM_AUTHTOK_EXPIRED:
-				/* fall through, since new token is required in this case */
+				/* Since new token is required in this case */
+				FALL_THROUGH;
 			case PAM_NEW_AUTHTOK_REQD:
 				_pam_log(ctx, LOG_WARNING,
 					 "pam_sm_acct_mgmt success but %s is set",
-- 
2.14.2


>From dd994626566db0d85662963a7deba8a58a57b863 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 27 Jul 2017 16:59:40 +0200
Subject: [PATCH 48/60] s3:libnet: Add FALL_THROUGH statements in libnet_join.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/libnet/libnet_join.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index eb6b894908f..6a8b9dda2f5 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -2381,7 +2381,8 @@ static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
 					valid_realm = true;
 					ignored_realm = true;
 				}
-				/* FALL THROUGH */
+
+				FALL_THROUGH;
 			case SEC_ADS:
 				valid_security = true;
 			}
-- 
2.14.2


>From 9c24f9a4b38b39fe770971056109aa31ad401595 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:08:36 +0200
Subject: [PATCH 49/60] s3:modules: Add FALL_THROUGH statements in getdate.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/modules/getdate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/source3/modules/getdate.c b/source3/modules/getdate.c
index 6ed994649c4..2879bc87f4b 100644
--- a/source3/modules/getdate.c
+++ b/source3/modules/getdate.c
@@ -1098,9 +1098,10 @@ yytnamerr (char *yyres, const char *yystr)
 	    goto do_not_strip_quotes;
 
 	  case '\\':
-	    if (*++yyp != '\\')
+	    if (*++yyp != '\\') {
 	      goto do_not_strip_quotes;
-	    /* Fall through.  */
+	    }
+	    FALL_THROUGH;
 	  default:
 	    if (yyres)
 	      yyres[yyn] = *yyp;
-- 
2.14.2


>From 1351500f26932a91b7518b0344695fa6c08f0e3d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:12:43 +0200
Subject: [PATCH 50/60] s3:lsa: Add FALL_THROUGH statements in srv_lsa_nt.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/rpc_server/lsa/srv_lsa_nt.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index 2d0d29e5f35..0089230abba 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -4288,11 +4288,13 @@ static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
 					exclusion = true;
 					break;
 				}
-				/* fall through */
+
+				FALL_THROUGH;
 			case DNS_CMP_FIRST_IS_CHILD:
 			case DNS_CMP_SECOND_IS_CHILD:
 				tln_conflict = true;
-				/* fall through */
+
+				FALL_THROUGH;
 			default:
 				break;
 			}
-- 
2.14.2


>From 86e38959b92b1d25fd1d717da6259f25ef39ae98 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:13:42 +0200
Subject: [PATCH 51/60] s3:rpcclient: Add FALL_THROUGH statements in
 rpcclient.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/rpcclient/rpcclient.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index c1039ed84c5..4eb1e145715 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -744,7 +744,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 				use_kerberos = CRED_AUTO_USE_KERBEROS;
 				break;
 			}
-			/* Fall through */
+			FALL_THROUGH;
 		case DCERPC_AUTH_TYPE_NTLMSSP:
 		case DCERPC_AUTH_TYPE_KRB5:
 			ntresult = cli_rpc_pipe_open_generic_auth(
-- 
2.14.2


>From 62e34ba864c06878cfe72a4d147873befd6781f1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:15:31 +0200
Subject: [PATCH 52/60] s3:smbd: Add FALL_THROUGH statements in reply.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/smbd/reply.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 7b07078249b..63a25e467d9 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -190,16 +190,16 @@ static NTSTATUS check_path_syntax_internal(char *path,
 			switch(siz) {
 				case 5:
 					*d++ = *s++;
-					/*fall through*/
+					FALL_THROUGH;
 				case 4:
 					*d++ = *s++;
-					/*fall through*/
+					FALL_THROUGH;
 				case 3:
 					*d++ = *s++;
-					/*fall through*/
+					FALL_THROUGH;
 				case 2:
 					*d++ = *s++;
-					/*fall through*/
+					FALL_THROUGH;
 				case 1:
 					*d++ = *s++;
 					break;
-- 
2.14.2


>From d0cb1671808b7e50ac9b552859ef71de0ae89ebb Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:18:09 +0200
Subject: [PATCH 53/60] s3:utils: Add FALL_THROUGH statements in
 net_registry_check.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/utils/net_registry_check.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/utils/net_registry_check.c b/source3/utils/net_registry_check.c
index de79f3e6af3..2274b739b0d 100644
--- a/source3/utils/net_registry_check.c
+++ b/source3/utils/net_registry_check.c
@@ -810,7 +810,8 @@ static int check_tdb_action(struct db_record *rec, void *check_ctx)
 					talloc_free(key);
 					key = p;
 				}
-			} /* fall through */
+				FALL_THROUGH;
+			}
 			case 'r': /* retry */
 				once_more = true;
 				break;
-- 
2.14.2


>From e01498589bcfd9cb79fd18093ca3e98c131e039f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:24:23 +0200
Subject: [PATCH 54/60] s3:utils: Add FALL_THROUGH statements in ntlm_auth.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/utils/ntlm_auth.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 5a10e27719f..ee89c897e3c 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -1376,7 +1376,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
 			 * NTLMSSP_CLIENT_1 for now.
 			 */
 			use_cached_creds = false;
-			/* fall through */
+			FALL_THROUGH;
 		case NTLMSSP_CLIENT_1:
 			/* setup the client side */
 
@@ -1472,7 +1472,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
 			if (!in.length) {
 				first = true;
 			}
-			/* fall through */
+			FALL_THROUGH;
 		case SQUID_2_5_NTLMSSP:
 			nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_NTLMSSP);
 			break;
-- 
2.14.2


>From 0fe18dda3e49ca8998392c0e35bfe1778e3221bc Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:25:27 +0200
Subject: [PATCH 55/60] s3:winbindd: Add FALL_THROUGH statements in
 idmap_autorid.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/winbindd/idmap_autorid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 39027d1511b..65b3d5af222 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -260,7 +260,7 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 		    }
 		    /* If we end up here, something weird is in the record. */
 
-		    /* FALL THROUGH */
+		    FALL_THROUGH;
 	    default:
 		    DBG_DEBUG("SID/domain range: %s\n",
 			      (const char *)data.dptr);
-- 
2.14.2


>From bc7986d9e058ecced952a1413dac2ef2db9a6488 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:26:38 +0200
Subject: [PATCH 56/60] s4:dsdb: Add FALL_THROUGH statements in password_hash.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/dsdb/samdb/ldb_modules/password_hash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index c428ff7f359..2e6464f0dd1 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -2241,7 +2241,7 @@ static int setup_last_set_field(struct setup_password_fields_io *io)
 		if (!io->ac->update_password) {
 			break;
 		}
-		/* fall through */
+		FALL_THROUGH;
 	case UINT64_MAX:
 		if (!io->ac->update_password &&
 		    io->u.pwdLastSet != 0 &&
-- 
2.14.2


>From 83155024838dfa6edf222fb47ced652930aab358 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:27:38 +0200
Subject: [PATCH 57/60] s4:lib: Add FALL_THROUGH statements in http.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source4/lib/http/http.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/lib/http/http.c b/source4/lib/http/http.c
index 659cba0ff14..10b49cd14fe 100644
--- a/source4/lib/http/http.c
+++ b/source4/lib/http/http.c
@@ -117,7 +117,7 @@ static enum http_read_status http_parse_headers(struct http_read_response_state
 				state->parser_state = HTTP_READING_BODY;
 				break;
 			}
-			/* fall through */
+			FALL_THROUGH;
 		case 0:
 			DEBUG(11, ("%s: Skipping body for code %d\n", __func__,
 				   state->response->response_code));
-- 
2.14.2


>From 817f62c3e596e6f369c27919754f98e079d82a0a Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:11:24 +0200
Subject: [PATCH 58/60] s3:spoolss: Remove incorrect fall through comment in
 srv_spoolss_nt.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 1476dc6bf15..21e3b718b74 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -1804,7 +1804,6 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
 		DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
 			? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
 
-		/* We fall through to return WERR_OK */
 		break;
 
 	case SPLHND_PRINTER:
-- 
2.14.2


>From 4809ee4f00d846f1f00e353f7e5f1ffef6218209 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 13 Oct 2017 11:06:48 +0200
Subject: [PATCH 59/60] libsmb: Remove incorrect fall through comment in
 trusts_util.c

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 source3/libsmb/trusts_util.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index 27e77e6cc60..1b2c43a0b59 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -82,7 +82,6 @@ char *trust_pw_new_value(TALLOC_CTX *mem_ctx,
 		min = 120;
 		max = 120;
 		break;
-		/* fall through */
 	case SEC_CHAN_DOMAIN:
 		/*
 		 * The maximum length of a trust account password.
-- 
2.14.2


>From cb151694310d46305f6612e547654b5fa029f33b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 26 Jul 2017 16:29:06 +0200
Subject: [PATCH 60/60] wafsamba: Add -Wimplicit-fallthrough if available

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 buildtools/wafsamba/samba_autoconf.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py
index 795d13075cf..2383e6d5c66 100644
--- a/buildtools/wafsamba/samba_autoconf.py
+++ b/buildtools/wafsamba/samba_autoconf.py
@@ -706,6 +706,8 @@ def SAMBA_CONFIG_H(conf, path=None):
                         testflags=True)
         conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
                         testflags=True)
+        conf.ADD_CFLAGS('-Wimplicit-fallthrough',
+                        testflags=True)
 
         conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
         conf.ADD_CFLAGS('-Werror=format-security -Wformat-security', testflags=True)
-- 
2.14.2



More information about the samba-technical mailing list