gpo: Run Group Policy Scripts
authorDavid Mulder <dmulder@suse.com>
Mon, 27 Apr 2020 22:02:55 +0000 (16:02 -0600)
committerDavid Mulder <dmulder@samba.org>
Tue, 23 Jun 2020 16:32:30 +0000 (16:32 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
libgpo/admx/en-US/samba.adml [new file with mode: 0755]
libgpo/admx/samba.admx [new file with mode: 0755]
libgpo/admx/wscript_build [new file with mode: 0644]
libgpo/wscript_build
python/samba/gp_scripts_ext.py [new file with mode: 0644]
source4/scripting/bin/samba-gpupdate

diff --git a/libgpo/admx/en-US/samba.adml b/libgpo/admx/en-US/samba.adml
new file mode 100755 (executable)
index 0000000..b5fc509
--- /dev/null
@@ -0,0 +1,19 @@
+<policyDefinitionResources revision="1.0" schemaVersion="1.0">\r
+  <displayName>\r
+  </displayName>\r
+  <description>\r
+  </description>\r
+  <resources>\r
+    <stringTable>\r
+      <string id="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9">Samba</string>\r
+      <string id="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6">Unix Settings</string>\r
+      <string id="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061">Daily Scripts</string>\r
+      <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>\r
+    </stringTable>\r
+    <presentationTable>\r
+      <presentation id="POL_9320E11F_AC80_4A7D_A5C8_1C0F3F727061">\r
+        <listBox refId="LST_2E9A4684_3C0E_415B_8FD6_D4AF68BC8AC6">Script and arguments</listBox>\r
+      </presentation>\r
+    </presentationTable>\r
+  </resources>\r
+</policyDefinitionResources>\r
diff --git a/libgpo/admx/samba.admx b/libgpo/admx/samba.admx
new file mode 100755 (executable)
index 0000000..f2921ff
--- /dev/null
@@ -0,0 +1,23 @@
+<policyDefinitions revision="1.0" schemaVersion="1.0">\r
+  <policyNamespaces>\r
+    <target prefix="fullarmor" namespace="FullArmor.Policies.98BB16AF_01EE_4D17_870D_A3311A44D6C2" />\r
+    <using prefix="windows" namespace="Microsoft.Policies.Windows" />\r
+  </policyNamespaces>\r
+  <supersededAdm fileName="" />\r
+  <resources minRequiredRevision="1.0" />\r
+  <categories>\r
+    <category name="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9" displayName="$(string.CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9)" />\r
+    <category name="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6" displayName="$(string.CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6)">\r
+      <parentCategory ref="CAT_3338C1DD_8A00_4273_8547_158D8B8C19E9" />\r
+    </category>\r
+  </categories>\r
+  <policies>\r
+    <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">\r
+      <parentCategory ref="CAT_7D8D7DC8_5A9D_4BE1_8227_F09CDD5AFFC6" />\r
+      <supportedOn ref="windows:SUPPORTED_WindowsVista" />\r
+      <elements>\r
+        <list id="LST_2E9A4684_3C0E_415B_8FD6_D4AF68BC8AC6" key="Software\Policies\Samba\Unix Settings\Daily Scripts" valueName="Daily Scripts" />\r
+      </elements>\r
+    </policy>\r
+  </policies>\r
+</policyDefinitions>\r
diff --git a/libgpo/admx/wscript_build b/libgpo/admx/wscript_build
new file mode 100644 (file)
index 0000000..cb1cadb
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+
+bld.INSTALL_FILES('${DATADIR}/samba/admx', ['samba.admx', 'en-US/samba.adml'])
index f36ccf2c701c3eb23d3ea56770b97bcd58479276..e6e54fe359a8146b0d216fbc66cca1eff1aa2032 100644 (file)
@@ -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 (file)
index 0000000..f83f367
--- /dev/null
@@ -0,0 +1,53 @@
+# gp_scripts_ext samba gpo policy
+# Copyright (C) David Mulder <dmulder@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()
index 528019c7478f29f0bb9fb24159da6b548b49f653..68dfad1ed87dd3407f4167127ac2c1bc76e6ef9d 100755 (executable)
@@ -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':