[PATCH] Harden Samba module functions
Andreas Schneider
asn at samba.org
Tue May 30 14:08:32 UTC 2017
Hi,
the attached patch hardens the samba module functions and adds tests.
Please review.
Andreas
--
Andreas Schneider GPG-ID: CC014E3D
Samba Team asn at samba.org
www.samba.org
-------------- next part --------------
>From 910dec858e3e65fe3d85010bdcbc004f71e29abb 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 dff503dc565f8648370bda4f6be98fd99f7c3645 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>
---
lib/util/modules.c | 10 +++++
selftest/tests.py | 2 +
testsuite/unittests/rpc_test_dummy_module.c | 14 +++++++
testsuite/unittests/test_sambafs_srv_pipe.c | 59 +++++++++++++++++++++++++++++
testsuite/unittests/wscript | 17 +++++++++
5 files changed, 102 insertions(+)
create mode 100644 testsuite/unittests/rpc_test_dummy_module.c
create mode 100644 testsuite/unittests/test_sambafs_srv_pipe.c
diff --git a/lib/util/modules.c b/lib/util/modules.c
index c3c05f21f33..3d6779b4298 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -91,9 +91,19 @@ static init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path)
}
while((entry = readdir(dir))) {
+ int cmp;
+
if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name))
continue;
+#ifdef DEVELOPER
+ /* Do not load test modules */
+ cmp = strncmp(entry->d_name, "test_dummy", 10);
+ if (cmp == 0) {
+ continue;
+ }
+#endif /* DEVELOPER */
+
filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name);
ret[success] = load_module(filename, true, NULL);
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..6d170d41f83
--- /dev/null
+++ b/testsuite/unittests/rpc_test_dummy_module.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+int samba_init_module(void);
+int samba_init_module(void)
+{
+ printf("dummy executed!\n");
+ 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..27ca1cfc876
--- /dev/null
+++ b/testsuite/unittests/test_sambafs_srv_pipe.c
@@ -0,0 +1,59 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.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_samr(void **state)
+{
+ rpc_samr_shutdown();
+
+ 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};
+
+ 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);
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_is_known_pipename,
+ setup_samr,
+ teardown_samr),
+ cmocka_unit_test(test_is_known_pipename_slash),
+ };
+
+ 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..9fa9850b906 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)
+
+ if bld.env.DEVELOPER_MODE:
+ 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',
+ subsystem='rpc',
+ allow_undefined_symbols=True,
+ init_function='',
+ internal_module=False)
--
2.13.0
>From 3f66a30626a70bd51cfb19aebf506be5d95439b4 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 3d6779b4298..b3849d521f0 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -157,6 +157,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). */
@@ -222,8 +252,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 0eb51f3a6a2c02405f6cea955b40f747e7cd50b1 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 b3849d521f0..71cc43be44a 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -247,7 +247,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 1711bbd451f4ddbe1590805353eed1873a2b16f0 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 71cc43be44a..6c907c93ea2 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -271,9 +271,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 8d0c711617047ca0372d0aa543aaeafee31ecdc4 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 6c907c93ea2..3afdf13a877 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -187,64 +187,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)
@@ -340,7 +282,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 37be8eb159ca0591ee49f007a1a98d3ab6e9dfe2 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 | 45 +++++++++++++++++++++++++++++
testsuite/unittests/wscript | 8 +++++
3 files changed, 55 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..d910eceed61
--- /dev/null
+++ b/testsuite/unittests/test_lib_util_modules.c
@@ -0,0 +1,45 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <talloc.h>
+
+#include "include/config.h"
+#include "libcli/util/ntstatus.h"
+#include "lib/util/samba_modules.h"
+
+static void test_samba_module_probe(void **state)
+{
+ NTSTATUS status;
+
+ status = smb_probe_module("auth", "skel");
+ assert_true(NT_STATUS_IS_OK(status));
+}
+
+static void test_samba_module_probe_slash(void **state)
+{
+ char dummy_module_path[4096] = {0};
+ 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));
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_samba_module_probe),
+ cmocka_unit_test(test_samba_module_probe_slash),
+ };
+
+ 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 9fa9850b906..d0007994370 100644
--- a/testsuite/unittests/wscript
+++ b/testsuite/unittests/wscript
@@ -21,6 +21,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',
subsystem='rpc',
--
2.13.0
More information about the samba-technical
mailing list