s4-python: Remove more unused imports, fix use of sets in upgradehelpers.
[kai/samba-autobuild/.git] / source4 / scripting / bin / fullschema
1 #!/usr/bin/env python
2
3 # Works out the full schema
4 #
5
6 import base64
7 import optparse
8 import sys
9
10 # Find right directory when running from source tree
11 sys.path.insert(0, "bin/python")
12
13 import samba
14 from samba import getopt as options, Ldb
15 from ldb import SCOPE_SUBTREE, SCOPE_BASE
16 import sys
17
18 parser = optparse.OptionParser("fullschema <URL>")
19 sambaopts = options.SambaOptions(parser)
20 parser.add_option_group(sambaopts)
21 credopts = options.CredentialsOptions(parser)
22 parser.add_option_group(credopts)
23 parser.add_option_group(options.VersionOptions(parser))
24 parser.add_option("--dump-classes", action="store_true")
25 parser.add_option("--dump-attributes", action="store_true")
26
27 opts, args = parser.parse_args()
28 opts.dump_all = True
29
30 if opts.dump_classes:
31     opts.dump_all = False
32 if opts.dump_attributes:
33     opts.dump_all = False
34 if opts.dump_all:
35     opts.dump_classes = True
36     opts.dump_attributes = True
37
38 if len(args) != 1:
39     parser.print_usage()
40     sys.exit(1)
41
42 url = args[0]
43
44 lp_ctx = sambaopts.get_loadparm()
45
46 creds = credopts.get_credentials(lp_ctx)
47 ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
48
49 # the attributes we need for objectclasses
50 class_attrs = ["objectClass", 
51                "cn",
52                "subClassOf", 
53                "governsID", 
54                "possSuperiors", 
55                "possibleInferiors",
56                "mayContain",
57                "mustContain",
58                "auxiliaryClass",
59                "rDNAttID",
60                "adminDisplayName",
61                "adminDescription",
62                "objectClassCategory",
63                "lDAPDisplayName",
64                "schemaIDGUID",
65                "systemOnly",
66                "systemPossSuperiors",
67                "systemMayContain",
68                "systemMustContain",
69                "systemAuxiliaryClass",
70                "defaultSecurityDescriptor",
71                "systemFlags",
72                "defaultHidingValue",
73                "defaultObjectCategory", 
74                
75                # this attributes are not used by w2k3
76                "schemaFlagsEx",
77                "msDs-IntId",
78                "msDs-Schema-Extensions",
79                "classDisplayName",
80                "isDefunct"]
81
82 attrib_attrs = ["objectClass",
83                 "cn",
84                 "attributeID", 
85                 "attributeSyntax",
86                 "isSingleValued",
87                 "rangeLower",
88                 "rangeUpper",
89                 "mAPIID",
90                 "linkID",
91                 "adminDisplayName",
92                 "oMObjectClass",
93                 "adminDescription",
94                 "oMSyntax", 
95                 "searchFlags",
96                 "extendedCharsAllowed",
97                 "lDAPDisplayName",
98                 "schemaIDGUID",
99                 "attributeSecurityGUID",
100                 "systemOnly",
101                 "systemFlags",
102                 "isMemberOfPartialAttributeSet",
103                 
104                 # this attributes are not used by w2k3
105                 "schemaFlagsEx",
106                 "msDs-IntId",
107                 "msDs-Schema-Extensions",
108                 "classDisplayName",
109                 "isEphemeral",
110                 "isDefunct"]
111
112 class Objectclass(dict):
113
114     def __init__(self, ldb, name):
115         """create an objectclass object"""
116         self.name = name
117
118
119 class Attribute(dict):
120
121     def __init__(self, ldb, name):
122         """create an attribute object"""
123         self.name = name
124         self["cn"] = get_object_cn(ldb, name)
125
126
127
128 def fix_dn(dn):
129     """fix a string DN to use ${SCHEMADN}"""
130     return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
131
132
133 def write_ldif_one(o, attrs):
134     """dump an object as ldif"""
135     print "dn: CN=%s,${SCHEMADN}" % o["cn"]
136     for a in attrs:
137         if not o.has_key(a):
138             continue
139         # special case for oMObjectClass, which is a binary object
140         v = o[a]
141         list = []
142         for j in v:
143             value = fix_dn(j)
144             list.append(value)
145         list.sort()
146         for j in list:
147             value = fix_dn(j)
148             if a != "cn":
149                 if a == "oMObjectClass":
150                     print "%s:: %s" % (a, base64.b64encode(value))
151                 elif a.endswith("GUID"):
152                     print "%s: %s" % (a, ldb.schema_format_value(a, value))
153                 else:
154                     print "%s: %s" % (a, value)
155     print ""
156
157
158 # get the rootDSE
159 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
160 rootDse = res[0]
161
162 if opts.dump_attributes:
163     res = ldb.search(expression="objectClass=attributeSchema", 
164                      base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs,
165                      controls=["server_sort:1:0:cn"])
166     
167     for msg in res:
168         o = Objectclass(ldb, msg["ldapDisplayName"])
169         for a in msg:
170             o[a] = msg[a]
171         write_ldif_one(o, attrib_attrs)
172             
173 if opts.dump_classes:
174     res = ldb.search(expression="objectClass=classSchema", 
175                      base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs,
176                      controls=["server_sort:1:0:cn"])
177
178     for msg in res:
179         o = Objectclass(ldb, msg["ldapDisplayName"])
180         for a in msg:
181             o[a] = msg[a]
182         write_ldif_one(o, class_attrs)
183