1 # Create DisplaySpecifiers LDIF (as a string) from the documents provided by
2 # Microsoft under the WSPP.
4 # Copyright (C) Andrew Kroeger <andrew@id10ts.net> 2009
6 # Based on ms_schema.py
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from __future__ import print_function
25 def __read_folded_line(f, buffer):
26 """Read a line from an LDIF file, unfolding it"""
35 # cannot fold an empty line
36 assert(line != "" and line != "\n")
46 # eof, definitely won't be folded
49 # marks end of a folded line
50 # line contains the now unfolded line
51 # buffer contains the start of the next possibly folded line
58 # Only compile regexp once.
59 # Will not match options after the attribute type.
60 attr_type_re = re.compile("^([A-Za-z][A-Za-z0-9-]*):")
63 def __read_raw_entries(f):
64 """Read an LDIF entry, only unfolding lines"""
72 (l, buffer) = __read_folded_line(f, buffer)
77 if l == "\n" or l == "":
80 m = attr_type_re.match(l)
88 print("Invalid line: %s" % l, end=' ', file=sys.stderr)
99 """Fix a string DN to use ${CONFIGDN}"""
101 if dn.find("<Configuration NC Distinguished Name>") != -1:
102 dn = dn.replace("\n ", "")
103 return dn.replace("<Configuration NC Distinguished Name>", "${CONFIGDN}")
108 def __write_ldif_one(entry):
109 """Write out entry as LDIF"""
114 out.append("%s: %s" % (l[0], l[1]))
116 # This is a base64-encoded value
117 out.append("%s:: %s" % (l[0], l[1]))
119 return "\n".join(out)
122 def __transform_entry(entry):
123 """Perform required transformations to the Microsoft-provided LDIF"""
130 if l.find("::") != -1:
131 # This is a base64-encoded value
132 t = l.split(":: ", 1)
140 if key == "changetype":
143 if key == "distinguishedname":
146 if key == "instancetype":
155 if key == "objectcategory":
158 if key == "showinadvancedviewonly":
159 value = t[1].upper().lstrip().rstrip()
161 # Remove showInAdvancedViewOnly attribute if it is set to the
162 # default value of TRUE
174 def read_ms_ldif(filename):
175 """Read and transform Microsoft-provided LDIF file."""
180 f = open(filename, "r", encoding='latin-1')
181 for entry in __read_raw_entries(f):
182 out.append(__write_ldif_one(__transform_entry(entry)))
184 return "\n\n".join(out) + "\n\n"
187 if __name__ == '__main__':
191 display_specifiers_file = sys.argv[1]
193 print("Usage: %s display-specifiers-ldif-file.txt" % (sys.argv[0]), file=sys.stderr)
196 print(read_ms_ldif(display_specifiers_file))