[SCM] Samba Shared Repository - branch master updated
David Mulder
dmulder at samba.org
Tue Jun 23 17:54:02 UTC 2020
The branch, master has been updated
via ab50d348d93 gpo: Test samba-tool gpo admxload
via 2c1ebd07b18 samba-tool: add command for installing gpo samba admx
via e32f4602ed3 Add python binding for DATADIR build path
via 97a8f999461 gpo: Test gpo scripts apply
via a9d1ccc5699 gpo: Run Group Policy Scripts
via cd52a280913 Create Registry.pol group policy extension parser
from 1a6b714605a nsswitch: silence openpam error messages about unexpected responses
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ab50d348d9357dcf18863161992cdf49038c954a
Author: David Mulder <dmulder at suse.com>
Date: Thu Jun 18 12:06:28 2020 -0600
gpo: Test samba-tool gpo admxload
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
Autobuild-User(master): David Mulder <dmulder at samba.org>
Autobuild-Date(master): Tue Jun 23 17:53:22 UTC 2020 on sn-devel-184
commit 2c1ebd07b18cdd64df444b8c356e9044c87008c3
Author: David Mulder <dmulder at suse.com>
Date: Tue Oct 16 03:36:09 2018 -0600
samba-tool: add command for installing gpo samba admx
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
commit e32f4602ed3827530fd63bf31693fb12ede013b9
Author: David Mulder <dmulder at suse.com>
Date: Tue Oct 16 03:23:34 2018 -0600
Add python binding for DATADIR build path
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
commit 97a8f999461f8ca9c24824734131700745310605
Author: David Mulder <dmulder at suse.com>
Date: Tue Jun 16 15:29:40 2020 -0600
gpo: Test gpo scripts apply
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
commit a9d1ccc5699a4e8c66012f769cec8fba6ce84a59
Author: David Mulder <dmulder at suse.com>
Date: Mon Apr 27 16:02:55 2020 -0600
gpo: Run Group Policy Scripts
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
commit cd52a280913a6536b4923da7214977c762f664ed
Author: David Mulder <dmulder at suse.com>
Date: Thu Aug 9 09:47:38 2018 -0600
Create Registry.pol group policy extension parser
Create a parent class for parsing Registry.pol
files by group policy extensions.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Alexander Bokovoy <ab at samba.org>
-----------------------------------------------------------------------
Summary of changes:
libgpo/admx/en-US/samba.adml | 19 ++++++++++
libgpo/admx/samba.admx | 23 ++++++++++++
libgpo/admx/wscript_build | 3 ++
libgpo/wscript_build | 2 +
python/samba/gp_scripts_ext.py | 53 ++++++++++++++++++++++++++
python/samba/gpclass.py | 14 ++++++-
python/samba/netcmd/gpo.py | 72 ++++++++++++++++++++++++++++++++++++
python/samba/tests/gpo.py | 48 +++++++++++++++++++++++-
python/samba/tests/samba_tool/gpo.py | 25 +++++++++++++
source4/param/pyparam.c | 7 ++++
source4/scripting/bin/samba-gpupdate | 2 +
11 files changed, 265 insertions(+), 3 deletions(-)
create mode 100755 libgpo/admx/en-US/samba.adml
create mode 100755 libgpo/admx/samba.admx
create mode 100644 libgpo/admx/wscript_build
create mode 100644 python/samba/gp_scripts_ext.py
Changeset truncated at 500 lines:
diff --git a/libgpo/admx/en-US/samba.adml b/libgpo/admx/en-US/samba.adml
new file mode 100755
index 00000000000..b5fc5098638
--- /dev/null
+++ b/libgpo/admx/en-US/samba.adml
@@ -0,0 +1,19 @@
+<policyDefinitionResources revision="1.0" schemaVersion="1.0">
+ <displayName>
+ </displayName>
+ <description>
+ </description>
+ <resources>
+ <stringTable>
+ <string id="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9">Samba</string>
+ <string id="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6">Unix Settings</string>
+ <string id="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061">Daily Scripts</string>
+ <string id="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061_Help">This policy setting allows you to execute commands, either local or on remote storage, daily.</string>
+ </stringTable>
+ <presentationTable>
+ <presentation id="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061">
+ <listBox refId="LST_2E9A4684_3C0E_415B_8FD6_D4AF68BC8AC6">Script and arguments</listBox>
+ </presentation>
+ </presentationTable>
+ </resources>
+</policyDefinitionResources>
diff --git a/libgpo/admx/samba.admx b/libgpo/admx/samba.admx
new file mode 100755
index 00000000000..f2921ff1885
--- /dev/null
+++ b/libgpo/admx/samba.admx
@@ -0,0 +1,23 @@
+<policyDefinitions revision="1.0" schemaVersion="1.0">
+ <policyNamespaces>
+ <target prefix="fullarmor" namespace="FullArmor.Policies.98BB16AF_01EE_4D17_870D_A3311A44D6C2" />
+ <using prefix="windows" namespace="Microsoft.Policies.Windows" />
+ </policyNamespaces>
+ <supersededAdm fileName="" />
+ <resources minRequiredRevision="1.0" />
+ <categories>
+ <category name="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9" displayName="$(string.CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9)" />
+ <category name="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6" displayName="$(string.CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6)">
+ <parentCategory ref="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9" />
+ </category>
+ </categories>
+ <policies>
+ <policy name="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061" class="Machine" displayName="$(string.POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061)" explainText="$(string.POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061_Help)" presentation="$(presentation.POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061)" key="Software\Policies\Samba\Unix Settings">
+ <parentCategory ref="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6" />
+ <supportedOn ref="windows:SUPPORTED_WindowsVista" />
+ <elements>
+ <list id="LST_2E9A4684_3C0E_415B_8FD6_D4AF68BC8AC6" key="Software\Policies\Samba\Unix Settings\Daily Scripts" valueName="Daily Scripts" />
+ </elements>
+ </policy>
+ </policies>
+</policyDefinitions>
diff --git a/libgpo/admx/wscript_build b/libgpo/admx/wscript_build
new file mode 100644
index 00000000000..cb1cadbf782
--- /dev/null
+++ b/libgpo/admx/wscript_build
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+
+bld.INSTALL_FILES('${DATADIR}/samba/admx', ['samba.admx', 'en-US/samba.adml'])
diff --git a/libgpo/wscript_build b/libgpo/wscript_build
index f36ccf2c701..e6e54fe359a 100644
--- a/libgpo/wscript_build
+++ b/libgpo/wscript_build
@@ -19,3 +19,5 @@ pyrpc_util = bld.pyembed_libname('pyrpc_util')
bld.SAMBA3_PYTHON('python_samba_libgpo', 'pygpo.c',
deps='%s gpext talloc ads TOKEN_UTIL auth %s' % (pyparam_util, pyrpc_util),
realname='samba/gpo.so')
+
+bld.RECURSE('admx')
diff --git a/python/samba/gp_scripts_ext.py b/python/samba/gp_scripts_ext.py
new file mode 100644
index 00000000000..f83f367a5d7
--- /dev/null
+++ b/python/samba/gp_scripts_ext.py
@@ -0,0 +1,53 @@
+# gp_scripts_ext samba gpo policy
+# Copyright (C) David Mulder <dmulder at suse.com> 2020
+#
+# 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/>.
+
+import os, re
+from samba.gpclass import gp_pol_ext
+from base64 import b64encode
+from tempfile import NamedTemporaryFile
+
+class gp_scripts_ext(gp_pol_ext):
+ def __str__(self):
+ return 'Unix Settings/Daily Scripts'
+
+ def process_group_policy(self, deleted_gpo_list, changed_gpo_list, cdir='/etc/cron.daily'):
+ for gpo in deleted_gpo_list:
+ self.gp_db.set_guid(gpo[0])
+ if str(self) in gpo[1]:
+ for attribute, script in gpo[1][str(self)].items():
+ os.unlink(script)
+ self.gp_db.delete(str(self), attribute)
+ self.gp_db.commit()
+
+ for gpo in changed_gpo_list:
+ if gpo.file_sys_path:
+ section_name = 'Software\\Policies\\Samba\\Unix Settings\\Daily Scripts'
+ self.gp_db.set_guid(gpo.name)
+ pol_file = 'MACHINE/Registry.pol'
+ path = os.path.join(gpo.file_sys_path, pol_file)
+ pol_conf = self.parse(path)
+ if not pol_conf:
+ continue
+ for e in pol_conf.entries:
+ if e.keyname == section_name and e.data.strip():
+ attribute = b64encode(e.data.encode()).decode()
+ old_val = self.gp_db.retrieve(str(self), attribute)
+ if not old_val:
+ with NamedTemporaryFile(mode="w+", delete=False, dir=cdir) as f:
+ f.write('#!/bin/sh\n%s' % e.data)
+ os.chmod(f.name, 0o700)
+ self.gp_db.store(str(self), attribute, f.name)
+ self.gp_db.commit()
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 0040f235e6e..cc574e12a42 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -35,6 +35,9 @@ import samba.gpo as gpo
from samba.param import LoadParm
from uuid import UUID
from tempfile import NamedTemporaryFile
+from samba.dcerpc import preg
+from samba.dcerpc import misc
+from samba.ndr import ndr_pack, ndr_unpack
try:
from enum import Enum
@@ -307,7 +310,7 @@ class gp_ext(object):
local_path = self.lp.cache_path('gpo_cache')
data_file = os.path.join(local_path, check_safe_path(afile).upper())
if os.path.exists(data_file):
- return self.read(open(data_file, 'r').read())
+ return self.read(data_file)
return None
@abstractmethod
@@ -347,7 +350,8 @@ class gp_ext_setter(object):
class gp_inf_ext(gp_ext):
- def read(self, policy):
+ def read(self, data_file):
+ policy = open(data_file, 'r').read()
inf_conf = ConfigParser()
inf_conf.optionxform = str
try:
@@ -357,6 +361,12 @@ class gp_inf_ext(gp_ext):
return inf_conf
+class gp_pol_ext(gp_ext):
+ def read(self, data_file):
+ raw = open(data_file, 'rb').read()
+ return ndr_unpack(preg.file, raw)
+
+
''' Fetch the hostname of a writable DC '''
diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 4b08c62d773..1e2c2918ebe 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -61,6 +61,7 @@ from samba.gp_parse.gp_ini import (
from samba.gp_parse.gp_csv import GPAuditCsvParser
from samba.gp_parse.gp_inf import GptTmplInfParser
from samba.gp_parse.gp_aas import GPAasParser
+from samba import param
def attr_default(msg, attrname, default):
@@ -1593,6 +1594,76 @@ class cmd_aclcheck(GPOCommand):
if (fs_sd.as_sddl(domain_sid) != expected_fs_sddl):
raise CommandError("Invalid GPO ACL %s on path (%s), should be %s" % (fs_sd.as_sddl(domain_sid), sharepath, expected_fs_sddl))
+class cmd_admxload(Command):
+ """Loads samba admx files to sysvol"""
+
+ synopsis = "%prog [options]"
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+ metavar="URL", dest="H"),
+ Option("--admx-dir", help="Directory where admx templates are stored",
+ type=str, default=os.path.join(param.data_dir(), 'samba/admx'))
+ ]
+
+ def run(self, H=None, sambaopts=None, credopts=None, versionopts=None,
+ admx_dir=None):
+ self.lp = sambaopts.get_loadparm()
+ self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
+
+ # We need to know writable DC to setup SMB connection
+ if H and H.startswith('ldap://'):
+ dc_hostname = H[7:]
+ self.url = H
+ else:
+ dc_hostname = netcmd_finddc(self.lp, self.creds)
+ self.url = dc_url(self.lp, self.creds, dc=dc_hostname)
+
+ # SMB connect to DC
+ conn = smb_connection(dc_hostname,
+ 'sysvol',
+ lp=self.lp,
+ creds=self.creds,
+ sign=True)
+
+ smb_dir = '\\'.join([self.lp.get('realm').lower(),
+ 'Policies', 'PolicyDefinitions'])
+ try:
+ conn.mkdir(smb_dir)
+ except NTSTATUSError as e:
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ elif e.args[0] != 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
+ raise
+
+ for dirname, dirs, files in os.walk(admx_dir):
+ for fname in files:
+ path_in_admx = dirname.replace(admx_dir, '')
+ full_path = os.path.join(dirname, fname)
+ sub_dir = '\\'.join([smb_dir, path_in_admx]).replace('/', '\\')
+ smb_path = '\\'.join([sub_dir, fname])
+ try:
+ conn.mkdir(sub_dir)
+ except NTSTATUSError as e:
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ elif e.args[0] != 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
+ raise
+ with open(full_path, 'rb') as f:
+ try:
+ conn.savefile(smb_path, f.read())
+ except NTSTATUSError as e:
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
class cmd_gpo(SuperCommand):
"""Group Policy Object (GPO) management."""
@@ -1613,3 +1684,4 @@ class cmd_gpo(SuperCommand):
subcommands["aclcheck"] = cmd_aclcheck()
subcommands["backup"] = cmd_backup()
subcommands["restore"] = cmd_restore()
+ subcommands["admxload"] = cmd_admxload()
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index dce00bd8f86..02ff6d97121 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -23,11 +23,14 @@ from samba.param import LoadParm
from samba.gpclass import check_refresh_gpo_list, check_safe_path, \
check_guid, parse_gpext_conf, atomic_write_conf, get_deleted_gpos_list
from subprocess import Popen, PIPE
-from tempfile import NamedTemporaryFile
+from tempfile import NamedTemporaryFile, TemporaryDirectory
from samba.gp_sec_ext import gp_sec_ext
+from samba.gp_scripts_ext import gp_scripts_ext
import logging
from samba.credentials import Credentials
from samba.compat import get_bytes
+from samba.dcerpc import preg
+from samba.ndr import ndr_pack
realm = os.environ.get('REALM')
policies = realm + '/POLICIES'
@@ -316,3 +319,46 @@ class GPOTests(tests.TestCase):
for guid in guids:
gpttmpl = gpofile % (local_path, guid)
unstage_file(gpttmpl)
+
+ def test_gp_daily_scripts(self):
+ local_path = self.lp.cache_path('gpo_cache')
+ guid = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
+ reg_pol = os.path.join(local_path, policies, guid,
+ 'MACHINE/REGISTRY.POL')
+ logger = logging.getLogger('gpo_tests')
+ cache_dir = self.lp.get('cache directory')
+ store = GPOStorage(os.path.join(cache_dir, 'gpo.tdb'))
+
+ machine_creds = Credentials()
+ machine_creds.guess(self.lp)
+ machine_creds.set_machine_account()
+
+ # Initialize the group policy extension
+ ext = gp_scripts_ext(logger, self.lp, machine_creds, store)
+
+ ads = gpo.ADS_STRUCT(self.server, self.lp, machine_creds)
+ if ads.connect():
+ gpos = ads.get_gpo_list(machine_creds.get_username())
+
+ # Stage the Registry.pol file with test data
+ stage = preg.file()
+ e = preg.entry()
+ e.keyname = b'Software\\Policies\\Samba\\Unix Settings\\Daily Scripts'
+ e.valuename = b'Software\\Policies\\Samba\\Unix Settings'
+ e.type = 1
+ e.data = b'echo hello world'
+ stage.num_entries = 1
+ stage.entries = [e]
+ ret = stage_file(reg_pol, ndr_pack(stage))
+ self.assertTrue(ret, 'Could not create the target %s' % reg_pol)
+
+ # Process all gpos, with temp output directory
+ with TemporaryDirectory() as dname:
+ ext.process_group_policy([], gpos, dname)
+ scripts = os.listdir(dname)
+ self.assertEquals(len(scripts), 1, 'The daily script was not created')
+ out, _ = Popen([os.path.join(dname, scripts[0])], stdout=PIPE).communicate()
+ self.assertIn(b'hello world', out, 'Daily script execution failed')
+
+ # Unstage the Registry.pol file
+ unstage_file(reg_pol)
diff --git a/python/samba/tests/samba_tool/gpo.py b/python/samba/tests/samba_tool/gpo.py
index 5cf68f808d4..3e6d4e8fd27 100644
--- a/python/samba/tests/samba_tool/gpo.py
+++ b/python/samba/tests/samba_tool/gpo.py
@@ -24,7 +24,9 @@ import samba
from samba.tests.samba_tool.base import SambaToolCmdTest
import shutil
from samba.netcmd.gpo import get_gpo_dn, get_gpo_info
+from samba.param import LoadParm
+source_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../.."))
def has_difference(path1, path2, binary=True, xml=True, sortlines=False):
"""Use this function to determine if the GPO backup differs from another.
@@ -517,6 +519,29 @@ class GpoCmdTestCase(SambaToolCmdTest):
shutil.rmtree(os.path.join(self.tempdir, "policy"))
shutil.rmtree(os.path.join(self.tempdir, 'temp'))
+ def test_admx_load(self):
+ lp = LoadParm()
+ lp.load(os.environ['SERVERCONFFILE'])
+ local_path = lp.get('path', 'sysvol')
+ admx_path = os.path.join(local_path, os.environ['REALM'].lower(),
+ 'Policies', 'PolicyDefinitions')
+ (result, out, err) = self.runsubcmd("gpo", "admxload",
+ "-H", "ldap://%s" %
+ os.environ["SERVER"],
+ "--admx-dir=%s" %
+ os.path.join(source_path,
+ 'libgpo/admx'),
+ "-U%s%%%s" %
+ (os.environ["USERNAME"],
+ os.environ["PASSWORD"]))
+ self.assertCmdSuccess(result, out, err,
+ 'Filling PolicyDefinitions failed')
+ self.assertTrue(os.path.exists(admx_path),
+ 'PolicyDefinitions was not created')
+ self.assertTrue(os.path.exists(os.path.join(admx_path, 'samba.admx')),
+ 'Filling PolicyDefinitions failed')
+ shutil.rmtree(admx_path)
+
def setUp(self):
"""set up a temporary GPO to work with"""
super(GpoCmdTestCase, self).setUp()
diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c
index 5e5e1d370cd..4023fac4dd6 100644
--- a/source4/param/pyparam.c
+++ b/source4/param/pyparam.c
@@ -614,6 +614,11 @@ PyTypeObject PyLoadparmService = {
.tp_flags = Py_TPFLAGS_DEFAULT,
};
+static PyObject *py_data_dir(PyObject *self)
+{
+ return PyUnicode_FromString(dyn_DATADIR);
+}
+
static PyObject *py_default_path(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return PyUnicode_FromString(lp_default_path());
@@ -640,6 +645,8 @@ static PyObject *py_sbin_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
}
static PyMethodDef pyparam_methods[] = {
+ { "data_dir", (PyCFunction)py_data_dir, METH_NOARGS,
+ "Returns the compiled in location of data directory." },
{ "default_path", (PyCFunction)py_default_path, METH_NOARGS,
"Returns the default smb.conf path." },
{ "setup_dir", (PyCFunction)py_setup_dir, METH_NOARGS,
diff --git a/source4/scripting/bin/samba-gpupdate b/source4/scripting/bin/samba-gpupdate
index 528019c7478..68dfad1ed87 100755
--- a/source4/scripting/bin/samba-gpupdate
+++ b/source4/scripting/bin/samba-gpupdate
@@ -32,6 +32,7 @@ from samba import getopt as options
from samba.gpclass import apply_gp, unapply_gp, GPOStorage
from samba.gp_sec_ext import gp_sec_ext
from samba.gp_ext_loader import get_gp_client_side_extensions
+from samba.gp_scripts_ext import gp_scripts_ext
import logging
if __name__ == "__main__":
@@ -80,6 +81,7 @@ if __name__ == "__main__":
gp_extensions = []
if opts.target == 'Computer':
gp_extensions.append(gp_sec_ext(logger, lp, creds, store))
+ gp_extensions.append(gp_scripts_ext(logger, lp, creds, store))
for ext in machine_exts:
gp_extensions.append(ext(logger, lp, creds, store))
elif opts.target == 'User':
--
Samba Shared Repository
More information about the samba-cvs
mailing list