[PATCH] Harden Samba module functions

Jeremy Allison jra at samba.org
Tue Jun 6 16:23:16 UTC 2017


On Tue, Jun 06, 2017 at 10:58:58AM +0200, Andreas Schneider wrote:
> On Thursday, 1 June 2017 10:41:26 CEST Andrew Bartlett wrote:
> > On Thu, 2017-06-01 at 10:15 +0200, Andreas Schneider via samba-
> > 
> > technical wrote:
> > > Take a look at this patchset.
> > 
> > G'Day Andreas,
> > 
> > Sorry to bike-shed this, but could you just set an environment variable
> > rather than modify the file system (and so have what could look like
> > /tmp races)?
> > 
> > I think you should also load the module once in the successful way
> > (rather than auth/skel) and once with the full path, so we don't get a
> > false positive this test if the module is just busted.
> > 
> > Andrew Bartlett
> 
> See attached.

This looks *GREAT* Andreas, thank you ! RB+.

> Andreas Schneider                   GPG-ID: CC014E3D
> Samba Team                             asn at samba.org
> www.samba.org

> From 0cd3e2878ea041b335cc7d88ec0a5ecbe3a073a5 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 11 May 2017 11:29:50 +0200
> Subject: [PATCH 1/7] wafsamba: Pass down the install argument for samba
>  modules
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  buildtools/wafsamba/wafsamba.py | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
> index 137cb0e4330..1bdabf60640 100644
> --- a/buildtools/wafsamba/wafsamba.py
> +++ b/buildtools/wafsamba/wafsamba.py
> @@ -465,7 +465,8 @@ def SAMBA_MODULE(bld, modname, source,
>                   pyembed=False,
>                   manpages=None,
>                   allow_undefined_symbols=False,
> -                 allow_warnings=False
> +                 allow_warnings=False,
> +                 install=True
>                   ):
>      '''define a Samba module.'''
>  
> @@ -535,7 +536,8 @@ def SAMBA_MODULE(bld, modname, source,
>                        pyembed=pyembed,
>                        manpages=manpages,
>                        allow_undefined_symbols=allow_undefined_symbols,
> -                      allow_warnings=allow_warnings
> +                      allow_warnings=allow_warnings,
> +                      install=install
>                        )
>  
>  
> -- 
> 2.13.0
> 
> 
> From 5b56483e24e008d0822459b3dbdd2eb5ca36ba40 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 11 May 2017 11:29:25 +0200
> Subject: [PATCH 2/7] unittest: Add testsuite for is_known_pipename()
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  selftest/tests.py                           |  2 +
>  testsuite/unittests/rpc_test_dummy_module.c | 20 ++++++++
>  testsuite/unittests/test_sambafs_srv_pipe.c | 76 +++++++++++++++++++++++++++++
>  testsuite/unittests/wscript                 | 17 +++++++
>  4 files changed, 115 insertions(+)
>  create mode 100644 testsuite/unittests/rpc_test_dummy_module.c
>  create mode 100644 testsuite/unittests/test_sambafs_srv_pipe.c
> 
> diff --git a/selftest/tests.py b/selftest/tests.py
> index e3dd91414d9..9f298a6f734 100644
> --- a/selftest/tests.py
> +++ b/selftest/tests.py
> @@ -145,3 +145,5 @@ if with_pam:
>  if with_cmocka:
>      plantestsuite("samba.unittests.krb5samba", "none",
>                    [os.path.join(bindir(), "default/testsuite/unittests/test_krb5samba")])
> +    plantestsuite("samba.unittests.sambafs_srv_pipe", "none",
> +                  [os.path.join(bindir(), "default/testsuite/unittests/test_sambafs_srv_pipe")])
> diff --git a/testsuite/unittests/rpc_test_dummy_module.c b/testsuite/unittests/rpc_test_dummy_module.c
> new file mode 100644
> index 00000000000..d067b6e2d2b
> --- /dev/null
> +++ b/testsuite/unittests/rpc_test_dummy_module.c
> @@ -0,0 +1,20 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <signal.h>
> +#include <unistd.h>
> +
> +int samba_init_module(void);
> +int samba_init_module(void)
> +{
> +	int rc;
> +
> +	fprintf(stderr, "Test dummy executed!\n");
> +
> +	rc = setenv("UNITTEST_DUMMY_MODULE_LOADED", "TRUE", 1);
> +	if (rc < 0) {
> +		kill(getpid(), SIGILL);
> +		exit(-1);
> +	}
> +
> +	return 0;
> +}
> diff --git a/testsuite/unittests/test_sambafs_srv_pipe.c b/testsuite/unittests/test_sambafs_srv_pipe.c
> new file mode 100644
> index 00000000000..641e99d932b
> --- /dev/null
> +++ b/testsuite/unittests/test_sambafs_srv_pipe.c
> @@ -0,0 +1,76 @@
> +#include <errno.h>
> +#include <stdarg.h>
> +#include <stddef.h>
> +#include <setjmp.h>
> +#include <unistd.h>
> +#include <sys/stat.h>
> +#include <cmocka.h>
> +
> +#include "include/config.h"
> +#include "librpc/gen_ndr/ndr_samr.h"
> +#include "source3/rpc_server/srv_pipe.h"
> +#include "librpc/gen_ndr/srv_samr.h"
> +
> +static int setup_samr(void **state)
> +{
> +	rpc_samr_init(NULL);
> +
> +	return 0;
> +}
> +
> +static int teardown(void **state)
> +{
> +	unsetenv("UNITTEST_DUMMY_MODULE_LOADED");
> +
> +	return 0;
> +}
> +
> +static int teardown_samr(void **state)
> +{
> +	rpc_samr_shutdown();
> +
> +	teardown(state);
> +
> +	return 0;
> +}
> +
> +static void test_is_known_pipename(void **state)
> +{
> +	struct ndr_syntax_id syntax_id = ndr_table_samr.syntax_id;
> +	bool is_pipename_ok;
> +
> +	is_pipename_ok = is_known_pipename("samr", &syntax_id);
> +	assert_true(is_pipename_ok);
> +}
> +
> +static void test_is_known_pipename_slash(void **state)
> +{
> +	struct ndr_syntax_id syntax_id = ndr_table_samr.syntax_id;
> +	bool is_pipename_ok;
> +	char dummy_module_path[4096] = {0};
> +	const char *module_env;
> +
> +	snprintf(dummy_module_path,
> +		 sizeof(dummy_module_path),
> +		 "%s/bin/modules/rpc/test_dummy_module.so",
> +		 SRCDIR);
> +
> +	is_pipename_ok = is_known_pipename(dummy_module_path, &syntax_id);
> +	assert_false(is_pipename_ok);
> +
> +	module_env = getenv("UNITTEST_DUMMY_MODULE_LOADED");
> +	assert_null(module_env);
> +}
> +
> +int main(void) {
> +	const struct CMUnitTest tests[] = {
> +		cmocka_unit_test_setup_teardown(test_is_known_pipename,
> +						setup_samr,
> +						teardown_samr),
> +		cmocka_unit_test_teardown(test_is_known_pipename_slash,
> +					  teardown),
> +	};
> +
> +	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
> +	return cmocka_run_group_tests(tests, NULL, NULL);
> +}
> diff --git a/testsuite/unittests/wscript b/testsuite/unittests/wscript
> index 355ab0cc10a..bb29fd8cba2 100644
> --- a/testsuite/unittests/wscript
> +++ b/testsuite/unittests/wscript
> @@ -10,3 +10,20 @@ def build(bld):
>                       source='test_krb5_samba.c',
>                       deps='krb5samba cmocka',
>                       install=False)
> +
> +    bld.SAMBA_BINARY('test_sambafs_srv_pipe',
> +                     source='test_sambafs_srv_pipe.c',
> +                     deps='''
> +                          RPC_SERVER
> +                          RPC_SAMR
> +                          cmocka
> +                          ''',
> +                     install=False)
> +
> +    bld.SAMBA_MODULE('rpc_test_dummy_module',
> +                     source='rpc_test_dummy_module.c',
> +                     deps='ndr',
> +                     subsystem='rpc',
> +                     allow_undefined_symbols=True,
> +                     init_function='',
> +                     internal_module=False)
> -- 
> 2.13.0
> 
> 
> From 86a50982dac4c14ebf5f40f5f7a88f6b71010d85 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 15 May 2017 09:06:51 +0200
> Subject: [PATCH 3/7] lib:util: Add new function to load modules from absolute
>  path
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  lib/util/modules.c | 42 ++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/util/modules.c b/lib/util/modules.c
> index c3c05f21f33..c693e5f32bb 100644
> --- a/lib/util/modules.c
> +++ b/lib/util/modules.c
> @@ -147,6 +147,36 @@ init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem)
>  	return ret;
>  }
>  
> +static NTSTATUS load_module_absolute_path(const char *module_path,
> +					  bool is_probe)
> +{
> +	void *handle;
> +	init_module_fn init;
> +	NTSTATUS status;
> +
> +	DBG_INFO("%s module '%s'\n",
> +		 is_probe ? "Probing" : "Loading",
> +		 module_path);
> +
> +	init = load_module(module_path, is_probe, &handle);
> +	if (init == NULL) {
> +		return NT_STATUS_UNSUCCESSFUL;
> +	}
> +
> +	DBG_NOTICE("Module '%s' loaded\n", module_path);
> +
> +	status = init(NULL);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		DBG_ERR("Module '%s' initialization failed: %s\n",
> +			module_path,
> +			get_friendly_nt_error_msg(status));
> +		dlclose(handle);
> +		return status;
> +	}
> +
> +	return NT_STATUS_OK;
> +}
> +
>  
>  /* Load a dynamic module.  Only log a level 0 error if we are not checking
>     for the existence of a module (probling). */
> @@ -212,8 +242,16 @@ int smb_load_modules(const char **modules)
>  	int i;
>  	int success = 0;
>  
> -	for(i = 0; modules[i]; i++){
> -		if(NT_STATUS_IS_OK(do_smb_load_module(NULL, modules[i], false))) {
> +	for(i = 0; modules[i] != NULL; i++) {
> +		const char *module = modules[i];
> +		NTSTATUS status;
> +
> +		if (module[0] != '/') {
> +			continue;
> +		}
> +
> +		status = load_module_absolute_path(module, false);
> +		if (NT_STATUS_IS_OK(status)) {
>  			success++;
>  		}
>  	}
> -- 
> 2.13.0
> 
> 
> From 88c48a42bbeab89f32d9d57ee3cc835ce4094cb1 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 15 May 2017 10:49:07 +0200
> Subject: [PATCH 4/7] lib:util: Rename smb_load_modules()
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  lib/util/modules.c       | 2 +-
>  lib/util/samba_modules.h | 2 +-
>  source3/smbd/process.c   | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/util/modules.c b/lib/util/modules.c
> index c693e5f32bb..e8a86c47fdf 100644
> --- a/lib/util/modules.c
> +++ b/lib/util/modules.c
> @@ -237,7 +237,7 @@ static NTSTATUS do_smb_load_module(const char *subsystem,
>  
>  /* Load all modules in list and return number of
>   * modules that has been successfully loaded */
> -int smb_load_modules(const char **modules)
> +int smb_load_all_modules_absoute_path(const char **modules)
>  {
>  	int i;
>  	int success = 0;
> diff --git a/lib/util/samba_modules.h b/lib/util/samba_modules.h
> index 1ae9c6e0e90..d7a452159ab 100644
> --- a/lib/util/samba_modules.h
> +++ b/lib/util/samba_modules.h
> @@ -53,7 +53,7 @@ bool run_init_functions(TALLOC_CTX *ctx, init_module_fn *fns);
>   */
>  init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem);
>  
> -int smb_load_modules(const char **modules);
> +int smb_load_all_modules_absoute_path(const char **modules);
>  NTSTATUS smb_probe_module(const char *subsystem, const char *module);
>  NTSTATUS smb_load_module(const char *subsystem, const char *module);
>  
> diff --git a/source3/smbd/process.c b/source3/smbd/process.c
> index 8f097ecbc00..d5c03b94199 100644
> --- a/source3/smbd/process.c
> +++ b/source3/smbd/process.c
> @@ -4018,7 +4018,7 @@ void smbd_process(struct tevent_context *ev_ctx,
>  			   locaddr);
>  
>  	if (lp_preload_modules()) {
> -		smb_load_modules(lp_preload_modules());
> +		smb_load_all_modules_absoute_path(lp_preload_modules());
>  	}
>  
>  	smb_perfcount_init();
> -- 
> 2.13.0
> 
> 
> From a2abf36bc6cb1a3fd5d80c6d82e8e49d419c981f Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 15 May 2017 11:05:59 +0200
> Subject: [PATCH 5/7] lib:util: Make probing of modules more secure
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  lib/util/modules.c       | 66 +++++++++++++++++++++++++++++++++++++++++++++++-
>  lib/util/samba_modules.h |  1 +
>  source3/smbd/perfcount.c |  2 +-
>  3 files changed, 67 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/util/modules.c b/lib/util/modules.c
> index e8a86c47fdf..978053e367b 100644
> --- a/lib/util/modules.c
> +++ b/lib/util/modules.c
> @@ -261,9 +261,73 @@ int smb_load_all_modules_absoute_path(const char **modules)
>  	return success;
>  }
>  
> +/**
> + * @brief Check if a module exist and load it.
> + *
> + * @param[in]  subsystem  The name of the subsystem the module belongs too.
> + *
> + * @param[in]  module     The name of the module
> + *
> + * @return  A NTSTATUS code
> + */
>  NTSTATUS smb_probe_module(const char *subsystem, const char *module)
>  {
> -	return do_smb_load_module(subsystem, module, true);
> +	NTSTATUS status;
> +	char *module_path = NULL;
> +	TALLOC_CTX *tmp_ctx = talloc_stackframe();
> +
> +	if (subsystem == NULL) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +	if (module == NULL) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +
> +	if (strchr(module, '/')) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +
> +	module_path = talloc_asprintf(tmp_ctx,
> +				      "%s/%s.%s",
> +				      modules_path(tmp_ctx, subsystem),
> +				      module,
> +				      shlib_ext());
> +	if (module_path == NULL) {
> +		status = NT_STATUS_NO_MEMORY;
> +		goto done;
> +	}
> +
> +	status = load_module_absolute_path(module_path, true);
> +
> +done:
> +	TALLOC_FREE(tmp_ctx);
> +	return status;
> +}
> +
> +/**
> + * @brief Check if a module exist and load it.
> + *
> + * Warning: Using this function can have security implecations!
> + *
> + * @param[in]  subsystem  The name of the subsystem the module belongs too.
> + *
> + * @param[in]  module     Load a module using an abolute path.
> + *
> + * @return  A NTSTATUS code
> + */
> +NTSTATUS smb_probe_module_absolute_path(const char *module)
> +{
> +	if (module == NULL) {
> +		return NT_STATUS_INVALID_PARAMETER;
> +	}
> +	if (module[0] != '/') {
> +		return NT_STATUS_INVALID_PARAMETER;
> +	}
> +
> +	return load_module_absolute_path(module, true);
>  }
>  
>  NTSTATUS smb_load_module(const char *subsystem, const char *module)
> diff --git a/lib/util/samba_modules.h b/lib/util/samba_modules.h
> index d7a452159ab..c6986910c38 100644
> --- a/lib/util/samba_modules.h
> +++ b/lib/util/samba_modules.h
> @@ -55,6 +55,7 @@ init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem);
>  
>  int smb_load_all_modules_absoute_path(const char **modules);
>  NTSTATUS smb_probe_module(const char *subsystem, const char *module);
> +NTSTATUS smb_probe_module_absolute_path(const char *module);
>  NTSTATUS smb_load_module(const char *subsystem, const char *module);
>  
>  #endif /* _SAMBA_MODULES_H */
> diff --git a/source3/smbd/perfcount.c b/source3/smbd/perfcount.c
> index a7c268a2fef..1555ea24b64 100644
> --- a/source3/smbd/perfcount.c
> +++ b/source3/smbd/perfcount.c
> @@ -144,7 +144,7 @@ static bool smb_load_perfcount_module(const char *name)
>  
>  	/* load the perfcounter module */
>  	if((entry = smb_perfcount_find_module(module_name)) ||
> -	   (NT_STATUS_IS_OK(smb_probe_module("perfcount", module_path)) &&
> +	   (NT_STATUS_IS_OK(smb_probe_module_absolute_path(module_path)) &&
>  		(entry = smb_perfcount_find_module(module_name)))) {
>  
>  		DEBUG(3,("Successfully loaded perfcounter module [%s] \n", name));
> -- 
> 2.13.0
> 
> 
> From f8126cc1bb6e987708e605533441046cce033051 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 15 May 2017 11:08:19 +0200
> Subject: [PATCH 6/7] lib:util: Make loading of modules more secure
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  lib/util/modules.c | 101 ++++++++++++++++++++++-------------------------------
>  1 file changed, 42 insertions(+), 59 deletions(-)
> 
> diff --git a/lib/util/modules.c b/lib/util/modules.c
> index 978053e367b..cf52594f619 100644
> --- a/lib/util/modules.c
> +++ b/lib/util/modules.c
> @@ -177,64 +177,6 @@ static NTSTATUS load_module_absolute_path(const char *module_path,
>  	return NT_STATUS_OK;
>  }
>  
> -
> -/* Load a dynamic module.  Only log a level 0 error if we are not checking
> -   for the existence of a module (probling). */
> -
> -static NTSTATUS do_smb_load_module(const char *subsystem,
> -				   const char *module_name, bool is_probe)
> -{
> -	void *handle;
> -	init_module_fn init;
> -	NTSTATUS status;
> -
> -	char *full_path = NULL;
> -	TALLOC_CTX *ctx = talloc_stackframe();
> -
> -	if (module_name == NULL) {
> -		TALLOC_FREE(ctx);
> -		return NT_STATUS_INVALID_PARAMETER;
> -	}
> -
> -	/* Check for absolute path */
> -
> -	DEBUG(5, ("%s module '%s'\n", is_probe ? "Probing" : "Loading", module_name));
> -
> -	if (subsystem && module_name[0] != '/') {
> -		full_path = talloc_asprintf(ctx,
> -					    "%s/%s.%s",
> -					    modules_path(ctx, subsystem),
> -					    module_name,
> -					    shlib_ext());
> -		if (!full_path) {
> -			TALLOC_FREE(ctx);
> -			return NT_STATUS_NO_MEMORY;
> -		}
> -
> -		DEBUG(5, ("%s module '%s': Trying to load from %s\n",
> -			  is_probe ? "Probing": "Loading", module_name, full_path));
> -		init = load_module(full_path, is_probe, &handle);
> -	} else {
> -		init = load_module(module_name, is_probe, &handle);
> -	}
> -
> -	if (!init) {
> -		TALLOC_FREE(ctx);
> -		return NT_STATUS_UNSUCCESSFUL;
> -	}
> -
> -	DEBUG(2, ("Module '%s' loaded\n", module_name));
> -
> -	status = init(NULL);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(0, ("Module '%s' initialization failed: %s\n",
> -			  module_name, get_friendly_nt_error_msg(status)));
> -		dlclose(handle);
> -	}
> -	TALLOC_FREE(ctx);
> -	return status;
> -}
> -
>  /* Load all modules in list and return number of
>   * modules that has been successfully loaded */
>  int smb_load_all_modules_absoute_path(const char **modules)
> @@ -330,7 +272,48 @@ NTSTATUS smb_probe_module_absolute_path(const char *module)
>  	return load_module_absolute_path(module, true);
>  }
>  
> +/**
> + * @brief Load a module.
> + *
> + * @param[in]  subsystem  The name of the subsystem the module belongs too.
> + *
> + * @param[in]  module     Check if a module exists and load it.
> + *
> + * @return  A NTSTATUS code
> + */
>  NTSTATUS smb_load_module(const char *subsystem, const char *module)
>  {
> -	return do_smb_load_module(subsystem, module, false);
> +	NTSTATUS status;
> +	char *module_path = NULL;
> +	TALLOC_CTX *tmp_ctx = talloc_stackframe();
> +
> +	if (subsystem == NULL) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +	if (module == NULL) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +
> +	if (strchr(module, '/')) {
> +		status = NT_STATUS_INVALID_PARAMETER;
> +		goto done;
> +	}
> +
> +	module_path = talloc_asprintf(tmp_ctx,
> +				      "%s/%s.%s",
> +				      modules_path(tmp_ctx, subsystem),
> +				      module,
> +				      shlib_ext());
> +	if (module_path == NULL) {
> +		status = NT_STATUS_NO_MEMORY;
> +		goto done;
> +	}
> +
> +	status = load_module_absolute_path(module_path, false);
> +
> +done:
> +	TALLOC_FREE(tmp_ctx);
> +	return status;
>  }
> -- 
> 2.13.0
> 
> 
> From 222d4ff238d6de4dfc7bac99768ea35ccdac0ddf Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 12 May 2017 14:13:42 +0200
> Subject: [PATCH 7/7] unittest: Add testsuite for smb_probe_module()
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  selftest/tests.py                           |  2 +
>  testsuite/unittests/test_lib_util_modules.c | 76 +++++++++++++++++++++++++++++
>  testsuite/unittests/wscript                 |  8 +++
>  3 files changed, 86 insertions(+)
>  create mode 100644 testsuite/unittests/test_lib_util_modules.c
> 
> diff --git a/selftest/tests.py b/selftest/tests.py
> index 9f298a6f734..b9c470c557a 100644
> --- a/selftest/tests.py
> +++ b/selftest/tests.py
> @@ -147,3 +147,5 @@ if with_cmocka:
>                    [os.path.join(bindir(), "default/testsuite/unittests/test_krb5samba")])
>      plantestsuite("samba.unittests.sambafs_srv_pipe", "none",
>                    [os.path.join(bindir(), "default/testsuite/unittests/test_sambafs_srv_pipe")])
> +    plantestsuite("samba.unittests.lib_util_modules", "none",
> +                  [os.path.join(bindir(), "default/testsuite/unittests/test_lib_util_modules")])
> diff --git a/testsuite/unittests/test_lib_util_modules.c b/testsuite/unittests/test_lib_util_modules.c
> new file mode 100644
> index 00000000000..c92dafd161e
> --- /dev/null
> +++ b/testsuite/unittests/test_lib_util_modules.c
> @@ -0,0 +1,76 @@
> +#include <stdarg.h>
> +#include <stddef.h>
> +#include <setjmp.h>
> +#include <cmocka.h>
> +
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include <sys/stat.h>
> +#include <talloc.h>
> +
> +#include "include/config.h"
> +#include "libcli/util/ntstatus.h"
> +#include "lib/util/samba_modules.h"
> +
> +static int teardown(void **state)
> +{
> +	unsetenv("UNITTEST_DUMMY_MODULE_LOADED");
> +
> +	return 0;
> +}
> +
> +static void test_samba_module_probe(void **state)
> +{
> +	NTSTATUS status;
> +
> +	status = smb_probe_module("auth", "unix");
> +	assert_true(NT_STATUS_IS_OK(status));
> +}
> +
> +static void test_samba_module_probe_dummy(void **state)
> +{
> +	const char *module_env;
> +	NTSTATUS status;
> +
> +	status = smb_probe_module("rpc", "test_dummy_module");
> +	assert_true(NT_STATUS_IS_OK(status));
> +
> +	module_env = getenv("UNITTEST_DUMMY_MODULE_LOADED");
> +	assert_non_null(module_env);
> +	assert_string_equal(module_env, "TRUE");
> +}
> +
> +static void test_samba_module_probe_slash(void **state)
> +{
> +	char dummy_module_path[4096] = {0};
> +	const char *module_env;
> +	NTSTATUS status;
> +
> +	snprintf(dummy_module_path,
> +		 sizeof(dummy_module_path),
> +		 "%s/bin/modules/rpc/test_dummy_module.so",
> +		 SRCDIR);
> +
> +	status = smb_probe_module("rpc", dummy_module_path);
> +	assert_true(NT_STATUS_IS_ERR(status));
> +
> +	module_env = getenv("UNITTEST_DUMMY_MODULE_LOADED");
> +	assert_null(module_env);
> +}
> +
> +int main(void) {
> +	const struct CMUnitTest tests[] = {
> +		cmocka_unit_test_teardown(test_samba_module_probe,
> +					  teardown),
> +		cmocka_unit_test_teardown(test_samba_module_probe_dummy,
> +					  teardown),
> +		cmocka_unit_test_teardown(test_samba_module_probe_slash,
> +					  teardown),
> +	};
> +
> +	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
> +	return cmocka_run_group_tests(tests, NULL, NULL);
> +}
> diff --git a/testsuite/unittests/wscript b/testsuite/unittests/wscript
> index bb29fd8cba2..ba6ad3cbed9 100644
> --- a/testsuite/unittests/wscript
> +++ b/testsuite/unittests/wscript
> @@ -20,6 +20,14 @@ def build(bld):
>                            ''',
>                       install=False)
>  
> +    bld.SAMBA_BINARY('test_lib_util_modules',
> +                     source='test_lib_util_modules.c',
> +                     deps='''
> +                          samba-modules
> +                          cmocka
> +                          ''',
> +                     install=False)
> +
>      bld.SAMBA_MODULE('rpc_test_dummy_module',
>                       source='rpc_test_dummy_module.c',
>                       deps='ndr',
> -- 
> 2.13.0
> 




More information about the samba-technical mailing list