From: Garming Sam Date: Thu, 10 May 2018 05:15:23 +0000 (+1200) Subject: gp_csv: Parse the audit.csv file which records audit settings X-Git-Tag: tdb-1.3.17~2161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a69308b7a5fa3f14681fd951999500129ee5bea;p=thirdparty%2Fsamba.git gp_csv: Parse the audit.csv file which records audit settings Based on the setting, the csv will omit certain fields. Using this we can later infer as to how to generalize the ACLs and SIDs. Signed-off-by: Garming Sam Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/gp_parse/gp_csv.py b/python/samba/gp_parse/gp_csv.py new file mode 100644 index 00000000000..4c7e7cfa5d5 --- /dev/null +++ b/python/samba/gp_parse/gp_csv.py @@ -0,0 +1,164 @@ +# GPO Parser for audit extensions +# +# Copyright (C) Andrew Bartlett 2018 +# Written by Garming Sam +# +# 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 . +# + +import codecs +import csv +import io + +from io import BytesIO +from xml.etree.ElementTree import Element, SubElement + +from samba.gp_parse import GPParser + +# [MS-GPAC] Group Policy Audit Configuration +class GPAuditCsvParser(GPParser): + encoding = 'utf-8' + header = None + lines = [] + + def parse(self, contents): + self.lines = [] + reader = UnicodeReader(BytesIO(contents), + encoding=self.encoding) + + self.header = reader.next() + for row in reader: + line = {} + for i, x in enumerate(row): + line[self.header[i]] = x + + self.lines.append(line) + # print line + + def write_xml(self, filename): + with file(filename, 'wb') as f: + root = Element('CsvFile') + child = SubElement(root, 'Row') + for e in self.header: + value = SubElement(child, 'Value') + value.text = e + + for line in self.lines: + child = SubElement(root, 'Row') + for e in [line[x] for x in self.header]: + value = SubElement(child, 'Value') + value.text = e + + self.write_pretty_xml(root, f) + + + # contents = codecs.open(filename, encoding='utf-8').read() + # self.load_xml(fromstring(contents)) + + def load_xml(self, root): + header = True + self.lines = [] + + for r in root.findall('Row'): + if header: + header = False + self.header = [] + for v in r.findall('Value'): + self.header.append(v.text.decode(self.output_encoding)) + else: + line = {} + for i, v in enumerate(r.findall('Value')): + line[self.header[i]] = v.text if v.text is not None else '' + line[self.header[i]] = line[self.header[i]].decode(self.output_encoding) + + self.lines.append(line) + + def write_binary(self, filename): + with file(filename, 'wb') as f: + # This should be using a unicode writer, but it seems to be in the + # right encoding at least by default. + # + # writer = UnicodeWriter(f, quoting=csv.QUOTE_MINIMAL) + writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL) + writer.writerow(self.header) + for line in self.lines: + writer.writerow([line[x] for x in self.header]) + + +# The following classes come from the Python documentation +# https://docs.python.org/3.0/library/csv.html + + +class UTF8Recoder: + """ + Iterator that reads an encoded stream and reencodes the input to UTF-8 + """ + def __init__(self, f, encoding): + self.reader = codecs.getreader(encoding)(f) + + def __iter__(self): + return self + + def next(self): + return next(self.reader).encode("utf-8") + + __next__ = next + +class UnicodeReader: + """ + A CSV reader which will iterate over lines in the CSV file "f", + which is encoded in the given encoding. + """ + + def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): + f = UTF8Recoder(f, encoding) + self.reader = csv.reader(f, dialect=dialect, **kwds) + + def next(self): + row = next(self.reader) + return [unicode(s, "utf-8") for s in row] + + def __iter__(self): + return self + + __next__ = next + +class UnicodeWriter: + """ + A CSV writer which will write rows to CSV file "f", + which is encoded in the given encoding. + """ + + def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): + # Redirect output to a queue + self.queue = io.StringIO() + self.writer = csv.writer(self.queue, dialect=dialect, **kwds) + self.stream = f + self.encoder = codecs.getincrementalencoder(encoding)() + + def writerow(self, row): + self.writer.writerow([s.encode("utf-8") for s in row]) + # Fetch UTF-8 output from the queue ... + data = self.queue.getvalue() + data = data.decode("utf-8") + # ... and reencode it into the target encoding + data = self.encoder.encode(data) + # write to the target stream + self.stream.write(data) + # empty queue + self.queue.truncate(0) + + def writerows(self, rows): + for row in rows: + self.writerow(row)