[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Wed Feb 24 22:02:01 UTC 2021
The branch, master has been updated
via 85d24068265 samba-tool: Add a gpo command for removing VGP Startup Scripts Group Policy
via 91655e6d713 samba-tool: Test gpo manage script startup remove command
via e5efe17246d samba-tool: Add a gpo command for adding VGP Startup Scripts Group Policy
via f6a0bd8b913 samba-tool: Test gpo manage script startup add command
via d22196117cd samba-tool: Add a gpo command for listing VGP Startup Scripts Group Policy
via 329b6c397b9 samba-tool: Test gpo manage script startup list command
via 15cec2ac4d7 gpo: Apply Group Policy Startup Scripts from VGP
via b13b2d8c3ec gpo: Test Group Policy VGP Startup Script Policy
from e49a0b444ab ldb: remove some 'if PY3's in tests
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 85d240682655cdcdcac22606178a257ac28d7783
Author: David Mulder <dmulder at suse.com>
Date: Tue Feb 16 14:12:02 2021 -0700
samba-tool: Add a gpo command for removing VGP Startup Scripts Group Policy
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Wed Feb 24 22:01:08 UTC 2021 on sn-devel-184
commit 91655e6d713cbd6b555ae43a8468f38ba238387e
Author: David Mulder <dmulder at suse.com>
Date: Fri Feb 12 14:49:16 2021 -0700
samba-tool: Test gpo manage script startup remove command
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit e5efe17246d1ef6b1aab84901a98660845a50bb1
Author: David Mulder <dmulder at suse.com>
Date: Fri Feb 12 14:13:51 2021 -0700
samba-tool: Add a gpo command for adding VGP Startup Scripts Group Policy
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit f6a0bd8b91302f4c7a9b1392d92bdaafcd1bcebd
Author: David Mulder <dmulder at suse.com>
Date: Fri Feb 12 08:04:30 2021 -0700
samba-tool: Test gpo manage script startup add command
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit d22196117cd3f87ca1e3790013909d6e72fdb942
Author: David Mulder <dmulder at suse.com>
Date: Tue Feb 9 06:16:32 2021 -0700
samba-tool: Add a gpo command for listing VGP Startup Scripts Group Policy
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 329b6c397b988839d73e18968dbdec855a471877
Author: David Mulder <dmulder at suse.com>
Date: Mon Feb 8 13:08:02 2021 -0700
samba-tool: Test gpo manage script startup list command
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 15cec2ac4d7af0fa82c21d0109607aa63c86c15a
Author: David Mulder <dmulder at suse.com>
Date: Tue Feb 2 12:33:11 2021 -0700
gpo: Apply Group Policy Startup Scripts from VGP
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit b13b2d8c3ec2a64ee56ce03bc9130b628a4c0fcb
Author: David Mulder <dmulder at suse.com>
Date: Fri Jan 29 13:34:50 2021 -0700
gpo: Test Group Policy VGP Startup Script Policy
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
docs-xml/manpages/samba-tool.8.xml | 15 ++
python/samba/netcmd/gpo.py | 279 ++++++++++++++++++++++++++++++++
python/samba/tests/gpo.py | 122 ++++++++++++++
python/samba/tests/samba_tool/gpo.py | 103 ++++++++++++
python/samba/vgp_startup_scripts_ext.py | 124 ++++++++++++++
5 files changed, 643 insertions(+)
create mode 100644 python/samba/vgp_startup_scripts_ext.py
Changeset truncated at 500 lines:
diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index e7ac7dd625a..b808c9b2616 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -939,6 +939,21 @@
<para>Removes a Samba Sudoers Group Policy from the sysvol.</para>
</refsect3>
+<refsect3>
+ <title>gpo manage scripts startup list</title>
+ <para>List VGP Startup Script Group Policy from the sysvol</para>
+</refsect3>
+
+<refsect3>
+ <title>gpo manage scripts startup add</title>
+ <para>Adds VGP Startup Script Group Policy to the sysvol</para>
+</refsect3>
+
+<refsect3>
+ <title>gpo manage scripts startup remove</title>
+ <para>Removes VGP Startup Script Group Policy from the sysvol</para>
+</refsect3>
+
<refsect2>
<title>group</title>
<para>Manage groups.</para>
diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 24ecf664ecf..2928ebcf7ce 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -69,6 +69,7 @@ from samba.common import get_bytes, get_string
from configparser import ConfigParser
from io import StringIO, BytesIO
from samba.vgp_files_ext import calc_mode, stat_from_mode
+import hashlib
def gpo_flags_string(value):
@@ -3039,6 +3040,283 @@ class cmd_openssh(SuperCommand):
subcommands["list"] = cmd_list_openssh()
subcommands["set"] = cmd_set_openssh()
+class cmd_list_startup(Command):
+ """List VGP Startup Script Group Policy from the sysvol
+
+This command lists the startup script policies currently set on the sysvol.
+
+Example:
+samba-tool gpo manage scripts startup list {31B2F340-016D-11D2-945F-00C04FB984F9}
+ """
+
+ synopsis = "%prog <gpo> [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"),
+ ]
+
+ takes_args = ["gpo"]
+
+ def run(self, gpo, H=None, sambaopts=None, credopts=None, versionopts=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)
+
+ realm = self.lp.get('realm')
+ vgp_xml = '\\'.join([realm.lower(), 'Policies', gpo,
+ 'MACHINE\\VGP\\VTLA\\Unix',
+ 'Scripts\\Startup\\manifest.xml'])
+ try:
+ xml_data = ET.fromstring(conn.loadfile(vgp_xml))
+ except NTSTATUSError as e:
+ # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+ # STATUS_OBJECT_PATH_NOT_FOUND
+ if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+ return # The file doesn't exist, so there is nothing to list
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ raise
+
+ policy = xml_data.find('policysetting')
+ data = policy.find('data')
+ for listelement in data.findall('listelement'):
+ script = listelement.find('script')
+ script_path = '\\'.join(['\\', realm.lower(), 'Policies', gpo,
+ 'MACHINE\\VGP\\VTLA\\Unix\\Scripts',
+ 'Startup', script.text])
+ parameters = listelement.find('parameters')
+ run_as = listelement.find('run_as')
+ if run_as is not None:
+ run_as = run_as.text
+ else:
+ run_as = 'root'
+ self.outf.write('@reboot %s %s %s' % (run_as, script_path,
+ parameters.text))
+
+class cmd_add_startup(Command):
+ """Adds VGP Startup Script Group Policy to the sysvol
+
+This command adds a startup script policy to the sysvol.
+
+Example:
+samba-tool gpo manage scripts startup add {31B2F340-016D-11D2-945F-00C04FB984F9} test_script.sh '-n'
+ """
+
+ synopsis = "%prog <gpo> <script> [args] [run_as] [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("--run-once", dest="run_once", default=False, action='store_true',
+ help="Whether to run the script only once"),
+ ]
+
+ takes_args = ["gpo", "script", "args?", "run_as?"]
+
+ def run(self, gpo, script, args=None, run_as=None, run_once=None,
+ H=None, sambaopts=None, credopts=None, versionopts=None):
+ self.lp = sambaopts.get_loadparm()
+ self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
+
+ if not os.path.exists(script):
+ raise CommandError("Script '%s' does not exist" % script)
+
+ # 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)
+
+ realm = self.lp.get('realm')
+ vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+ 'MACHINE\\VGP\\VTLA\\Unix\\Scripts\\Startup'])
+ vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
+ try:
+ xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+ policy = xml_data.getroot().find('policysetting')
+ data = policy.find('data')
+ except NTSTATUSError as e:
+ # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+ # STATUS_OBJECT_PATH_NOT_FOUND
+ if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+ # The file doesn't exist, so create the xml structure
+ xml_data = ET.ElementTree(ET.Element('vgppolicy'))
+ policysetting = ET.SubElement(xml_data.getroot(),
+ 'policysetting')
+ pv = ET.SubElement(policysetting, 'version')
+ pv.text = '1'
+ name = ET.SubElement(policysetting, 'name')
+ name.text = 'Unix Scripts'
+ description = ET.SubElement(policysetting, 'description')
+ description.text = \
+ 'Represents Unix scripts to run on Group Policy clients'
+ data = ET.SubElement(policysetting, 'data')
+ elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ else:
+ raise
+
+ script_data = open(script, 'rb').read()
+ listelement = ET.SubElement(data, 'listelement')
+ script_elm = ET.SubElement(listelement, 'script')
+ script_elm.text = os.path.basename(script)
+ hash = ET.SubElement(listelement, 'hash')
+ hash.text = hashlib.md5(script_data).hexdigest().upper()
+ if args is not None:
+ parameters = ET.SubElement(listelement, 'parameters')
+ parameters.text = args.strip('"').strip("'")
+ if run_as is not None:
+ run_as_elm = ET.SubElement(listelement, 'run_as')
+ run_as_elm.text = run_as
+ if run_once is not None:
+ ET.SubElement(listelement, 'run_once')
+
+ out = BytesIO()
+ xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+ out.seek(0)
+ sysvol_script = '\\'.join([vgp_dir, os.path.basename(script)])
+ try:
+ create_directory_hier(conn, vgp_dir)
+ conn.savefile(vgp_xml, out.read())
+ conn.savefile(sysvol_script, script_data)
+ except NTSTATUSError as e:
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ raise
+
+class cmd_remove_startup(Command):
+ """Removes VGP Startup Script Group Policy from the sysvol
+
+This command removes a startup script policy from the sysvol.
+
+Example:
+samba-tool gpo manage scripts startup remove {31B2F340-016D-11D2-945F-00C04FB984F9} test_script.sh
+ """
+
+ synopsis = "%prog <gpo> <script> [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"),
+ ]
+
+ takes_args = ["gpo", "script"]
+
+ def run(self, gpo, script, H=None, sambaopts=None, credopts=None,
+ versionopts=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)
+
+ realm = self.lp.get('realm')
+ vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+ 'MACHINE\\VGP\\VTLA\\Unix\\Scripts\\Startup'])
+ vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
+ try:
+ xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+ policy = xml_data.getroot().find('policysetting')
+ data = policy.find('data')
+ except NTSTATUSError as e:
+ # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+ # STATUS_OBJECT_PATH_NOT_FOUND
+ if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+ raise CommandError("Cannot remove script '%s' "
+ "because it does not exist" % script)
+ elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ else:
+ raise
+
+ for listelement in data.findall('listelement'):
+ script_elm = listelement.find('script')
+ if script_elm.text == os.path.basename(script.replace('\\', '/')):
+ data.remove(listelement)
+ break
+ else:
+ raise CommandError("Cannot remove script '%s' "
+ "because it does not exist" % script)
+
+ out = BytesIO()
+ xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+ out.seek(0)
+ try:
+ create_directory_hier(conn, vgp_dir)
+ conn.savefile(vgp_xml, out.read())
+ except NTSTATUSError as e:
+ if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+ raise CommandError("The authenticated user does "
+ "not have sufficient privileges")
+ raise
+
+class cmd_startup(SuperCommand):
+ """Manage Startup Scripts Group Policy Objects"""
+ subcommands = {}
+ subcommands["list"] = cmd_list_startup()
+ subcommands["add"] = cmd_add_startup()
+ subcommands["remove"] = cmd_remove_startup()
+
+class cmd_scripts(SuperCommand):
+ """Manage Scripts Group Policy Objects"""
+ subcommands = {}
+ subcommands["startup"] = cmd_startup()
+
class cmd_manage(SuperCommand):
"""Manage Group Policy Objects"""
subcommands = {}
@@ -3048,6 +3326,7 @@ class cmd_manage(SuperCommand):
subcommands["symlink"] = cmd_symlink()
subcommands["files"] = cmd_files()
subcommands["openssh"] = cmd_openssh()
+ subcommands["scripts"] = cmd_scripts()
class cmd_gpo(SuperCommand):
"""Group Policy Object (GPO) management."""
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index e3b500868ec..2ff3e5e593e 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -33,6 +33,7 @@ from samba.gpclass import gp_inf_ext
from samba.gp_smb_conf_ext import gp_smb_conf_ext
from samba.vgp_files_ext import vgp_files_ext
from samba.vgp_openssh_ext import vgp_openssh_ext
+from samba.vgp_startup_scripts_ext import vgp_startup_scripts_ext
import logging
from samba.credentials import Credentials
from samba.gp_msgs_ext import gp_msgs_ext
@@ -42,6 +43,7 @@ from samba.ndr import ndr_pack
import codecs
from shutil import copyfile
import xml.etree.ElementTree as etree
+import hashlib
realm = os.environ.get('REALM')
policies = realm + '/POLICIES'
@@ -1106,3 +1108,123 @@ class GPOTests(tests.TestCase):
# Unstage the Registry.pol file
unstage_file(manifest)
+
+ def test_vgp_startup_scripts(self):
+ local_path = self.lp.cache_path('gpo_cache')
+ guid = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
+ manifest = os.path.join(local_path, policies, guid, 'MACHINE',
+ 'VGP/VTLA/UNIX/SCRIPTS/STARTUP/MANIFEST.XML')
+ test_script = os.path.join(os.path.dirname(manifest), 'TEST.SH')
+ test_data = '#!/bin/sh\necho $@ hello world'
+ ret = stage_file(test_script, test_data)
+ self.assertTrue(ret, 'Could not create the target %s' % test_script)
+ 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 = vgp_startup_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 manifest.xml file with test data
+ stage = etree.Element('vgppolicy')
+ policysetting = etree.SubElement(stage, 'policysetting')
+ version = etree.SubElement(policysetting, 'version')
+ version.text = '1'
+ data = etree.SubElement(policysetting, 'data')
+ listelement = etree.SubElement(data, 'listelement')
+ script = etree.SubElement(listelement, 'script')
+ script.text = os.path.basename(test_script).lower()
+ parameters = etree.SubElement(listelement, 'parameters')
+ parameters.text = '-n'
+ hash = etree.SubElement(listelement, 'hash')
+ hash.text = \
+ hashlib.md5(open(test_script, 'rb').read()).hexdigest().upper()
+ run_as = etree.SubElement(listelement, 'run_as')
+ run_as.text = 'root'
+ ret = stage_file(manifest, etree.tostring(stage))
+ self.assertTrue(ret, 'Could not create the target %s' % manifest)
+
+ # Process all gpos, with temp output directory
+ with TemporaryDirectory() as dname:
+ ext.process_group_policy([], gpos, dname)
+ files = os.listdir(dname)
+ self.assertEquals(len(files), 1,
+ 'The target script was not created')
+ entry = '@reboot %s %s %s' % (run_as.text, test_script,
+ parameters.text)
+ self.assertIn(entry,
+ open(os.path.join(dname, files[0]), 'r').read(),
+ 'The test entry was not found')
+
+ # Remove policy
+ gp_db = store.get_gplog(machine_creds.get_username())
+ del_gpos = get_deleted_gpos_list(gp_db, [])
+ ext.process_group_policy(del_gpos, [])
+ files = os.listdir(dname)
+ self.assertEquals(len(files), 0,
+ 'The target script was not removed')
+
+ # Test rsop
+ g = [g for g in gpos if g.name == guid][0]
+ ret = ext.rsop(g)
+ self.assertIn(entry, list(ret.values())[0][0],
+ 'The target entry was not listed by rsop')
+
+ # Unstage the manifest.xml and script files
+ unstage_file(manifest)
+ unstage_file(test_script)
+
+ # Stage the manifest.xml file for run once scripts
+ etree.SubElement(listelement, 'run_once')
+ run_as.text = pwd.getpwuid(os.getuid()).pw_name
+ ret = stage_file(manifest, etree.tostring(stage))
+ self.assertTrue(ret, 'Could not create the target %s' % manifest)
+
+ # Process all gpos, with temp output directory
+ # A run once script will be executed immediately,
+ # instead of creating a cron job
+ with TemporaryDirectory() as dname:
+ test_file = '%s/TESTING.txt' % dname
+ test_data = '#!/bin/sh\ntouch %s' % test_file
+ ret = stage_file(test_script, test_data)
+ self.assertTrue(ret, 'Could not create the target %s' % test_script)
+
+ ext.process_group_policy([], gpos, dname)
+ files = os.listdir(dname)
+ self.assertEquals(len(files), 1,
+ 'The test file was not created')
+ self.assertEquals(files[0], os.path.basename(test_file),
+ 'The test file was not created')
+
+ # Unlink the test file and ensure that processing
+ # policy again does not recreate it.
+ os.unlink(test_file)
+ ext.process_group_policy([], gpos, dname)
+ files = os.listdir(dname)
+ self.assertEquals(len(files), 0,
+ 'The test file should not have been created')
+
+ # Remove policy
+ gp_db = store.get_gplog(machine_creds.get_username())
+ del_gpos = get_deleted_gpos_list(gp_db, [])
+ ext.process_group_policy(del_gpos, [])
+
+ # Test rsop
+ entry = 'Run once as: %s `%s %s`' % (run_as.text, test_script,
+ parameters.text)
+ g = [g for g in gpos if g.name == guid][0]
+ ret = ext.rsop(g)
+ self.assertIn(entry, list(ret.values())[0][0],
+ 'The target entry was not listed by rsop')
+
+ # Unstage the manifest.xml and script files
+ unstage_file(manifest)
+ unstage_file(test_script)
diff --git a/python/samba/tests/samba_tool/gpo.py b/python/samba/tests/samba_tool/gpo.py
index c57c6786d79..13734f3b163 100644
--- a/python/samba/tests/samba_tool/gpo.py
+++ b/python/samba/tests/samba_tool/gpo.py
@@ -32,6 +32,8 @@ from samba.common import get_string
from configparser import ConfigParser
from io import StringIO
import xml.etree.ElementTree as etree
+from tempfile import NamedTemporaryFile
+from time import sleep
source_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../.."))
@@ -1120,6 +1122,107 @@ class GpoCmdTestCase(SambaToolCmdTest):
os.environ["PASSWORD"]))
self.assertNotIn(openssh, out, 'The test entry was still found!')
+ def test_startup_script_add(self):
+ lp = LoadParm()
+ fname = None
+ with NamedTemporaryFile() as f:
+ fname = os.path.basename(f.name)
+ f.write(b'#!/bin/sh\necho $@ hello world')
+ f.flush()
+ (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+ "scripts", "startup",
--
Samba Shared Repository
More information about the samba-cvs
mailing list