VERSION: Bump version number up to 4.0.4.
[samba.git] / source4 / scripting / python / samba / ms_schema.py
index a0abc337ce45cb54de851533f3ef78cfe7b4a4f7..c16693c9b5ab08469816de5650b172b689bf0bb0 100644 (file)
@@ -1,12 +1,25 @@
-#!/usr/bin/env python
-#
 # create schema.ldif (as a string) from WSPP documentation
 #
 # based on minschema.py and minschema_wspp
 #
+# 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 <http://www.gnu.org/licenses/>.
+
+"""Generate LDIF from WSPP documentation."""
 
 import re
 import base64
+import uuid
 
 bitFields = {}
 
@@ -15,7 +28,7 @@ bitFields = {}
 bitFields["searchflags"] = {
     'fATTINDEX': 31,         # IX
     'fPDNTATTINDEX': 30,     # PI
-    'fANR': 29, #AR
+    'fANR': 29,  # AR
     'fPRESERVEONDELETE': 28,         # PR
     'fCOPY': 27,     # CP
     'fTUPLEINDEX': 26,       # TP
@@ -33,19 +46,19 @@ bitFields["searchflags"] = {
 
 # ADTS: 2.2.10
 bitFields["systemflags"] = {
-    'FLAG_ATTR_NOT_REPLICATED': 31, 'FLAG_CR_NTDS_NC': 31,     # NR
-    'FLAG_ATTR_REQ_PARTIAL_SET_MEMBER': 30, 'FLAG_CR_NTDS_DOMAIN': 30,         # PS
-    'FLAG_ATTR_IS_CONSTRUCTED': 29, 'FLAG_CR_NTDS_NOT_GC_REPLICATED': 29,      # CS
-    'FLAG_ATTR_IS_OPERATIONAL': 28,    # OP
-    'FLAG_SCHEMA_BASE_OBJECT': 27,     # BS
-    'FLAG_ATTR_IS_RDN': 26,    # RD
-    'FLAG_DISALLOW_MOVE_ON_DELETE': 6,         # DE
-    'FLAG_DOMAIN_DISALLOW_MOVE': 5,    # DM
-    'FLAG_DOMAIN_DISALLOW_RENAME': 4,  # DR
-    'FLAG_CONFIG_ALLOW_LIMITED_MOVE': 3,       # AL
-    'FLAG_CONFIG_ALLOW_MOVE': 2,       # AM
-    'FLAG_CONFIG_ALLOW_RENAME': 1,     # AR
-    'FLAG_DISALLOW_DELETE': 0  # DD
+    'FLAG_ATTR_NOT_REPLICATED': 31, 'FLAG_CR_NTDS_NC': 31,     # NR
+    'FLAG_ATTR_REQ_PARTIAL_SET_MEMBER': 30, 'FLAG_CR_NTDS_DOMAIN': 30,     # PS
+    'FLAG_ATTR_IS_CONSTRUCTED': 29, 'FLAG_CR_NTDS_NOT_GC_REPLICATED': 29,     # CS
+    'FLAG_ATTR_IS_OPERATIONAL': 28,     # OP
+    'FLAG_SCHEMA_BASE_OBJECT': 27,     # BS
+    'FLAG_ATTR_IS_RDN': 26,     # RD
+    'FLAG_DISALLOW_MOVE_ON_DELETE': 6,     # DE
+    'FLAG_DOMAIN_DISALLOW_MOVE': 5,     # DM
+    'FLAG_DOMAIN_DISALLOW_RENAME': 4,     # DR
+    'FLAG_CONFIG_ALLOW_LIMITED_MOVE': 3,     # AL
+    'FLAG_CONFIG_ALLOW_MOVE': 2,     # AM
+    'FLAG_CONFIG_ALLOW_RENAME': 1,     # AR
+    'FLAG_DISALLOW_DELETE': 0     # DD
     }
 
 # ADTS: 2.2.11
@@ -72,7 +85,7 @@ multivalued_attrs = set(["auxiliaryclass","maycontain","mustcontain","posssuperi
 def __read_folded_line(f, buffer):
     """ reads a line from an LDIF file, unfolding it"""
     line = buffer
-    
+
     while True:
         l = f.readline()
 
@@ -85,7 +98,7 @@ def __read_folded_line(f, buffer):
             # preserves '\n '
             line = line + l
         else:
-            # non-continued line            
+            # non-continued line
             if line == "":
                 line = l
 
@@ -98,7 +111,7 @@ def __read_folded_line(f, buffer):
                 # buffer contains the start of the next possibly folded line
                 buffer = l
                 break
-        
+
     return (line, buffer)
 
 
@@ -109,13 +122,13 @@ def __read_raw_entries(f):
     attr_type_re = re.compile("^([A-Za-z]+[A-Za-z0-9-]*):")
 
     buffer = ""
-    
+
     while True:
         entry = []
-        
+
         while True:
             (l, buffer) = __read_folded_line(f, buffer)
-                        
+
             if l[:1] == "#":
                 continue
 
@@ -127,7 +140,7 @@ def __read_raw_entries(f):
             if m:
                 if l[-1:] == "\n":
                     l = l[:-1]
-                    
+
                 entry.append(l)
             else:
                 print >>sys.stderr, "Invalid line: %s" % l,
@@ -157,7 +170,7 @@ def __convert_bitfield(key, value):
 
     value = value.replace("\n ", "")
     value = value.replace(" ", "")
-    
+
     try:
         # some attributes already have numeric values
         o = int(value)
@@ -173,7 +186,7 @@ def __convert_bitfield(key, value):
 def __write_ldif_one(entry):
     """Write out entry as LDIF"""
     out = []
-    
+
     for l in entry:
         if isinstance(l[1], str):
             vl = [l[1]]
@@ -183,21 +196,21 @@ def __write_ldif_one(entry):
         if l[0].lower() == 'omobjectclass':
             out.append("%s:: %s" % (l[0], l[1]))
             continue
-            
+
         for v in vl:
             out.append("%s: %s" % (l[0], v))
 
 
     return "\n".join(out)
-    
+
 def __transform_entry(entry, objectClass):
     """Perform transformations required to convert the LDIF-like schema
        file entries to LDIF, including Samba-specific stuff."""
-    
+
     entry = [l.split(":", 1) for l in entry]
 
     cn = ""
-    
+
     for l in entry:
         key = l[0].lower()
         l[1] = l[1].lstrip()
@@ -205,14 +218,14 @@ def __transform_entry(entry, objectClass):
 
         if not cn and key == "cn":
             cn = l[1]
-        
+
         if key in multivalued_attrs:
             # unlike LDIF, these are comma-separated
             l[1] = l[1].replace("\n ", "")
             l[1] = l[1].replace(" ", "")
 
             l[1] = l[1].split(",")
-            
+
         if key in bitFields:
             l[1] = __convert_bitfield(key, l[1])
 
@@ -227,7 +240,10 @@ def __transform_entry(entry, objectClass):
     entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn])
     entry.insert(1, ["objectClass", ["top", objectClass]])
     entry.insert(2, ["cn", cn])
-    
+    entry.insert(2, ["objectGUID", str(uuid.uuid4())])
+    entry.insert(2, ["adminDescription", cn])
+    entry.insert(2, ["adminDisplayName", cn])
+
     for l in entry:
         key = l[0].lower()
 
@@ -240,7 +256,7 @@ def __parse_schema_file(filename, objectClass):
     """Load and transform a schema file."""
 
     out = []
-    
+
     f = open(filename, "rU")
     for entry in __read_raw_entries(f):
         out.append(__write_ldif_one(__transform_entry(entry, objectClass)))
@@ -253,7 +269,7 @@ def read_ms_schema(attr_file, classes_file, dump_attributes = True, dump_classes
 
     attr_ldif = ""
     classes_ldif = ""
-    
+
     if dump_attributes:
         attr_ldif =  __parse_schema_file(attr_file, "attributeSchema")
     if dump_classes:
@@ -270,7 +286,5 @@ if __name__ == '__main__':
     except IndexError:
         print >>sys.stderr, "Usage: %s attr-file.txt classes-file.txt" % (sys.argv[0])
         sys.exit(1)
-        
-    print read_ms_schema(attr_file, classes_file)
 
-        
+    print read_ms_schema(attr_file, classes_file)