• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/scripting/python/samba/
1#!/usr/bin/python
2#
3# Create DisplaySpecifiers LDIF (as a string) from the documents provided by
4# Microsoft under the WSPP.
5#
6# Copyright (C) Andrew Kroeger <andrew@id10ts.net> 2009
7#
8# Based on ms_schema.py
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23import re
24
25def __read_folded_line(f, buffer):
26    """Read a line from an LDIF file, unfolding it"""
27    line = buffer
28
29    while True:
30        l = f.readline()
31
32        if l[:1] == " ":
33            # continued line
34
35            # cannot fold an empty line
36            assert(line != "" and line != "\n")
37
38            # preserves '\n '
39            line = line + l
40        else:
41            # non-continued line
42            if line == "":
43                line = l
44
45                if l == "":
46                    # eof, definitely won't be folded
47                    break
48            else:
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
52                buffer = l
53                break
54
55    return (line, buffer)
56
57# Only compile regexp once.
58# Will not match options after the attribute type.
59attr_type_re = re.compile("^([A-Za-z][A-Za-z0-9-]*):")
60
61def __read_raw_entries(f):
62    """Read an LDIF entry, only unfolding lines"""
63
64    buffer = ""
65
66    while True:
67        entry = []
68
69        while True:
70            (l, buffer) = __read_folded_line(f, buffer)
71
72            if l[:1] == "#":
73                continue
74
75            if l == "\n" or l == "":
76                break
77
78            m = attr_type_re.match(l)
79
80            if m:
81                if l[-1:] == "\n":
82                    l = l[:-1]
83
84                entry.append(l)
85            else:
86                print >>sys.stderr, "Invalid line: %s" % l,
87                sys.exit(1)
88
89        if len(entry):
90            yield entry
91
92        if l == "":
93            break
94
95def fix_dn(dn):
96    """Fix a string DN to use ${CONFIGDN}"""
97
98    if dn.find("<Configuration NC Distinguished Name>") != -1:
99        dn = dn.replace("\n ", "")
100        return dn.replace("<Configuration NC Distinguished Name>", "${CONFIGDN}")
101    else:
102        return dn
103
104def __write_ldif_one(entry):
105    """Write out entry as LDIF"""
106    out = []
107
108    for l in entry:
109        if l[2] == 0:
110            out.append("%s: %s" % (l[0], l[1]))
111        else:
112            # This is a base64-encoded value
113            out.append("%s:: %s" % (l[0], l[1]))
114
115    return "\n".join(out)
116
117def __transform_entry(entry):
118    """Perform required transformations to the Microsoft-provided LDIF"""
119
120    temp_entry = []
121
122    for l in entry:
123        t = []
124
125        if l.find("::") != -1:
126            # This is a base64-encoded value
127            t = l.split(":: ", 1)
128            t.append(1)
129        else:
130            t = l.split(": ", 1)
131            t.append(0)
132
133        key = t[0].lower()
134
135        if key == "changetype":
136            continue
137
138        if key == "distinguishedname":
139            continue
140
141        if key == "instancetype":
142            continue
143
144        if key == "name":
145            continue
146
147        if key == "cn":
148            continue
149
150        if key == "objectcategory":
151            continue
152
153        if key == "showinadvancedviewonly":
154            value = t[1].upper().lstrip().rstrip()
155            if value == "TRUE":
156                # Remove showInAdvancedViewOnly attribute if it is set to the
157                # default value of TRUE
158                continue
159
160        t[1] = fix_dn(t[1])
161
162        temp_entry.append(t)
163
164    entry = temp_entry
165
166    return entry
167
168def read_ms_ldif(filename):
169    """Read and transform Microsoft-provided LDIF file."""
170
171    out = []
172
173    f = open(filename, "rU")
174    for entry in __read_raw_entries(f):
175        out.append(__write_ldif_one(__transform_entry(entry)))
176
177    return "\n\n".join(out) + "\n\n"
178
179if __name__ == '__main__':
180    import sys
181
182    try:
183        display_specifiers_file = sys.argv[1]
184    except IndexError:
185        print >>sys.stderr, "Usage: %s display-specifiers-ldif-file.txt" % (sys.argv[0])
186        sys.exit(1)
187
188    print read_ms_ldif(display_specifiers_file)
189
190