[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-598-gf696bb8

Andrew Bartlett abartlet at samba.org
Fri Mar 20 05:29:05 GMT 2009


The branch, master has been updated
       via  f696bb81f8499443eee9815e7adf8dbb6810506a (commit)
       via  653dd024a630af095277f5884add9246da399eb9 (commit)
       via  5bfed623f5115a774f47e1cdceed862c53cd40a1 (commit)
       via  6906c01cac226db508cd56a31b751eee3ac62bc9 (commit)
       via  1dc5b90e86fdee2978f5608f483c3b11c86fb9bc (commit)
      from  5fe2b28f45289dc5578cdd536600f0d30a14d820 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f696bb81f8499443eee9815e7adf8dbb6810506a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 20 16:18:40 2009 +1100

    s4: Remove autogenerated attributes from minschema and fullschema output
    
    These attributes will be generated by Samba on import, and do not need
    to be in the schema file.
    
    Andrew Bartlett

commit 653dd024a630af095277f5884add9246da399eb9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 20 16:07:49 2009 +1100

    Add minschema like tool to extract and dump the full schema from AD

commit 5bfed623f5115a774f47e1cdceed862c53cd40a1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 20 13:55:43 2009 +1100

    s4:minschma Fix aggregate schema generation in minschema
    
    The conversion from EJS to python I did with Jelmer this morning was
    not quite complete, due mostly to the difference between print in EJS
    and python (python implies a newline).
    
    Andrew Bartlett

commit 6906c01cac226db508cd56a31b751eee3ac62bc9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 20 16:25:01 2009 +1100

    s4:ldb Ensure to pass down options to LDB from python
    
    This is needed for things such as to load modules, like the
    paged_searches module.
    
    Andrew Bartlett

commit 1dc5b90e86fdee2978f5608f483c3b11c86fb9bc
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 20 16:26:42 2009 +1100

    s4:ldb Fix the paged_searches module
    
    This simplifies the code, removes presumptions about being the only
    control in the reply, and allows it to function against Windows 2008.
    
    For searches which did not require a paged result, the module was
    simply returning a failure when the compleated search did not include
    a paged result control.
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 source4/lib/ldb/modules/paged_searches.c   |  109 ++++++++---------
 source4/scripting/bin/fullschema           |  177 ++++++++++++++++++++++++++++
 source4/scripting/bin/minschema            |   49 ++++----
 source4/scripting/python/samba/__init__.py |    6 +-
 4 files changed, 254 insertions(+), 87 deletions(-)
 create mode 100644 source4/scripting/bin/fullschema


Changeset truncated at 500 lines:

diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c
index 01e77cb..70b880e 100644
--- a/source4/lib/ldb/modules/paged_searches.c
+++ b/source4/lib/ldb/modules/paged_searches.c
@@ -2,6 +2,7 @@
    ldb database library
 
    Copyright (C) Simo Sorce  2005-2008
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2009
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -52,23 +53,40 @@ struct ps_context {
 
 	char **saved_referrals;
 	int num_referrals;
+
+	struct ldb_request *down_req;
 };
 
-static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares)
+static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares)
 {
-	struct ps_context *ac;
-	struct ldb_paged_control *rep_control, *req_control;
+	struct ldb_context *ldb;
+	struct ldb_control *rep_control, *req_control;
+	struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL;
+	ldb = ldb_module_get_ctx(ac->module);
 
-	ac = talloc_get_type(req->context, struct ps_context);
+	rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID);
+	if (rep_control) {
+		paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control);
+	}
 
-	/* look up our paged control */
-	if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) {
-		/* something wrong here */
-		return LDB_ERR_OPERATIONS_ERROR;
+	req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID);
+	paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control);
+
+	if (!rep_control || !paged_rep_control) {
+		if (paged_req_control->cookie) {
+			/* something wrong here - why give us a control back befre, but not one now? */
+			ldb_set_errstring(ldb, "paged_searches:  ERROR: We got back a control from a previous page, but this time no control was returned!");
+			return LDB_ERR_OPERATIONS_ERROR;
+		} else {
+			/* No cookie recived yet, valid to just return the full data set */
+
+			/* we are done */
+			ac->pending = false;
+			return LDB_SUCCESS;
+		}
 	}
 
-	rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control);
-	if (rep_control->cookie_len == 0) {
+	if (paged_rep_control->cookie_len == 0) {
 		/* we are done */
 		ac->pending = false;
 		return LDB_SUCCESS;
@@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares
 	/* if there's a reply control we must find a request
 	 * control matching it */
 
-	if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) {
-		/* something wrong here */
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control);
-
-	if (req_control->cookie) {
-		talloc_free(req_control->cookie);
+	if (paged_req_control->cookie) {
+		talloc_free(paged_req_control->cookie);
 	}
 
-	req_control->cookie = talloc_memdup(req_control,
-					    rep_control->cookie,
-					    rep_control->cookie_len);
-	req_control->cookie_len = rep_control->cookie_len;
+	paged_req_control->cookie = talloc_memdup(req_control,
+						  paged_rep_control->cookie,
+						  paged_rep_control->cookie_len);
+	paged_req_control->cookie_len = paged_rep_control->cookie_len;
 
 	ac->pending = true;
 	return LDB_SUCCESS;
@@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac)
 	return LDB_SUCCESS;
 }
 
-static int ps_next_request(struct ps_context *ac);
-
 static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
 	struct ps_context *ac;
@@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
 
 	case LDB_REPLY_DONE:
 
-		ret = check_ps_continuation(req, ares);
+		ret = check_ps_continuation(ac, req, ares);
 		if (ret != LDB_SUCCESS) {
 			return ldb_module_done(ac->req, NULL, NULL, ret);
 		}
 
 		if (ac->pending) {
 
-			ret = ps_next_request(ac);
+			ret = ldb_next_request(ac->module, ac->down_req);
+
 			if (ret != LDB_SUCCESS) {
 				return ldb_module_done(ac->req,
 							NULL, NULL, ret);
@@ -214,6 +224,8 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
 	struct ldb_context *ldb;
 	struct private_data *private_data;
 	struct ps_context *ac;
+	struct ldb_paged_control *control;
+	int ret;
 
 	private_data = talloc_get_type(ldb_module_get_private(module), struct private_data);
 	ldb = ldb_module_get_ctx(module);
@@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
 	ac->saved_referrals = NULL;
 	ac->num_referrals = 0;
 
-	return ps_next_request(ac);
-}
-
-static int ps_next_request(struct ps_context *ac) {
-
-	struct ldb_context *ldb;
-	struct ldb_paged_control *control;
-	struct ldb_control **controls;
-	struct ldb_request *new_req;
-	int ret;
-
 	ldb = ldb_module_get_ctx(ac->module);
 
-	controls = talloc_array(ac, struct ldb_control *, 2);
-	if (!controls) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	controls[0] = talloc(controls, struct ldb_control);
-	if (!controls[0]) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	control = talloc(controls[0], struct ldb_paged_control);
+	control = talloc(ac, struct ldb_paged_control);
 	if (!control) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
@@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) {
 	control->cookie = NULL;
 	control->cookie_len = 0;
 
-	controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
-	controls[0]->critical = 1;
-	controls[0]->data = control;
-	controls[1] = NULL;
-
-	ret = ldb_build_search_req_ex(&new_req, ldb, ac,
+	ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac,
 					ac->req->op.search.base,
 					ac->req->op.search.scope,
 					ac->req->op.search.tree,
 					ac->req->op.search.attrs,
-					controls,
+					ac->req->controls,
 					ac,
 					ps_callback,
 					ac->req);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
-	talloc_steal(new_req, controls);
 
-	return ldb_next_request(ac->module, new_req);
+	ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID,
+				      true, control);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	talloc_steal(ac->down_req, control);
+
+	return ldb_next_request(ac->module, ac->down_req);
 }
 
 static int check_supported_paged(struct ldb_request *req,
diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema
new file mode 100644
index 0000000..d3bf398
--- /dev/null
+++ b/source4/scripting/bin/fullschema
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+# 
+#  work out the minimal schema for a set of objectclasses 
+#
+
+import base64
+import optparse
+import os
+import sys
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba import getopt as options, Ldb
+from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError
+import sys
+
+parser = optparse.OptionParser("fullschema <URL>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--dump-classes", action="store_true")
+parser.add_option("--dump-attributes", action="store_true")
+
+opts, args = parser.parse_args()
+opts.dump_all = True
+
+if opts.dump_classes:
+    opts.dump_all = False
+if opts.dump_attributes:
+    opts.dump_all = False
+if opts.dump_all:
+    opts.dump_classes = True
+    opts.dump_attributes = True
+
+if len(args) != 1:
+    parser.print_usage()
+    sys.exit(1)
+
+url = args[0]
+
+lp_ctx = sambaopts.get_loadparm()
+
+creds = credopts.get_credentials(lp_ctx)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
+
+# the attributes we need for objectclasses
+class_attrs = ["objectClass", 
+               "cn",
+               "subClassOf", 
+               "governsID", 
+               "possSuperiors", 
+               "possibleInferiors",
+               "mayContain",
+               "mustContain",
+               "auxiliaryClass",
+               "rDNAttID",
+               "adminDisplayName",
+               "adminDescription",
+               "objectClassCategory",
+               "lDAPDisplayName",
+               "schemaIDGUID",
+               "systemOnly",
+               "systemPossSuperiors",
+               "systemMayContain",
+               "systemMustContain",
+               "systemAuxiliaryClass",
+               "defaultSecurityDescriptor",
+               "systemFlags",
+               "defaultHidingValue",
+               "defaultObjectCategory", 
+               
+               # this attributes are not used by w2k3
+               "schemaFlagsEx",
+               "msDs-IntId",
+               "msDs-Schema-Extensions",
+               "classDisplayName",
+               "isDefunct"]
+
+attrib_attrs = ["objectClass",
+                "cn",
+                "attributeID", 
+                "attributeSyntax",
+                "isSingleValued",
+                "rangeLower",
+                "rangeUpper",
+                "mAPIID",
+                "linkID",
+                "adminDisplayName",
+                "oMObjectClass",
+                "adminDescription",
+                "oMSyntax", 
+                "searchFlags",
+                "extendedCharsAllowed",
+                "lDAPDisplayName",
+                "schemaIDGUID",
+                "attributeSecurityGUID",
+                "systemOnly",
+                "systemFlags",
+                "isMemberOfPartialAttributeSet",
+                
+                # this attributes are not used by w2k3
+                "schemaFlagsEx",
+                "msDs-IntId",
+                "msDs-Schema-Extensions",
+                "classDisplayName",
+                "isEphemeral",
+                "isDefunct"]
+
+class Objectclass(dict):
+
+    def __init__(self, ldb, name):
+        """create an objectclass object"""
+        self.name = name
+
+
+class Attribute(dict):
+
+    def __init__(self, ldb, name):
+        """create an attribute object"""
+        self.name = name
+        self["cn"] = get_object_cn(ldb, name)
+
+
+
+def fix_dn(dn):
+    """fix a string DN to use ${SCHEMADN}"""
+    return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
+
+
+def write_ldif_one(o, attrs):
+    """dump an object as ldif"""
+    print "dn: CN=%s,${SCHEMADN}" % o["cn"]
+    for a in attrs:
+        if not o.has_key(a):
+            continue
+        # special case for oMObjectClass, which is a binary object
+        v = o[a]
+        for j in v:
+            value = fix_dn(j)
+            if a != "cn":
+                if a == "oMObjectClass":
+                    print "%s:: %s" % (a, base64.b64encode(value))
+                elif a.endswith("GUID"):
+                    print "%s: %s" % (a, ldb.schema_format_value(a, value))
+                else:
+                    print "%s: %s" % (a, value)
+    print ""
+
+
+# get the rootDSE
+res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
+rootDse = res[0]
+
+if opts.dump_attributes:
+    res = ldb.search(expression="objectClass=attributeSchema", 
+                     base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs)
+    
+    for msg in res:
+        o = Objectclass(ldb, msg["ldapDisplayName"])
+        for a in msg:
+            o[a] = msg[a]
+        write_ldif_one(o, attrib_attrs)
+            
+if opts.dump_classes:
+    res = ldb.search(expression="objectClass=classSchema", 
+                     base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs)
+
+    for msg in res:
+        o = Objectclass(ldb, msg["ldapDisplayName"])
+        for a in msg:
+            o[a] = msg[a]
+        write_ldif_one(o, class_attrs)
+
diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema
index f2dfdcb..c860495 100755
--- a/source4/scripting/bin/minschema
+++ b/source4/scripting/bin/minschema
@@ -72,7 +72,6 @@ class_attrs = ["objectClass",
                "mustContain",
                "auxiliaryClass",
                "rDNAttID",
-               "showInAdvancedViewOnly",
                "adminDisplayName",
                "adminDescription",
                "objectClassCategory",
@@ -104,7 +103,6 @@ attrib_attrs = ["objectClass",
                 "rangeUpper",
                 "mAPIID",
                 "linkID",
-                "showInAdvancedViewOnly",
                 "adminDisplayName",
                 "oMObjectClass",
                 "adminDescription",
@@ -405,40 +403,40 @@ def attribute_list(objectclass, attr1, attr2):
 
 def aggregate_list(name, list):
     """write out a list in aggregate form"""
-    if list is None:
-        return
-    print "%s ( %s )" % (name, "$ ".join(list))
+    if list == []:
+        return ""
+    return " %s ( %s )" % (name, " $ ".join(list))
 
 def write_aggregate_objectclass(objectclass):
     """write the aggregate record for an objectclass"""
-    print "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name),
+    line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
     if not objectclass.has_key('subClassOf'):
-        print "SUP %s " % objectclass['subClassOf'],
+        line += "SUP %s" % objectclass['subClassOf']
     if objectclass["objectClassCategory"] == 1:
-        print "STRUCTURAL ",
+        line += "STRUCTURAL"
     elif objectclass["objectClassCategory"] == 2:
-        print "ABSTRACT ",
+        line += "ABSTRACT"
     elif objectclass["objectClassCategory"] == 3:
-        print "AUXILIARY ",
+        line += "AUXILIARY"
 
     list = attribute_list(objectclass, "systemMustContain", "mustContain")
-    aggregate_list("MUST", list)
+    line += aggregate_list("MUST", list)
 
     list = attribute_list(objectclass, "systemMayContain", "mayContain")
-    aggregate_list("MAY", list)
+    line += aggregate_list("MAY", list)
 
-    print ")"
+    print line + " )"
 
 
 def write_aggregate_ditcontentrule(objectclass):
     """write the aggregate record for an ditcontentrule"""
     list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass")
-    if list is None:
+    if list == []:
         return
 
-    print "dITContentRules: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
+    line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name)
 
-    aggregate_list("AUX", list)
+    line += aggregate_list("AUX", list)
 
     may_list = []
     must_list = []
@@ -451,31 +449,30 @@ def write_aggregate_ditcontentrule(objectclass):
                        "mustContain", "systemMustContain")
         must_list = must_list + list2
 
-    aggregate_list("MUST", must_list)
-    aggregate_list("MAY", may_list)
+    line += aggregate_list("MUST", must_list)
+    line += aggregate_list("MAY", may_list)
 
-    print ")\n"
+    print line + " )"
 
 def write_aggregate_attribute(attrib):
     """write the aggregate record for an attribute"""
-    print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
+    line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
            attrib["attributeID"], attrib.name, 
            map_attribute_syntax(attrib["attributeSyntax"]))
     if attrib.get('isSingleValued') == "TRUE":
-        print "SINGLE-VALUE "
+        line += "SINGLE-VALUE "
     if attrib.get('systemOnly') == "TRUE":
-        print "NO-USER-MODIFICATION "
+        line += "NO-USER-MODIFICATION "
 
-    print ")\n"
+    print line + ")"
 
 
 def write_aggregate():
     """write the aggregate record"""
-    print "dn: CN=Aggregate,${SCHEMADN}\n"
+    print "dn: CN=Aggregate,${SCHEMADN}"
     print """objectClass: top
 objectClass: subSchema
-objectCategory: CN=SubSchema,${SCHEMADN}
-"""
+objectCategory: CN=SubSchema,${SCHEMADN}"""
     if not opts.dump_subschema_auto:
         return
 
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index a49e6e1..c5827b9 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py


-- 
Samba Shared Repository


More information about the samba-cvs mailing list