summaryrefslogtreecommitdiffstats
path: root/python/samba/gp_parse/gp_pol.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/samba/gp_parse/gp_pol.py')
-rw-r--r--python/samba/gp_parse/gp_pol.py151
1 files changed, 151 insertions, 0 deletions
diff --git a/python/samba/gp_parse/gp_pol.py b/python/samba/gp_parse/gp_pol.py
new file mode 100644
index 0000000..1d5f348
--- /dev/null
+++ b/python/samba/gp_parse/gp_pol.py
@@ -0,0 +1,151 @@
+# GPO Parser for registry extension
+#
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
+# Written by Garming Sam <garming@catalyst.net.nz>
+#
+# 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 base64
+
+from xml.etree.ElementTree import Element, SubElement
+
+from samba.dcerpc import preg
+from samba.dcerpc import misc
+from samba.ndr import ndr_pack, ndr_unpack
+
+from samba.gp_parse import GPParser
+
+# [MS-GPREG]
+# [MS-GPFAS] Firewall and Advanced Security
+# [MS-GPEF] Encrypting File System
+# [MS-GPNRPT] Name Resolution Table
+class GPPolParser(GPParser):
+ pol_file = None
+
+ reg_type = {
+ misc.REG_NONE: "REG_NONE",
+ misc.REG_SZ: "REG_SZ",
+ misc.REG_DWORD: "REG_DWORD",
+ misc.REG_DWORD_BIG_ENDIAN: "REG_DWORD_BIG_ENDIAN",
+ misc.REG_QWORD: "REG_QWORD",
+ misc.REG_EXPAND_SZ: "REG_EXPAND_SZ",
+ misc.REG_MULTI_SZ: "REG_MULTI_SZ",
+ misc.REG_BINARY: "REG_BINARY"
+ }
+
+ def map_reg_type(self, val):
+ ret = self.reg_type.get(val)
+ if ret is None:
+ return "REG_UNKNOWN"
+ return ret
+
+ def parse(self, contents):
+ self.pol_file = ndr_unpack(preg.file, contents)
+
+ def load_xml(self, root):
+ self.pol_file = preg.file()
+ self.pol_file.header.signature = root.attrib['signature']
+ self.pol_file.header.version = int(root.attrib['version'])
+ self.pol_file.num_entries = int(root.attrib['num_entries'])
+
+ entries = []
+ for e in root.findall('Entry'):
+ entry = preg.entry()
+ entry_type = int(e.attrib['type'])
+
+ entry.type = entry_type
+
+ entry.keyname = e.find('Key').text
+ value_name = e.find('ValueName').text
+ if value_name is None:
+ value_name = ''
+
+ entry.valuename = value_name
+ # entry.size = int(e.attrib['size'])
+
+ if misc.REG_MULTI_SZ == entry_type:
+ values = [x.text for x in e.findall('Value')]
+ if values == [None]:
+ data = u'\x00'
+ else:
+ data = u'\x00'.join(values) + u'\x00\x00'
+ entry.data = data.encode('utf-16le')
+ elif (misc.REG_NONE == entry_type):
+ pass
+ elif (misc.REG_SZ == entry_type or
+ misc.REG_EXPAND_SZ == entry_type):
+ string_val = e.find('Value').text
+ if string_val is None:
+ string_val = ''
+ entry.data = string_val
+ elif (misc.REG_DWORD == entry_type or
+ misc.REG_DWORD_BIG_ENDIAN == entry_type or
+ misc.REG_QWORD == entry_type):
+ entry.data = int(e.find('Value').text)
+ else: # REG UNKNOWN or REG_BINARY
+ entry.data = base64.b64decode(e.find('Value').text)
+
+ entries.append(entry)
+
+ self.pol_file.entries = entries
+ # print self.pol_file.__ndr_print__()
+
+ def write_xml(self, filename):
+ with open(filename, 'wb') as f:
+ root = Element('PolFile')
+ root.attrib['num_entries'] = str(self.pol_file.num_entries)
+ root.attrib['signature'] = self.pol_file.header.signature
+ root.attrib['version'] = str(self.pol_file.header.version)
+ for entry in self.pol_file.entries:
+ child = SubElement(root, 'Entry')
+ # child.attrib['size'] = str(entry.size)
+ child.attrib['type'] = str(entry.type)
+ child.attrib['type_name'] = self.map_reg_type(entry.type)
+ key = SubElement(child, 'Key')
+ key.text = entry.keyname
+ valuename = SubElement(child, 'ValueName')
+ valuename.text = entry.valuename
+ if misc.REG_MULTI_SZ == entry.type:
+ multi = entry.data.decode('utf-16').rstrip(u'\x00').split(u'\x00')
+ # print repr(multi)
+ for m in multi:
+ value = SubElement(child, 'Value')
+ value.text = m
+ # print tostring(value)
+ elif (misc.REG_NONE == entry.type or
+ misc.REG_SZ == entry.type or
+ misc.REG_DWORD == entry.type or
+ misc.REG_DWORD_BIG_ENDIAN == entry.type or
+ misc.REG_QWORD == entry.type or
+ misc.REG_EXPAND_SZ == entry.type):
+ value = SubElement(child, 'Value')
+ value.text = str(entry.data)
+ # print tostring(value)
+ else: # REG UNKNOWN or REG_BINARY
+ value = SubElement(child, 'Value')
+ value.text = base64.b64encode(entry.data).decode('utf8')
+ # print tostring(value)
+
+ # print tostring(root)
+
+ self.write_pretty_xml(root, f)
+
+ # contents = codecs.open(filename, encoding='utf-8').read()
+ # self.load_xml(fromstring(contents))
+
+ def write_binary(self, filename):
+ with open(filename, 'wb') as f:
+ binary_data = ndr_pack(self.pol_file)
+ f.write(binary_data)