VERSION: Disable GIT_SNAPSHOT for the 4.9.4 release.
[Samba.git] / python / samba / ms_display_specifiers.py
blob0d7b39aaae99eefea506808a28d43c6aa4835642
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
22 import re
24 def __read_folded_line(f, buffer):
25 """Read a line from an LDIF file, unfolding it"""
26 line = buffer
28 while True:
29 l = f.readline()
31 if l[:1] == " ":
32 # continued line
34 # cannot fold an empty line
35 assert(line != "" and line != "\n")
37 # preserves '\n '
38 line = line + l
39 else:
40 # non-continued line
41 if line == "":
42 line = l
44 if l == "":
45 # eof, definitely won't be folded
46 break
47 else:
48 # marks end of a folded line
49 # line contains the now unfolded line
50 # buffer contains the start of the next possibly folded line
51 buffer = l
52 break
54 return (line, buffer)
56 # Only compile regexp once.
57 # Will not match options after the attribute type.
58 attr_type_re = re.compile("^([A-Za-z][A-Za-z0-9-]*):")
60 def __read_raw_entries(f):
61 """Read an LDIF entry, only unfolding lines"""
63 buffer = ""
65 while True:
66 entry = []
68 while True:
69 (l, buffer) = __read_folded_line(f, buffer)
71 if l[:1] == "#":
72 continue
74 if l == "\n" or l == "":
75 break
77 m = attr_type_re.match(l)
79 if m:
80 if l[-1:] == "\n":
81 l = l[:-1]
83 entry.append(l)
84 else:
85 print("Invalid line: %s" % l, end=' ', file=sys.stderr)
86 sys.exit(1)
88 if len(entry):
89 yield entry
91 if l == "":
92 break
94 def fix_dn(dn):
95 """Fix a string DN to use ${CONFIGDN}"""
97 if dn.find("<Configuration NC Distinguished Name>") != -1:
98 dn = dn.replace("\n ", "")
99 return dn.replace("<Configuration NC Distinguished Name>", "${CONFIGDN}")
100 else:
101 return dn
103 def __write_ldif_one(entry):
104 """Write out entry as LDIF"""
105 out = []
107 for l in entry:
108 if l[2] == 0:
109 out.append("%s: %s" % (l[0], l[1]))
110 else:
111 # This is a base64-encoded value
112 out.append("%s:: %s" % (l[0], l[1]))
114 return "\n".join(out)
116 def __transform_entry(entry):
117 """Perform required transformations to the Microsoft-provided LDIF"""
119 temp_entry = []
121 for l in entry:
122 t = []
124 if l.find("::") != -1:
125 # This is a base64-encoded value
126 t = l.split(":: ", 1)
127 t.append(1)
128 else:
129 t = l.split(": ", 1)
130 t.append(0)
132 key = t[0].lower()
134 if key == "changetype":
135 continue
137 if key == "distinguishedname":
138 continue
140 if key == "instancetype":
141 continue
143 if key == "name":
144 continue
146 if key == "cn":
147 continue
149 if key == "objectcategory":
150 continue
152 if key == "showinadvancedviewonly":
153 value = t[1].upper().lstrip().rstrip()
154 if value == "TRUE":
155 # Remove showInAdvancedViewOnly attribute if it is set to the
156 # default value of TRUE
157 continue
159 t[1] = fix_dn(t[1])
161 temp_entry.append(t)
163 entry = temp_entry
165 return entry
167 def read_ms_ldif(filename):
168 """Read and transform Microsoft-provided LDIF file."""
170 out = []
172 f = open(filename, "rU")
173 for entry in __read_raw_entries(f):
174 out.append(__write_ldif_one(__transform_entry(entry)))
176 return "\n\n".join(out) + "\n\n"
178 if __name__ == '__main__':
179 import sys
181 try:
182 display_specifiers_file = sys.argv[1]
183 except IndexError:
184 print("Usage: %s display-specifiers-ldif-file.txt" % (sys.argv[0]), file=sys.stderr)
185 sys.exit(1)
187 print(read_ms_ldif(display_specifiers_file))