[PATCH 22/23] gpo: Add gpo tests
David Mulder
dmulder at suse.com
Fri Mar 10 16:09:29 UTC 2017
Lays down a sysvol gpttmpl.inf with password policies, then runs the samba_gpoupdate command. Verifies policies are applied to the samdb.
Signed-off-by: David Mulder <dmulder at suse.com>
---
python/samba/gpclass.py | 5 +-
selftest/target/Samba4.pm | 1 +
source4/selftest/tests.py | 4 +
source4/torture/gpo/apply.c | 189 ++++++++++++++++++++++++++++++++++++++
source4/torture/gpo/gpo.c | 36 ++++++++
source4/torture/gpo/wscript_build | 14 +++
source4/torture/wscript_build | 1 +
7 files changed, 249 insertions(+), 1 deletion(-)
create mode 100644 source4/torture/gpo/apply.c
create mode 100644 source4/torture/gpo/gpo.c
create mode 100644 source4/torture/gpo/wscript_build
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index c8f8c79..81580d9 100755
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -134,7 +134,10 @@ class gp_sec_ext(gp_ext):
ret = False
inftable = self.populate_inf()
- policy = conn.loadfile(path.replace('/', '\\')).decode('utf-16')
+ try:
+ policy = conn.loadfile(path.replace('/', '\\')).decode('utf-16')
+ except ValueError:
+ policy = conn.loadfile(path.replace('/', '\\')) # Handle ascii files created by linux
current_section = None
LOG = open(attr_log, "a")
LOG.write(str(path.split('/')[2]) + '\n')
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index dacdab4..681c199 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -582,6 +582,7 @@ sub provision_raw_step1($$)
rndc command = true
dns update command = $ctx->{samba_dnsupdate}
spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate -s $ctx->{smb_conf}
+ gpo update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_gpoupdate -s $ctx->{smb_conf}
dreplsrv:periodic_startup_interval = 0
dsdb:schema update allowed = yes
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 93635d9..7231c6a 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -237,6 +237,10 @@ for env in ["ad_dc_ntvfs", "nt4_dc"]:
plantestsuite("samba.blackbox.pdbtest.s4winbind(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_pdbtest.sh"), '$SERVER', "$PREFIX", "pdbtest3", smbclient4, '$SMB_CONF_PATH', configuration + " --option='authmethods=samba4:winbind'"])
plantestsuite("samba.blackbox.pdbtest.s4winbind_wbclient(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_pdbtest.sh"), '$SERVER', "$PREFIX", "pdbtest4", smbclient4, '$SMB_CONF_PATH', configuration + " --option='authmethods=samba4:winbind_wbclient'"])
+gpo = smbtorture4_testsuites("gpo.")
+for t in gpo:
+ plansmbtorture4testsuite(t, 'ad_dc:local', ['//$SERVER/sysvol', '-U$USERNAME%$PASSWORD'])
+
transports = ["ncacn_np", "ncacn_ip_tcp"]
#Kerberos varies between functional levels, so it is important to check this on all of them
diff --git a/source4/torture/gpo/apply.c b/source4/torture/gpo/apply.c
new file mode 100644
index 0000000..a9944ab0
--- /dev/null
+++ b/source4/torture/gpo/apply.c
@@ -0,0 +1,189 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) David Mulder 2017
+
+ 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 "includes.h"
+#include "param/param.h"
+#include "param/loadparm.h"
+#include "torture/smbtorture.h"
+#include "lib/util/mkdir_p.h"
+#include "dsdb/samdb/samdb.h"
+#include "auth/session.h"
+#include "lib/ldb/include/ldb.h"
+#include "torture/gpo/proto.h"
+
+struct torture_suite *gpo_apply_suite(TALLOC_CTX *ctx)
+{
+ struct torture_suite *suite = torture_suite_create(ctx, "apply");
+
+ torture_suite_add_simple_test(suite, "gpo_param_from_gpo", torture_gpo_system_access_policies);
+
+ suite->description = talloc_strdup(suite, "Group Policy apply tests");
+
+ return suite;
+}
+
+static char* convert_param(struct torture_context *tctx, struct parm_struct *parm, void *parm_ptr)
+{
+ switch (parm->type) {
+ case P_CHAR:
+ return talloc_asprintf(tctx, "%c", *(char *)parm_ptr);
+ case P_STRING:
+ case P_USTRING:
+ return talloc_strdup(tctx, *(char **)parm_ptr);;
+ case P_CMDLIST:
+ case P_LIST:
+ {
+ int j, len = 0;
+ const char **strlist = *(const char ***)parm_ptr;
+ char *result = NULL;
+
+ if (strlist == NULL)
+ return NULL;
+
+ for (j = 0; strlist[j]; j++) {
+ int len_chunk = strlen(strlist[j])+1;
+ result = talloc_realloc(tctx, result, char, len+len_chunk);
+ memcpy(result+len, strlist[j], len_chunk);
+ len += len_chunk;
+ result[len-1] = ' ';
+ }
+ result[len-1] = '\0'; // Terminate the string
+ return result;
+ }
+ case P_BOOL:
+ case P_BOOLREV:
+ case P_INTEGER:
+ case P_OCTAL:
+ case P_BYTES:
+ case P_ENUM:
+ default:
+ return NULL; // TODO: implement the other types if needed
+ }
+ return NULL;
+}
+
+static const char* lp_get_param(struct torture_context *tctx, const char *service_name, const char *param_name)
+{
+ struct parm_struct *parm = NULL;
+ struct loadparm_service *service;
+ void *parm_ptr = NULL;
+
+ if (service_name) {
+ service = lpcfg_service(tctx->lp_ctx, service_name);
+ torture_assert(tctx, service, talloc_asprintf(tctx, "Failed to find %s", service_name));
+ parm = lpcfg_parm_struct(tctx->lp_ctx, param_name);
+ torture_assert(tctx, parm, talloc_asprintf(tctx, "Failed to find %s %s", service_name, param_name));
+ parm_ptr = lpcfg_parm_ptr(tctx->lp_ctx, service, parm);
+ torture_assert(tctx, parm_ptr, talloc_asprintf(tctx, "Failed to find %s %s", service_name, param_name));
+ } else {
+ parm = lpcfg_parm_struct(tctx->lp_ctx, param_name);
+ torture_assert(tctx, parm, talloc_asprintf(tctx, "Failed to find %s", param_name));
+ parm_ptr = lpcfg_parm_ptr(tctx->lp_ctx, NULL, parm);
+ torture_assert(tctx, parm, talloc_asprintf(tctx, "Failed to find %s", param_name));
+ }
+ return convert_param(tctx, parm, parm_ptr);
+}
+
+#define GPODIR "addom.samba.example.com/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Microsoft/Windows NT/SecEdit"
+#define GPOFILE "GptTmpl.inf"
+#define GPTTMPL "[System Access]\n\
+MinimumPasswordAge = 2\n\
+MaximumPasswordAge = 37\n\
+MinimumPasswordLength = 11\n\
+PasswordComplexity = 2\n\
+"
+#define GPTINI "addom.samba.example.com/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI"
+
+bool torture_gpo_system_access_policies(struct torture_context *tctx)
+{
+ int ret, vers = 0;
+ const char *gpo_update_cmd = NULL, *sysvol_path = NULL, *gpo_dir = NULL, *gpo_file = NULL, *gpt_file = NULL;
+ struct ldb_context *samdb = NULL;
+ struct ldb_result *result;
+ const char *attrs[] = {
+ "minPwdAge",
+ "maxPwdAge",
+ "minPwdLength",
+ "pwdProperties",
+ NULL
+ };
+ const struct ldb_val *val;
+ FILE *fp = NULL;
+
+ sysvol_path = lp_get_param(tctx, "sysvol", "path");
+ torture_assert(tctx, sysvol_path, "Failed to fetch the sysvol path");
+ gpo_update_cmd = lp_get_param(tctx, NULL, "gpo update command");
+ torture_assert(tctx, gpo_update_cmd, "Failed to fetch the gpo update command");
+
+ /* Write out the sysvol */
+ gpo_dir = talloc_asprintf(tctx, "%s/%s", sysvol_path, GPODIR);
+ mkdir_p(gpo_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+ gpo_file = talloc_asprintf(tctx, "%s/%s", gpo_dir, GPOFILE);
+ if ( (fp = fopen(gpo_file, "w")) ) {
+ fputs(GPTTMPL, fp);
+ fclose(fp);
+ }
+
+ /* Update the version in the GPT.INI */
+ gpt_file = talloc_asprintf(tctx, "%s/%s", sysvol_path, GPTINI);
+ if ( (fp = fopen(gpt_file, "r")) ) {
+ char line[256];
+ while (fgets(line, 256, fp)) {
+ if (strncasecmp(line, "Version=", 8) == 0) {
+ vers = atoi(line+8);
+ break;
+ }
+ }
+ fclose(fp);
+ }
+ if ( (fp = fopen(gpt_file, "w")) ) {
+ char *data = talloc_asprintf(tctx, "[General]\nVersion=%d\n", ++vers);
+ fputs(data, fp);
+ fclose(fp);
+ }
+
+ /* Run the gpo update command */
+ system(gpo_update_cmd);
+
+ /* Open and read the samba db and verify the settings applied */
+ samdb = samdb_connect(tctx, tctx->ev, tctx->lp_ctx, system_session(tctx->lp_ctx), 0);
+ torture_assert(tctx, samdb, "Failed to connect to the samdb");
+
+ ret = ldb_search(samdb, tctx, &result, ldb_get_default_basedn(samdb), LDB_SCOPE_BASE, attrs, NULL);
+ torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1, "Searching the samdb failed");
+
+ /* minPwdAge */
+ val = ldb_msg_find_ldb_val(result->msgs[0], attrs[0]);
+ torture_assert(tctx, strcmp((char*)val->data, "-1728000000000") == 0, "The minPwdAge was not applied");
+
+ /* maxPwdAge */
+ val = ldb_msg_find_ldb_val(result->msgs[0], attrs[1]);
+ torture_assert(tctx, strcmp((char*)val->data, "-31968000000000") == 0, "The maxPwdAge was not applied");
+
+ /* minPwdLength */
+ val = ldb_msg_find_ldb_val(result->msgs[0], attrs[2]);
+ torture_assert(tctx, atoi((char*)val->data) == 11, "The minPwdLength was not applied");
+
+ /* pwdProperties */
+ val = ldb_msg_find_ldb_val(result->msgs[0], attrs[3]);
+ torture_assert(tctx, atoi((char*)val->data) == 2, "The pwdProperties were not applied");
+
+ return true;
+}
+
diff --git a/source4/torture/gpo/gpo.c b/source4/torture/gpo/gpo.c
new file mode 100644
index 0000000..ded4404
--- /dev/null
+++ b/source4/torture/gpo/gpo.c
@@ -0,0 +1,36 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) David Mulder 2017
+
+ 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 "includes.h"
+#include "torture/smbtorture.h"
+#include "torture/gpo/proto.h"
+
+NTSTATUS torture_gpo_init(void)
+{
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "gpo");
+
+ torture_suite_add_suite(suite, gpo_apply_suite(suite));
+
+ suite->description = talloc_strdup(suite, "Group Policy tests");
+
+ torture_register_suite(suite);
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/torture/gpo/wscript_build b/source4/torture/gpo/wscript_build
new file mode 100644
index 0000000..c92bbf7
--- /dev/null
+++ b/source4/torture/gpo/wscript_build
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+bld.SAMBA_MODULE('TORTURE_GPO',
+ source='''
+ gpo.c
+ apply.c
+ ''',
+ subsystem='smbtorture',
+ deps='torture mkdir_p',
+ internal_module=True,
+ autoproto='proto.h',
+ init_function='torture_gpo_init'
+ )
+
diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build
index c065eaa..b235baa 100644
--- a/source4/torture/wscript_build
+++ b/source4/torture/wscript_build
@@ -31,6 +31,7 @@ bld.RECURSE('smb2')
bld.RECURSE('winbind')
bld.RECURSE('libnetapi')
bld.RECURSE('libsmbclient')
+bld.RECURSE('gpo')
ntvfs_specific = dict(source='', deps='')
--
2.10.2
More information about the samba-technical
mailing list