[PATCH] make nsswitch and libwbclient thread safe

Jeremy Allison jra at samba.org
Mon Oct 29 17:29:21 UTC 2018


On Mon, Oct 29, 2018 at 05:28:37PM +0100, Volker Lendecke via samba-technical wrote:
> On Mon, Oct 29, 2018 at 09:20:57AM -0700, Jeremy Allison wrote:
> > Ping for Ralph and Volker.
> > 
> > I'd love to get this into master if you both are
> > happy with it !
> 
> Ralph has found that the nss_wrapper needs some fixes. Attached find
> my patchset with my Reviewed-By: (really just finished). We can't put
> that into Samba, because the nss_wrapper piece needs to wait for the
> nss_wrapper team to get to the point where they have enough patches to
> justify a release. Then we need a patch to upgrade the in-tree
> nss_wrapper copy, and *then* we can start thinking about putting this
> into Samba. We will start working on that process asap.

Ah, the perils of depending on third-party :-).

Pinging Andreas.... !

Jeremy.

> -- 
> SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
> phone: +49-551-370000-0, fax: +49-551-370000-9
> AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
> http://www.sernet.de, mailto:kontakt at sernet.de

> From 993ed34e430ee58ec2698ab7ee3aae18a6a06fdd Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 11:27:04 +0200
> Subject: [PATCH 01/11] nwrap: fix nwrap_module_getpwnam_r
> 
> On success *pwdstp must point to pwdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index 566d02ca34b..5049883dcf9 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -3836,6 +3836,7 @@ static int nwrap_module_getpwnam_r(struct nwrap_backend *b,
>  	(void) pwdst; /* unused */
>  	(void) pwdstp; /* unused */
>  
> +	*pwdstp = NULL;
>  	if (!b->fns->_nss_getpwnam_r) {
>  		return NSS_STATUS_NOTFOUND;
>  	}
> @@ -3843,6 +3844,7 @@ static int nwrap_module_getpwnam_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getpwnam_r(name, pwdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*pwdstp = pwdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From a0e70a3d7de5af4af3c17916cdf75cb3319a5d87 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 12:15:53 +0200
> Subject: [PATCH 02/11] nwrap: fix nwrap_module_getpwuid_r
> 
> On success *pwdstp must point to pwdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index 5049883dcf9..5352058ee11 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -3893,6 +3893,7 @@ static int nwrap_module_getpwuid_r(struct nwrap_backend *b,
>  
>  	(void) pwdstp; /* unused */
>  
> +	*pwdstp = NULL;
>  	if (!b->fns->_nss_getpwuid_r) {
>  		return ENOENT;
>  	}
> @@ -3900,6 +3901,7 @@ static int nwrap_module_getpwuid_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getpwuid_r(uid, pwdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*pwdstp = pwdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From cc4270c6ec27ffd02c08cd0b8cb7cc8fb652b2ab Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 12:19:17 +0200
> Subject: [PATCH 03/11] nwrap: fix nwrap_module_getpwent_r
> 
> On success *pwdstp must point to pwdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index 5352058ee11..aae92c28129 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -3958,6 +3958,7 @@ static int nwrap_module_getpwent_r(struct nwrap_backend *b,
>  
>  	(void) pwdstp; /* unused */
>  
> +	*pwdstp = NULL;
>  	if (!b->fns->_nss_getpwent_r) {
>  		return ENOENT;
>  	}
> @@ -3965,6 +3966,7 @@ static int nwrap_module_getpwent_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getpwent_r(pwdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*pwdstp = pwdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From f48298cf16d79f24d12a4f580509d23ee20427d7 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 15:19:28 +0200
> Subject: [PATCH 04/11] nwrap: fix nwrap_module_getgrnam_r
> 
> On success *grdstp must point to grdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index aae92c28129..064194727b5 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -4053,6 +4053,7 @@ static int nwrap_module_getgrnam_r(struct nwrap_backend *b,
>  
>  	(void) grdstp; /* unused */
>  
> +	*grdstp = NULL;
>  	if (!b->fns->_nss_getgrnam_r) {
>  		return ENOENT;
>  	}
> @@ -4060,6 +4061,7 @@ static int nwrap_module_getgrnam_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getgrnam_r(name, grdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*grdstp = grdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From e22b6e65391d928d988355262aecf2b7865e04a3 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 15:22:23 +0200
> Subject: [PATCH 05/11] nwrap: fix nwrap_module_getgrgid_r
> 
> On success *grdstp must point to grdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index 064194727b5..0538c7919a8 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -4126,6 +4126,7 @@ static int nwrap_module_getgrgid_r(struct nwrap_backend *b,
>  
>  	(void) grdstp; /* unused */
>  
> +	*grdstp = NULL;
>  	if (!b->fns->_nss_getgrgid_r) {
>  		return ENOENT;
>  	}
> @@ -4133,6 +4134,7 @@ static int nwrap_module_getgrgid_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getgrgid_r(gid, grdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*grdstp = grdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From 7ccdb98c91caf174ddc73bb5b0de49d12fe7d5fa Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 19 Oct 2018 15:24:21 +0200
> Subject: [PATCH 06/11] nwrap: fix nwrap_module_getgrent_r
> 
> On success *grdstp must point to grdst, on error return NULL instead.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  third_party/nss_wrapper/nss_wrapper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/third_party/nss_wrapper/nss_wrapper.c b/third_party/nss_wrapper/nss_wrapper.c
> index 0538c7919a8..d7839519159 100644
> --- a/third_party/nss_wrapper/nss_wrapper.c
> +++ b/third_party/nss_wrapper/nss_wrapper.c
> @@ -4207,6 +4207,7 @@ static int nwrap_module_getgrent_r(struct nwrap_backend *b,
>  
>  	(void) grdstp; /* unused */
>  
> +	*grdstp = NULL;
>  	if (!b->fns->_nss_getgrent_r) {
>  		return ENOENT;
>  	}
> @@ -4214,6 +4215,7 @@ static int nwrap_module_getgrent_r(struct nwrap_backend *b,
>  	ret = b->fns->_nss_getgrent_r(grdst, buf, buflen, &errno);
>  	switch (ret) {
>  	case NSS_STATUS_SUCCESS:
> +		*grdstp = grdst;
>  		return 0;
>  	case NSS_STATUS_NOTFOUND:
>  		if (errno != 0) {
> -- 
> 2.11.0
> 
> 
> From c923641c92238b0443714d232306cd2c79cb5154 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Tue, 2 Oct 2018 10:58:12 +0200
> Subject: [PATCH 07/11] nsswitch: use goto to have only one function return
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  nsswitch/wb_common.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
> index 42b341b8c1c..c2f67d7a556 100644
> --- a/nsswitch/wb_common.c
> +++ b/nsswitch/wb_common.c
> @@ -731,10 +731,12 @@ NSS_STATUS winbindd_request_response(struct winbindd_context *ctx,
>  	}
>  
>  	status = winbindd_send_request(ctx, req_type, 0, request);
> -	if (status != NSS_STATUS_SUCCESS)
> -		return (status);
> +	if (status != NSS_STATUS_SUCCESS) {
> +		goto out;
> +	}
>  	status = winbindd_get_response(ctx, response);
>  
> +out:
>  	return status;
>  }
>  
> @@ -750,10 +752,12 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx,
>  	}
>  
>  	status = winbindd_send_request(ctx, req_type, 1, request);
> -	if (status != NSS_STATUS_SUCCESS)
> -		return (status);
> +	if (status != NSS_STATUS_SUCCESS) {
> +		goto out;
> +	}
>  	status = winbindd_get_response(ctx, response);
>  
> +out:
>  	return status;
>  }
>  
> -- 
> 2.11.0
> 
> 
> From deed9b57ef55b3b968554d8f14159704fe15f3bd Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Tue, 2 Oct 2018 13:35:16 +0200
> Subject: [PATCH 08/11] nsswitch: make wb_global_ctx private add add get/put
>  functions to access global context
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  nsswitch/wb_common.c | 41 +++++++++++++++++++++++++++++++++--------
>  1 file changed, 33 insertions(+), 8 deletions(-)
> 
> diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
> index c2f67d7a556..9ba74c35a6d 100644
> --- a/nsswitch/wb_common.c
> +++ b/nsswitch/wb_common.c
> @@ -35,11 +35,22 @@ struct winbindd_context {
>  	pid_t our_pid;		/* calling process pid */
>  };
>  
> -static struct winbindd_context wb_global_ctx = {
> -	.winbindd_fd = -1,
> -	.is_privileged = false,
> -	.our_pid = 0
> -};
> +static struct winbindd_context *get_wb_global_ctx(void)
> +{
> +	static struct winbindd_context wb_global_ctx = {
> +		.winbindd_fd = -1,
> +		.is_privileged = false,
> +		.our_pid = 0
> +	};
> +
> +	return &wb_global_ctx;
> +}
> +
> +static void put_wb_global_ctx(void)
> +{
> +	/* noop for now */
> +	return;
> +}
>  
>  /* Free a response structure */
>  
> @@ -93,7 +104,11 @@ __attribute__((destructor))
>  #endif
>  static void winbind_destructor(void)
>  {
> -	winbind_close_sock(&wb_global_ctx);
> +	struct winbindd_context *ctx;
> +
> +	ctx = get_wb_global_ctx();
> +	winbind_close_sock(ctx);
> +	put_wb_global_ctx();
>  }
>  
>  #define CONNECT_TIMEOUT 30
> @@ -725,9 +740,11 @@ NSS_STATUS winbindd_request_response(struct winbindd_context *ctx,
>  				     struct winbindd_response *response)
>  {
>  	NSS_STATUS status = NSS_STATUS_UNAVAIL;
> +	bool release_global_ctx = false;
>  
>  	if (ctx == NULL) {
> -		ctx = &wb_global_ctx;
> +		ctx = get_wb_global_ctx();
> +		release_global_ctx = true;
>  	}
>  
>  	status = winbindd_send_request(ctx, req_type, 0, request);
> @@ -737,6 +754,9 @@ NSS_STATUS winbindd_request_response(struct winbindd_context *ctx,
>  	status = winbindd_get_response(ctx, response);
>  
>  out:
> +	if (release_global_ctx) {
> +		put_wb_global_ctx();
> +	}
>  	return status;
>  }
>  
> @@ -746,9 +766,11 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx,
>  					  struct winbindd_response *response)
>  {
>  	NSS_STATUS status = NSS_STATUS_UNAVAIL;
> +	bool release_global_ctx = false;
>  
>  	if (ctx == NULL) {
> -		ctx = &wb_global_ctx;
> +		ctx = get_wb_global_ctx();
> +		release_global_ctx = true;
>  	}
>  
>  	status = winbindd_send_request(ctx, req_type, 1, request);
> @@ -758,6 +780,9 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx,
>  	status = winbindd_get_response(ctx, response);
>  
>  out:
> +	if (release_global_ctx) {
> +		put_wb_global_ctx();
> +	}
>  	return status;
>  }
>  
> -- 
> 2.11.0
> 
> 
> From 5a5331bf3c4d50a9abf800b9dac8ea212f3e5b74 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Tue, 2 Oct 2018 13:41:00 +0200
> Subject: [PATCH 09/11] nsswitch: protect access to wb_global_ctx by a mutex
> 
> This change will make libwbclient thread safe for all API calls not using a
> context. Especially there are no more conflicts with threads using nsswitch
> and libwbclient in parallel.
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  nsswitch/wb_common.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
> index 9ba74c35a6d..59370aa5bbc 100644
> --- a/nsswitch/wb_common.c
> +++ b/nsswitch/wb_common.c
> @@ -27,6 +27,10 @@
>  #include "system/select.h"
>  #include "winbind_client.h"
>  
> +#if HAVE_PTHREAD_H
> +#include <pthread.h>
> +#endif
> +
>  /* Global context */
>  
>  struct winbindd_context {
> @@ -35,6 +39,10 @@ struct winbindd_context {
>  	pid_t our_pid;		/* calling process pid */
>  };
>  
> +#if HAVE_PTHREAD
> +static pthread_mutex_t wb_global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
> +#endif
> +
>  static struct winbindd_context *get_wb_global_ctx(void)
>  {
>  	static struct winbindd_context wb_global_ctx = {
> @@ -43,12 +51,17 @@ static struct winbindd_context *get_wb_global_ctx(void)
>  		.our_pid = 0
>  	};
>  
> +#if HAVE_PTHREAD
> +	pthread_mutex_lock(&wb_global_ctx_mutex);
> +#endif
>  	return &wb_global_ctx;
>  }
>  
>  static void put_wb_global_ctx(void)
>  {
> -	/* noop for now */
> +#if HAVE_PTHREAD
> +	pthread_mutex_unlock(&wb_global_ctx_mutex);
> +#endif
>  	return;
>  }
>  
> -- 
> 2.11.0
> 
> 
> From 9df57391cd0c4a1e360209b0699e03c73b306519 Mon Sep 17 00:00:00 2001
> From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Date: Fri, 5 Oct 2018 13:53:30 +0200
> Subject: [PATCH 10/11] nsswitch: add test for parallel NSS & libwbclient calls
> 
> Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
> Reviewed-by: Volker Lendecke <vl at samba.org>
> ---
>  nsswitch/stress-nss-libwbclient.c | 156 ++++++++++++++++++++++++++++++++++++++
>  nsswitch/wscript_build            |   7 ++
>  2 files changed, 163 insertions(+)
>  create mode 100644 nsswitch/stress-nss-libwbclient.c
> 
> diff --git a/nsswitch/stress-nss-libwbclient.c b/nsswitch/stress-nss-libwbclient.c
> new file mode 100644
> index 00000000000..cf85ff3f817
> --- /dev/null
> +++ b/nsswitch/stress-nss-libwbclient.c
> @@ -0,0 +1,156 @@
> +/*
> +   Unix SMB/CIFS implementation.
> +
> +   Stress test for parallel NSS & libwbclient calls.
> +
> +   Copyright (C) Ralph Wuerthner 2018
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <pthread.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <time.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <pwd.h>
> +#include <wbclient.h>
> +
> +#define RUNTIME 10
> +
> +struct thread_state {
> +	const char *username;
> +	time_t timeout;
> +	pthread_mutex_t lock;
> +	bool fail;
> +	int nss_loop_count;
> +	int wbc_loop_count;
> +};
> +
> +static void *query_nss_thread(void *ptr)
> +{
> +	struct thread_state *state = ptr;
> +	char buf[1024];
> +	int rc;
> +	struct passwd pwd, *result;
> +
> +	while (time(NULL) < state->timeout) {
> +		rc = getpwnam_r(state->username,
> +				&pwd,
> +				buf,
> +				sizeof(buf),
> +				&result);
> +		if (rc != 0 || result == NULL) {
> +			pthread_mutex_lock(&state->lock);
> +			state->fail = true;
> +			pthread_mutex_unlock(&state->lock);
> +			fprintf(stderr,
> +				"getpwnam_r failed with rc='%s' result=%p\n",
> +				strerror(rc),
> +				result);
> +			break;
> +		}
> +		state->nss_loop_count++;
> +		pthread_mutex_lock(&state->lock);
> +		if (state->fail) {
> +			pthread_mutex_unlock(&state->lock);
> +			break;
> +		}
> +		pthread_mutex_unlock(&state->lock);
> +	}
> +	return NULL;
> +}
> +
> +static void *query_wbc_thread(void *ptr)
> +{
> +	struct thread_state *state = ptr;
> +	struct passwd *ppwd;
> +	wbcErr wbc_status;
> +
> +	while (time(NULL) < state->timeout) {
> +		wbc_status = wbcGetpwnam(state->username, &ppwd);
> +		if (!WBC_ERROR_IS_OK(wbc_status)) {
> +			pthread_mutex_lock(&state->lock);
> +			state->fail = true;
> +			pthread_mutex_unlock(&state->lock);
> +			fprintf(stderr,
> +				"wbcGetpwnam failed with %s\n",
> +				wbcErrorString(wbc_status));
> +			break;
> +		}
> +		wbcFreeMemory(ppwd);
> +		state->wbc_loop_count++;
> +		pthread_mutex_lock(&state->lock);
> +		if (state->fail) {
> +			pthread_mutex_unlock(&state->lock);
> +			break;
> +		}
> +		pthread_mutex_unlock(&state->lock);
> +	}
> +	return NULL;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	int rc, n;
> +	struct thread_state state;
> +	pthread_t threads[2];
> +
> +	if (argc < 2 ) {
> +		fprintf(stderr,"%s: missing domain user\n", argv[0]);
> +		return 1;
> +	}
> +
> +	state.username = argv[1];
> +	state.timeout = time(NULL) + RUNTIME;
> +	pthread_mutex_init(&state.lock, NULL);
> +	state.fail = false;
> +	state.nss_loop_count = 0;
> +	state.wbc_loop_count = 0;
> +
> +	printf("query domain user '%s'\n", state.username);
> +
> +	/* create query threads */
> +	rc = pthread_create(&threads[0], NULL, query_nss_thread, &state);
> +	if (rc != 0) {
> +		fprintf(stderr,
> +			"creating NSS thread failed: %s\n",
> +			strerror(rc));
> +		exit(1);
> +	}
> +	rc = pthread_create(&threads[1], NULL, query_wbc_thread, &state);
> +	if (rc != 0) {
> +		fprintf(stderr,
> +			"creating libwbclient thread failed: %s\n",
> +			strerror(rc));
> +		exit(1);
> +	}
> +
> +	/* wait for query threads to terminate */
> +	for (n = 0; n < 2; n++) {
> +		pthread_join(threads[n], NULL);
> +	}
> +
> +	fprintf(state.fail ? stderr: stdout,
> +		"test %s with %i NSS and %i libwbclient calls\n",
> +		state.fail ? "failed" : "passed",
> +		state.nss_loop_count,
> +		state.wbc_loop_count);
> +
> +	return state.fail;
> +}
> diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build
> index ff98372fd6e..6acc4a19b9b 100644
> --- a/nsswitch/wscript_build
> +++ b/nsswitch/wscript_build
> @@ -17,6 +17,13 @@ bld.SAMBA_BINARY('nsstest',
>                   install=False
>  		 )
>  
> +if bld.CONFIG_SET('HAVE_PTHREAD'):
> +    bld.SAMBA_BINARY('stress-nss-libwbclient',
> +		     source='stress-nss-libwbclient.c',
> +		     deps='wbclient',
> +		     install=False
> +		     )
> +
>  # The nss_wrapper code relies strictly on the linux implementation and
>  # name, so compile but do not install a copy under this name.
>  bld.SAMBA_LIBRARY('nss_wrapper_winbind',
> -- 
> 2.11.0
> 
> 
> From 50fd2de30f13afedc991677c9a43f44873b5c9c6 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 5 Oct 2018 16:27:48 +0200
> Subject: [PATCH 11/11] nsswitch: Run nsswitch thread test
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/script/tests/test_libwbclient_threads.sh | 17 +++++++++++++++++
>  source3/selftest/tests.py                        |  7 +++++++
>  2 files changed, 24 insertions(+)
>  create mode 100755 source3/script/tests/test_libwbclient_threads.sh
> 
> diff --git a/source3/script/tests/test_libwbclient_threads.sh b/source3/script/tests/test_libwbclient_threads.sh
> new file mode 100755
> index 00000000000..1f8d041b7af
> --- /dev/null
> +++ b/source3/script/tests/test_libwbclient_threads.sh
> @@ -0,0 +1,17 @@
> +#!/bin/sh
> +
> +if [ $# -lt 2 ] ; then
> +cat <<EOF
> +Usage: test_libwbclient_threads.sh DOMAIN USERNAME
> +EOF
> +exit 1;
> +fi
> +
> +DOMAIN="$1"
> +USERNAME="$2"
> +shift 2
> +
> +incdir=`dirname $0`/../../../testprogs/blackbox
> +. $incdir/subunit.sh
> +
> +testit "libwbclient-threads" "$BINDIR/stress-nss-libwbclient" "$DOMAIN/$USERNAME"
> diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
> index 75190c49b2b..e990aaf10e7 100755
> --- a/source3/selftest/tests.py
> +++ b/source3/selftest/tests.py
> @@ -385,6 +385,13 @@ if with_pthreadpool and have_ldwrap:
>      plantestsuite("samba3.pthreadpool_cmocka", "none",
>                    [os.path.join(bindir(), "pthreadpooltest_cmocka")])
>  
> +if with_pthreadpool:
> +    plantestsuite("samba3.libwbclient_threads",
> +                  "nt4_member",
> +                  [os.path.join(samba3srcdir,
> +                                "script/tests/test_libwbclient_threads.sh"),
> +                   "$DOMAIN", "$DC_USERNAME"])
> +
>  plantestsuite("samba3.async_req", "nt4_dc",
>                [os.path.join(samba3srcdir, "script/tests/test_async_req.sh")])
>  
> -- 
> 2.11.0
> 




More information about the samba-technical mailing list