1 # GPO Parser for registry extension
3 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
4 # Written by Garming Sam <garming@catalyst.net.nz>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 from xml.etree.ElementTree import Element, SubElement
25 from samba.dcerpc import preg
26 from samba.dcerpc import misc
27 from samba.ndr import ndr_pack, ndr_unpack
29 from samba.gp_parse import GPParser
32 # [MS-GPFAS] Firewall and Advanced Security
33 # [MS-GPEF] Encrypting File System
34 # [MS-GPNRPT] Name Resolution Table
35 class GPPolParser(GPParser):
39 misc.REG_NONE: "REG_NONE",
40 misc.REG_SZ: "REG_SZ",
41 misc.REG_DWORD: "REG_DWORD",
42 misc.REG_DWORD_BIG_ENDIAN: "REG_DWORD_BIG_ENDIAN",
43 misc.REG_QWORD: "REG_QWORD",
44 misc.REG_EXPAND_SZ: "REG_EXPAND_SZ",
45 misc.REG_MULTI_SZ: "REG_MULTI_SZ",
46 misc.REG_BINARY: "REG_BINARY"
49 def map_reg_type(self, val):
50 ret = self.reg_type.get(val)
55 def parse(self, contents):
56 self.pol_file = ndr_unpack(preg.file, contents)
58 def load_xml(self, root):
59 self.pol_file = preg.file()
60 self.pol_file.header.signature = root.attrib['signature']
61 self.pol_file.header.version = int(root.attrib['version'])
62 self.pol_file.num_entries = int(root.attrib['num_entries'])
65 for e in root.findall('Entry'):
67 entry_type = int(e.attrib['type'])
69 entry.type = entry_type
71 entry.keyname = e.find('Key').text
72 value_name = e.find('ValueName').text
73 if value_name is None:
76 entry.valuename = value_name
77 # entry.size = int(e.attrib['size'])
79 if misc.REG_MULTI_SZ == entry_type:
80 values = [x.text for x in e.findall('Value')]
81 entry.data = (u'\x00'.join(values) + u'\x00\x00').encode('utf-16le')
82 elif (misc.REG_NONE == entry_type):
84 elif (misc.REG_SZ == entry_type or
85 misc.REG_EXPAND_SZ == entry_type):
86 string_val = e.find('Value').text
87 if string_val is None:
89 entry.data = string_val
90 elif (misc.REG_DWORD == entry_type or
91 misc.REG_DWORD_BIG_ENDIAN == entry_type or
92 misc.REG_QWORD == entry_type):
93 entry.data = int(e.find('Value').text)
94 else: # REG UNKNOWN or REG_BINARY
95 entry.data = base64.b64decode(e.find('Value').text)
99 self.pol_file.entries = entries
100 # print self.pol_file.__ndr_print__()
102 def write_xml(self, filename):
103 with file(filename, 'w') as f:
104 root = Element('PolFile')
105 root.attrib['signature'] = self.pol_file.header.signature
106 root.attrib['version'] = str(self.pol_file.header.version)
107 root.attrib['num_entries'] = str(self.pol_file.num_entries)
108 for entry in self.pol_file.entries:
109 child = SubElement(root, 'Entry')
110 # child.attrib['size'] = str(entry.size)
111 child.attrib['type'] = str(entry.type)
112 child.attrib['type_name'] = self.map_reg_type(entry.type)
113 key = SubElement(child, 'Key')
114 key.text = entry.keyname
115 valuename = SubElement(child, 'ValueName')
116 valuename.text = entry.valuename
117 if misc.REG_MULTI_SZ == entry.type:
118 multi = entry.data.decode('utf-16').rstrip(u'\x00').split(u'\x00')
121 value = SubElement(child, 'Value')
123 # print tostring(value)
124 elif (misc.REG_NONE == entry.type or
125 misc.REG_SZ == entry.type or
126 misc.REG_DWORD == entry.type or
127 misc.REG_DWORD_BIG_ENDIAN == entry.type or
128 misc.REG_QWORD == entry.type or
129 misc.REG_EXPAND_SZ == entry.type):
130 value = SubElement(child, 'Value')
131 value.text = str(entry.data)
132 # print tostring(value)
133 else: # REG UNKNOWN or REG_BINARY
134 value = SubElement(child, 'Value')
135 value.text = base64.b64encode(entry.data).decode('utf8')
136 # print tostring(value)
138 # print tostring(root)
140 self.write_pretty_xml(root, f)
142 # contents = codecs.open(filename, encoding='utf-8').read()
143 # self.load_xml(fromstring(contents))
145 def write_binary(self, filename):
146 with file(filename, 'wb') as f:
147 binary_data = ndr_pack(self.pol_file)