[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Thu Jul 12 23:06:11 UTC 2018
The branch, master has been updated
via f3358f0 gpo: Specify samba module when importing from gpclass
via b05b619 gpo: Don't duplicate guids in the apply log
via de8b30a gpo: Add user policy extensions
via 126b789 gpo: Dynamically load gp_exts
via fb6c250 gpo: Tests for gp_ext register/unregister
via 4436b67 gpo: add list_gp_extensions for listing registered gp extensions
via b4f09af gpo: add unregister_gp_extension for unregistering gp extensions
via 387dc35 gpo: add register_gp_extension for registering gp extensions
via 46629f5 param: Add python binding for lpcfg_state_path
via 2412c70 gpo: Offline policy application via cache
via 57faf35 gpo: Read GPO versions locally, not from sysvol
via 4c7348e python: Allow forced signing via smb.SMB()
via 2494e33 gpo: Disable python3 testing
via ce9ac51 gpo: Fix asserts in gpo testing
from 3eee52b pthreadpool: allocate glue->tctx on glue as memory context.
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit f3358f048d7583bb63cb0f09efdd68fbbe49d32e
Author: David Mulder <dmulder at suse.com>
Date: Wed May 16 09:03:32 2018 -0600
gpo: Specify samba module when importing from gpclass
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Fri Jul 13 01:05:22 CEST 2018 on sn-devel-144
commit b05b6198a3fa480e7026145bfd0608e41fd3f326
Author: David Mulder <dmulder at suse.com>
Date: Tue May 15 08:37:08 2018 -0600
gpo: Don't duplicate guids in the apply log
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit de8b30a726bcef3f8c5e37b1f27c97020f4fb051
Author: David Mulder <dmulder at suse.com>
Date: Fri May 4 13:25:25 2018 -0600
gpo: Add user policy extensions
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 126b789268a3a21ee4d5769290b69d45860bb608
Author: David Mulder <dmulder at suse.com>
Date: Wed May 9 09:24:37 2018 -0600
gpo: Dynamically load gp_exts
This loads Group Policy Client Side Extensions
similar to the way that they are loaded on a
Windows client. Extensions are installed to a
configuration file in the samba cache path where
they receive a unique GUID matched with the path
to the python gp_ext file. Classes which inherit
from the gp_ext class (as defined in gpclass.py)
will be dynamically loaded.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit fb6c250bdeebfd00d1605dd76ac54d1013ea4ba2
Author: David Mulder <dmulder at suse.com>
Date: Wed Jul 11 17:09:26 2018 +1200
gpo: Tests for gp_ext register/unregister
Adds testing for the gp_ext register and
unregister functions, as well as testing
the list function.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 4436b6703c081d0479af407d4c8ea28f5a323f88
Author: David Mulder <dmulder at suse.com>
Date: Wed Jun 13 14:46:30 2018 -0600
gpo: add list_gp_extensions for listing registered gp extensions
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b4f09af27abc8da260a1c1b2ea074f9f6e5ce56b
Author: David Mulder <dmulder at suse.com>
Date: Wed Jun 13 14:46:05 2018 -0600
gpo: add unregister_gp_extension for unregistering gp extensions
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 387dc358d3a2bd33bca7d7bcbcb2668eae6c0bd5
Author: David Mulder <dmulder at suse.com>
Date: Wed Jun 13 14:45:09 2018 -0600
gpo: add register_gp_extension for registering gp extensions
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 46629f53217f269c3bea044b054e62381149443c
Author: David Mulder <dmulder at suse.com>
Date: Fri Jun 29 14:08:34 2018 -0600
param: Add python binding for lpcfg_state_path
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 2412c70481fe22fb9e266e6ef1a1cd86fb39a1e5
Author: David Mulder <dmulder at suse.com>
Date: Wed May 16 10:37:09 2018 -0600
gpo: Offline policy application via cache
Read policy files from the cache, rather than
the sysvol. This enables offline policy apply.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 57faf35cf836e675e088b3a6e6e455c1309fd4ea
Author: David Mulder <dmulder at suse.com>
Date: Mon Jan 8 07:17:29 2018 -0700
gpo: Read GPO versions locally, not from sysvol
Non-kdc clients cannot read directly from the
sysvol, so we need to store the GPT.INI file
locally to read each gpo version.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 4c7348e44d10ca519dd1322fd40b12c69e17a8e6
Author: David Mulder <dmulder at suse.com>
Date: Thu Jun 28 09:01:59 2018 -0600
python: Allow forced signing via smb.SMB()
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 2494e33822276cc6a8836121b3012f9e94b9fddf
Author: David Mulder <dmulder at suse.com>
Date: Wed Jun 13 14:42:43 2018 -0600
gpo: Disable python3 testing
The gpo module doesn't work in python3 yet,
causing this test to fail on python3.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13525
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ce9ac51ee223271a789fa7aee215acd383fa33a3
Author: David Mulder <dmulder at suse.com>
Date: Thu Jul 5 09:02:57 2018 -0600
gpo: Fix asserts in gpo testing
These tests weren't using python's unit testing
asserts.
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
python/samba/gp_ext_loader.py | 56 ++++++++++++
python/samba/gp_sec_ext.py | 2 +-
python/samba/gpclass.py | 170 ++++++++++++++++++++++++++++-------
python/samba/tests/gpo.py | 98 +++++++++++++++++---
source4/libcli/pysmb.c | 10 ++-
source4/param/pyparam.c | 27 ++++++
source4/scripting/bin/samba-gpupdate | 8 +-
source4/selftest/tests.py | 2 +-
8 files changed, 322 insertions(+), 51 deletions(-)
create mode 100644 python/samba/gp_ext_loader.py
Changeset truncated at 500 lines:
diff --git a/python/samba/gp_ext_loader.py b/python/samba/gp_ext_loader.py
new file mode 100644
index 0000000..61cc29b
--- /dev/null
+++ b/python/samba/gp_ext_loader.py
@@ -0,0 +1,56 @@
+# Group Policy Client Side Extension Loader
+# Copyright (C) David Mulder <dmulder at suse.com> 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/>.
+
+import os
+from samba.gpclass import list_gp_extensions
+from samba.gpclass import gp_ext
+
+try:
+ import importlib.util
+ def import_file(name, location):
+ spec = importlib.util.spec_from_file_location(name, location)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+except ImportError:
+ import imp
+ def import_file(name, location):
+ return imp.load_source(name, location)
+
+def get_gp_ext_from_module(name, mod):
+ if mod:
+ for k, v in vars(mod).items():
+ if k == name and issubclass(v, gp_ext):
+ return v
+ return None
+
+def get_gp_client_side_extensions(logger, smb_conf):
+ user_exts = []
+ machine_exts = []
+ gp_exts = list_gp_extensions(smb_conf)
+ for gp_ext in gp_exts.values():
+ module = import_file(gp_ext['ProcessGroupPolicy'], gp_ext['DllName'])
+ ext = get_gp_ext_from_module(gp_ext['ProcessGroupPolicy'], module)
+ if ext and gp_ext['MachinePolicy']:
+ machine_exts.append(ext)
+ logger.info('Loaded machine extension from %s: %s'
+ % (gp_ext['DllName'], ext.__name__))
+ if ext and gp_ext['UserPolicy']:
+ user_exts.append(ext)
+ logger.info('Loaded user extension from %s: %s'
+ % (gp_ext['DllName'], ext.__name__))
+ return (machine_exts, user_exts)
+
diff --git a/python/samba/gp_sec_ext.py b/python/samba/gp_sec_ext.py
index bbd385f..11fd1f5 100644
--- a/python/samba/gp_sec_ext.py
+++ b/python/samba/gp_sec_ext.py
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os.path
-from gpclass import gp_ext_setter, gp_inf_ext
+from samba.gpclass import gp_ext_setter, gp_inf_ext
class inf_to_kdc_tdb(gp_ext_setter):
def mins_to_hours(self):
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 0966611..70ab261 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -17,6 +17,7 @@
import sys
import os
+import errno
import tdb
sys.path.insert(0, "bin/python")
from samba import NTSTATUSError
@@ -29,6 +30,9 @@ from samba.net import Net
from samba.dcerpc import nbt
from samba import smb
import samba.gpo as gpo
+from samba.param import LoadParm
+from uuid import UUID
+from tempfile import NamedTemporaryFile
try:
from enum import Enum
@@ -135,9 +139,11 @@ class gp_log:
apply_log = user_obj.find('applylog')
if apply_log is None:
apply_log = etree.SubElement(user_obj, 'applylog')
- item = etree.SubElement(apply_log, 'guid')
- item.attrib['count'] = '%d' % (len(apply_log)-1)
- item.attrib['value'] = guid
+ prev = apply_log.find('guid[@value="%s"]' % guid)
+ if prev is None:
+ item = etree.SubElement(apply_log, 'guid')
+ item.attrib['count'] = '%d' % (len(apply_log)-1)
+ item.attrib['value'] = guid
def apply_log_pop(self):
''' Pop a GPO guid from the applylog
@@ -305,32 +311,16 @@ class gp_ext(object):
def read(self, policy):
pass
- def parse(self, afile, ldb, conn, gp_db, lp):
+ def parse(self, afile, ldb, gp_db, lp):
self.ldb = ldb
self.gp_db = gp_db
self.lp = lp
- # Fixing the bug where only some Linux Boxes capitalize MACHINE
- try:
- blist = afile.split('/')
- idx = afile.lower().split('/').index('machine')
- for case in [
- blist[idx].upper(),
- blist[idx].capitalize(),
- blist[idx].lower()
- ]:
- bfile = '/'.join(blist[:idx]) + '/' + case + '/' + \
- '/'.join(blist[idx+1:])
- try:
- return self.read(conn.loadfile(bfile.replace('/', '\\')))
- except NTSTATUSError:
- continue
- except ValueError:
- try:
- return self.read(conn.loadfile(afile.replace('/', '\\')))
- except Exception as e:
- self.logger.error(str(e))
- return None
+ 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 None
@abstractmethod
def __str__(self):
@@ -423,23 +413,66 @@ def get_gpo_list(dc_hostname, creds, lp):
gpos = ads.get_gpo_list(creds.get_username())
return gpos
+
+def cache_gpo_dir(conn, cache, sub_dir):
+ loc_sub_dir = sub_dir.upper()
+ local_dir = os.path.join(cache, loc_sub_dir)
+ try:
+ os.makedirs(local_dir, mode=0o755)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+ for fdata in conn.list(sub_dir):
+ if fdata['attrib'] & smb.FILE_ATTRIBUTE_DIRECTORY:
+ cache_gpo_dir(conn, cache, os.path.join(sub_dir, fdata['name']))
+ else:
+ local_name = fdata['name'].upper()
+ f = NamedTemporaryFile(delete=False, dir=local_dir)
+ fname = os.path.join(sub_dir, fdata['name']).replace('/', '\\')
+ f.write(conn.loadfile(fname))
+ f.close()
+ os.rename(f.name, os.path.join(local_dir, local_name))
+
+
+def check_safe_path(path):
+ dirs = re.split('/|\\\\', path)
+ if 'sysvol' in path:
+ dirs = dirs[dirs.index('sysvol')+1:]
+ if not '..' in dirs:
+ return os.path.join(*dirs)
+ raise OSError(path)
+
+def check_refresh_gpo_list(dc_hostname, lp, creds, gpos):
+ conn = smb.SMB(dc_hostname, 'sysvol', lp=lp, creds=creds, sign=True)
+ cache_path = lp.cache_path('gpo_cache')
+ for gpo in gpos:
+ if not gpo.file_sys_path:
+ continue
+ cache_gpo_dir(conn, cache_path, check_safe_path(gpo.file_sys_path))
+
+def gpo_version(lp, path):
+ # gpo.gpo_get_sysvol_gpt_version() reads the GPT.INI from a local file,
+ # read from the gpo client cache.
+ gpt_path = lp.cache_path(os.path.join('gpo_cache', path))
+ return int(gpo.gpo_get_sysvol_gpt_version(gpt_path)[1])
+
def apply_gp(lp, creds, test_ldb, logger, store, gp_extensions):
gp_db = store.get_gplog(creds.get_username())
dc_hostname = get_dc_hostname(creds, lp)
+ gpos = get_gpo_list(dc_hostname, creds, lp)
try:
- conn = smb.SMB(dc_hostname, 'sysvol', lp=lp, creds=creds)
+ check_refresh_gpo_list(dc_hostname, lp, creds, gpos)
except:
- logger.error('Error connecting to \'%s\' using SMB' % dc_hostname)
- raise
- gpos = get_gpo_list(dc_hostname, creds, lp)
+ logger.error('Failed downloading gpt cache from \'%s\' using SMB' \
+ % dc_hostname)
+ return
for gpo_obj in gpos:
guid = gpo_obj.name
if guid == 'Local Policy':
continue
- path = os.path.join(lp.get('realm').lower(), 'Policies', guid)
- local_path = os.path.join(lp.get("path", "sysvol"), path)
- version = int(gpo.gpo_get_sysvol_gpt_version(local_path)[1])
+ path = os.path.join(lp.get('realm'), 'Policies', guid).upper()
+ version = gpo_version(lp, path)
if version != store.get_int(guid):
logger.info('GPO %s has changed' % guid)
gp_db.state(GPOSTATE.APPLY)
@@ -449,7 +482,7 @@ def apply_gp(lp, creds, test_ldb, logger, store, gp_extensions):
store.start()
for ext in gp_extensions:
try:
- ext.parse(ext.list(path), test_ldb, conn, gp_db, lp)
+ ext.parse(ext.list(path), test_ldb, gp_db, lp)
except Exception as e:
logger.error('Failed to parse gpo %s for extension %s' % \
(guid, str(ext)))
@@ -479,3 +512,74 @@ def unapply_gp(lp, creds, test_ldb, logger, store, gp_extensions):
gp_db.delete(str(attr_obj), attr[0])
gp_db.commit()
+def parse_gpext_conf(smb_conf):
+ lp = LoadParm()
+ if smb_conf is not None:
+ lp.load(smb_conf)
+ else:
+ lp.load_default()
+ ext_conf = lp.state_path('gpext.conf')
+ parser = ConfigParser()
+ parser.read(ext_conf)
+ return lp, parser
+
+def atomic_write_conf(lp, parser):
+ ext_conf = lp.state_path('gpext.conf')
+ with NamedTemporaryFile(delete=False, dir=os.path.dirname(ext_conf)) as f:
+ parser.write(f)
+ os.rename(f.name, ext_conf)
+
+def check_guid(guid):
+ # Check for valid guid with curly braces
+ if guid[0] != '{' or guid[-1] != '}' or len(guid) != 38:
+ return False
+ try:
+ UUID(guid, version=4)
+ except ValueError:
+ return False
+ return True
+
+def register_gp_extension(guid, name, path,
+ smb_conf=None, machine=True, user=True):
+ # Check that the module exists
+ if not os.path.exists(path):
+ return False
+ if not check_guid(guid):
+ return False
+
+ lp, parser = parse_gpext_conf(smb_conf)
+ if not guid in parser.sections():
+ parser.add_section(guid)
+ parser.set(guid, 'DllName', path)
+ parser.set(guid, 'ProcessGroupPolicy', name)
+ parser.set(guid, 'NoMachinePolicy', 0 if machine else 1)
+ parser.set(guid, 'NoUserPolicy', 0 if user else 1)
+
+ atomic_write_conf(lp, parser)
+
+ return True
+
+def list_gp_extensions(smb_conf=None):
+ _, parser = parse_gpext_conf(smb_conf)
+ results = {}
+ for guid in parser.sections():
+ results[guid] = {}
+ results[guid]['DllName'] = parser.get(guid, 'DllName')
+ results[guid]['ProcessGroupPolicy'] = \
+ parser.get(guid, 'ProcessGroupPolicy')
+ results[guid]['MachinePolicy'] = \
+ not int(parser.get(guid, 'NoMachinePolicy'))
+ results[guid]['UserPolicy'] = not int(parser.get(guid, 'NoUserPolicy'))
+ return results
+
+def unregister_gp_extension(guid, smb_conf=None):
+ if not check_guid(guid):
+ return False
+
+ lp, parser = parse_gpext_conf(smb_conf)
+ if guid in parser.sections():
+ parser.remove_section(guid)
+
+ atomic_write_conf(lp, parser)
+
+ return True
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index 796a5cb..27f52af 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -16,7 +16,11 @@
import os
from samba import gpo, tests
+from samba.gpclass import register_gp_extension, list_gp_extensions, \
+ unregister_gp_extension
from samba.param import LoadParm
+from samba.gpclass import check_refresh_gpo_list, check_safe_path, \
+ check_guid, parse_gpext_conf, atomic_write_conf
poldir = r'\\addom.samba.example.com\sysvol\addom.samba.example.com\Policies'
dspath = 'CN=Policies,CN=System,DC=addom,DC=samba,DC=example,DC=com'
@@ -43,12 +47,12 @@ class GPOTests(tests.TestCase):
file_sys_paths = [None, '%s\\%s' % (poldir, guid)]
ds_paths = [None, 'CN=%s,%s' % (guid, dspath)]
for i in range(0, len(gpos)):
- assert gpos[i].name == names[i], \
- 'The gpo name did not match expected name %s' % gpos[i].name
- assert gpos[i].file_sys_path == file_sys_paths[i], \
- 'file_sys_path did not match expected %s' % gpos[i].file_sys_path
- assert gpos[i].ds_path == ds_paths[i], \
- 'ds_path did not match expected %s' % gpos[i].ds_path
+ self.assertEquals(gpos[i].name, names[i],
+ 'The gpo name did not match expected name %s' % gpos[i].name)
+ self.assertEquals(gpos[i].file_sys_path, file_sys_paths[i],
+ 'file_sys_path did not match expected %s' % gpos[i].file_sys_path)
+ self.assertEquals(gpos[i].ds_path, ds_paths[i],
+ 'ds_path did not match expected %s' % gpos[i].ds_path)
def test_gpo_ads_does_not_segfault(self):
@@ -59,19 +63,89 @@ class GPOTests(tests.TestCase):
def test_gpt_version(self):
global gpt_data
- local_path = self.lp.get("path", "sysvol")
- policies = 'addom.samba.example.com/Policies'
+ local_path = self.lp.cache_path('gpo_cache')
+ policies = 'ADDOM.SAMBA.EXAMPLE.COM/POLICIES'
guid = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
gpo_path = os.path.join(local_path, policies, guid)
old_vers = gpo.gpo_get_sysvol_gpt_version(gpo_path)[1]
with open(os.path.join(gpo_path, 'GPT.INI'), 'w') as gpt:
gpt.write(gpt_data % 42)
- assert gpo.gpo_get_sysvol_gpt_version(gpo_path)[1] == 42, \
- 'gpo_get_sysvol_gpt_version() did not return the expected version'
+ self.assertEquals(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], 42,
+ 'gpo_get_sysvol_gpt_version() did not return the expected version')
with open(os.path.join(gpo_path, 'GPT.INI'), 'w') as gpt:
gpt.write(gpt_data % old_vers)
- assert gpo.gpo_get_sysvol_gpt_version(gpo_path)[1] == old_vers, \
- 'gpo_get_sysvol_gpt_version() did not return the expected version'
+ self.assertEquals(gpo.gpo_get_sysvol_gpt_version(gpo_path)[1], old_vers,
+ 'gpo_get_sysvol_gpt_version() did not return the expected version')
+
+ def test_check_refresh_gpo_list(self):
+ cache = self.lp.cache_path('gpo_cache')
+ ads = gpo.ADS_STRUCT(self.server, self.lp, self.creds)
+ if ads.connect():
+ gpos = ads.get_gpo_list(self.creds.get_username())
+ check_refresh_gpo_list(self.server, self.lp, self.creds, gpos)
+
+ self.assertTrue(os.path.exists(cache),
+ 'GPO cache %s was not created' % cache)
+
+ guid = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
+ gpt_ini = os.path.join(cache, 'ADDOM.SAMBA.EXAMPLE.COM/POLICIES',
+ guid, 'GPT.INI')
+ self.assertTrue(os.path.exists(gpt_ini),
+ 'GPT.INI was not cached for %s' % guid)
+
+ def test_check_refresh_gpo_list_malicious_paths(self):
+ # the path cannot contain ..
+ path = '/usr/local/samba/var/locks/sysvol/../../../../../../root/'
+ self.assertRaises(OSError, check_safe_path, path)
+
+ self.assertEqual(check_safe_path('/etc/passwd'), 'etc/passwd')
+ self.assertEqual(check_safe_path('\\\\etc/\\passwd'), 'etc/passwd')
+
+ # there should be no backslashes used to delineate paths
+ before = 'sysvol/addom.samba.example.com\\Policies/' \
+ '{31B2F340-016D-11D2-945F-00C04FB984F9}\\GPT.INI'
+ after = 'addom.samba.example.com/Policies/' \
+ '{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI'
+ result = check_safe_path(before)
+ self.assertEquals(result, after, 'check_safe_path() didn\'t' \
+ ' correctly convert \\ to /')
+
+ def test_gpt_ext_register(self):
+ this_path = os.path.dirname(os.path.realpath(__file__))
+ samba_path = os.path.realpath(os.path.join(this_path, '../../../'))
+ ext_path = os.path.join(samba_path, 'python/samba/gp_sec_ext.py')
+ ext_guid = '{827D319E-6EAC-11D2-A4EA-00C04F79F83A}'
+ ret = register_gp_extension(ext_guid, 'gp_sec_ext', ext_path,
+ smb_conf=self.lp.configfile,
+ machine=True, user=False)
+ self.assertTrue(ret, 'Failed to register a gp ext')
+ gp_exts = list_gp_extensions(self.lp.configfile)
+ self.assertTrue(ext_guid in gp_exts.keys(),
+ 'Failed to list gp exts')
+ self.assertEquals(gp_exts[ext_guid]['DllName'], ext_path,
+ 'Failed to list gp exts')
+
+ unregister_gp_extension(ext_guid)
+ gp_exts = list_gp_extensions(self.lp.configfile)
+ self.assertTrue(ext_guid not in gp_exts.keys(),
+ 'Failed to unregister gp exts')
+
+ self.assertTrue(check_guid(ext_guid), 'Failed to parse valid guid')
+ self.assertFalse(check_guid('AAAAAABBBBBBBCCC'), 'Parsed invalid guid')
+
+ lp, parser = parse_gpext_conf(self.lp.configfile)
+ self.assertTrue(lp and parser, 'parse_gpext_conf() invalid return')
+ parser.add_section('test_section')
+ parser.set('test_section', 'test_var', ext_guid)
+ atomic_write_conf(lp, parser)
+
+ lp, parser = parse_gpext_conf(self.lp.configfile)
+ self.assertTrue('test_section' in parser.sections(),
+ 'test_section not found in gpext.conf')
+ self.assertEquals(parser.get('test_section', 'test_var'), ext_guid,
+ 'Failed to find test variable in gpext.conf')
+ parser.remove_section('test_section')
+ atomic_write_conf(lp, parser)
diff --git a/source4/libcli/pysmb.c b/source4/libcli/pysmb.c
index a53e30b..45ff9a0 100644
--- a/source4/libcli/pysmb.c
+++ b/source4/libcli/pysmb.c
@@ -601,7 +601,7 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
PyObject *py_creds = Py_None;
PyObject *py_lp = Py_None;
const char *kwnames[] = { "hostname", "service", "creds", "lp",
- "ntlmv2_auth", "use_spnego", NULL };
+ "ntlmv2_auth", "use_spnego", "sign", NULL };
const char *hostname = NULL;
const char *service = NULL;
PyObject *smb;
@@ -612,11 +612,12 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
struct smbcli_session_options session_options;
uint8_t ntlmv2_auth = 0xFF;
uint8_t use_spnego = 0xFF;
+ PyObject *sign = Py_False;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zz|OObb",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zz|OObbO",
discard_const_p(char *, kwnames),
&hostname, &service, &py_creds, &py_lp,
- &ntlmv2_auth, &use_spnego)) {
+ &ntlmv2_auth, &use_spnego, &sign)) {
return NULL;
}
@@ -658,6 +659,9 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
if (use_spnego != 0xFF) {
options.use_spnego = use_spnego;
}
+ if (PyObject_IsTrue(sign)) {
+ options.signing = SMB_SIGNING_REQUIRED;
+ }
status = do_smb_connect(spdata, spdata, hostname, service,
&options,
diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c
index 11257c3..7f69d7b 100644
--- a/source4/param/pyparam.c
+++ b/source4/param/pyparam.c
@@ -381,6 +381,30 @@ static PyObject *py_cache_path(PyObject *self, PyObject *args)
return ret;
}
+static PyObject *py_state_path(PyObject *self, PyObject *args)
+{
+ struct loadparm_context *lp_ctx =
+ PyLoadparmContext_AsLoadparmContext(self);
+ char *name = NULL;
+ char *path = NULL;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &name)) {
+ return NULL;
+ }
+
+ path = lpcfg_state_path(NULL, lp_ctx, name);
+ if (!path) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list