[SCM] Samba Shared Repository - branch master updated

Kamen Mazdrashki kamenim at samba.org
Wed Dec 1 05:31:01 MST 2010


The branch, master has been updated
       via  6803a72 s4-test/schema: Extend the test to replicate a Class with Attribute with "mayContain" relation
       via  23b4408 s4-dsdb/syntax: Map remote ATTIDs for Attribute OID syntax
       via  29f9249 s4-dsdb/syntax: Implement Remote-ATTID to Local-ATTID mapping function
       via  cf8ffc3 s4-dreplsrv: Use working_schema when replicating from Schema NC
       via  a42e267 s4-dsdb/schema: Implement multi-pass working schema creation function
       via  fcc26c5 s4-dsdb/schema: Add Schema shallow copy function
       via  16bd9dd s4-dsdb/prefixMap: Add prefixMap shallow copy function
       via  4041791 s4-repl: Let dsdb_replicated_objects_convert() to accept schema from caller
      from  4cd16dd s4-ranged_result.c: Fix memory context for ranged attributes handling

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


- Log -----------------------------------------------------------------
commit 6803a72d1595db6c25ff2a42f7ed5dd7a8be574f
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Nov 30 12:17:03 2010 +0200

    s4-test/schema: Extend the test to replicate a Class with Attribute with "mayContain" relation
    
    Autobuild-User: Kamen Mazdrashki <kamenim at samba.org>
    Autobuild-Date: Wed Dec  1 13:30:45 CET 2010 on sn-devel-104

commit 23b4408a6210363a11c4df12b6b737f94026d20d
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Nov 30 12:15:53 2010 +0200

    s4-dsdb/syntax: Map remote ATTIDs for Attribute OID syntax

commit 29f9249bd64a1873149e3857483c64b897deac13
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Nov 30 12:13:16 2010 +0200

    s4-dsdb/syntax: Implement Remote-ATTID to Local-ATTID mapping function

commit cf8ffc37b42b9b880ba1a0058bd5d0ab984f82b6
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Nov 30 01:38:16 2010 +0200

    s4-dreplsrv: Use working_schema when replicating from Schema NC
    
    Schema is changed and it is quite possible we won't be able
    to decode replicated objects using current Schema cache we have.
    
    Thus, when replicating Schema, we will make a temporary Schema
    cache, working_schema, so that we can fully decode objects
    we recieve.

commit a42e267105544e63ae28a3c40d96c0ff36b2d070
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Mon Nov 29 14:00:42 2010 +0200

    s4-dsdb/schema: Implement multi-pass working schema creation function
    
    It is heavily based on implementation in libnet_vampire_cb_apply_schema()
    function, except that it actually creates a new copy of the supplied
    initial_schema + resolving all incoming objects and add them to
    supplied initial_schema.
    
    We are going to need this 'working_schema' later so we are able
    to fully resolve all objects we receive on wire during DRS replication.
    
    Working schema created is to be used only as an index to search in.
    It is not supposed to be set to an ldb_context as it doesn't
    contain all information for classSchema and attributeSchema objects.

commit fcc26c5d59b1f7519a9a813fd70d1139c9f6976c
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Mon Nov 29 13:28:33 2010 +0200

    s4-dsdb/schema: Add Schema shallow copy function

commit 16bd9dd7aef2e92771cffc7be55d4f35687c0e64
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Mon Nov 29 13:28:00 2010 +0200

    s4-dsdb/prefixMap: Add prefixMap shallow copy function

commit 4041791d01b10b250dab5b356f0477fb8a40907e
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Fri Nov 26 02:38:39 2010 +0200

    s4-repl: Let dsdb_replicated_objects_convert() to accept schema from caller
    
    This allows us to use schema that is different than the one
    set to 'ldb' to decode objects.

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

Summary of changes:
 source4/dsdb/repl/drepl_out_helpers.c     |   30 ++++++
 source4/dsdb/repl/replicated_objects.c    |  145 +++++++++++++++++++++++++++--
 source4/dsdb/schema/schema_init.c         |   57 +++++++++++
 source4/dsdb/schema/schema_prefixmap.c    |   17 ++++
 source4/dsdb/schema/schema_syntax.c       |   41 ++++++++
 source4/libnet/libnet_vampire.c           |    9 ++
 source4/torture/drs/python/repl_schema.py |   12 ++-
 source4/torture/drs/rpc/dssync.c          |    1 +
 8 files changed, 303 insertions(+), 9 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index 2cbf008..f02fae9 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -541,6 +541,8 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
 	struct dreplsrv_service *service = state->op->service;
 	struct dreplsrv_partition *partition = state->op->source_dsa->partition;
 	struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
+	struct dsdb_schema *schema;
+	struct dsdb_schema *working_schema;
 	const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
 	uint32_t object_count;
 	struct drsuapi_DsReplicaObjectListItemEx *first_object;
@@ -579,7 +581,35 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
 		return;
 	}
 
+	schema = dsdb_get_schema(service->samdb, NULL);
+	if (!schema) {
+		DEBUG(0,(__location__ ": Schema is not loaded yet!\n"));
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
+	/* Decide what working schema to use for object conversion */
+	if (ldb_dn_compare(partition->dn, ldb_get_schema_basedn(service->samdb)) == 0) {
+		/* create working schema to convert objects with */
+		status = dsdb_repl_make_working_schema(service->samdb,
+						       schema,
+						       mapping_ctr,
+						       object_count,
+						       first_object,
+						       &drsuapi->gensec_skey,
+						       state, &working_schema);
+		if (!W_ERROR_IS_OK(status)) {
+			DEBUG(0,("Failed to create working schema: %s",
+				 win_errstr(status)));
+			tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+			return;
+		}
+	} else {
+		working_schema = schema;
+	}
+
 	status = dsdb_replicated_objects_convert(service->samdb,
+						 working_schema,
 						 partition->nc.dn,
 						 mapping_ctr,
 						 object_count,
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index 5824334..0965538 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -31,6 +31,138 @@
 #include "libcli/auth/libcli_auth.h"
 #include "param/param.h"
 
+/**
+ * Multi-pass working schema creation
+ * Function will:
+ *  - shallow copy initial schema supplied
+ *  - create a working schema in multiple passes
+ *    until all objects are resolved
+ * Working schema is a schema with Attributes, Classes
+ * and indexes, but w/o subClassOf, possibleSupperiors etc.
+ * It is to be used just us cache for converting attribute values.
+ */
+WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
+				     const struct dsdb_schema *initial_schema,
+				     const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
+				     uint32_t object_count,
+				     const struct drsuapi_DsReplicaObjectListItemEx *first_object,
+				     const DATA_BLOB *gensec_skey,
+				     TALLOC_CTX *mem_ctx,
+				     struct dsdb_schema **_schema_out)
+{
+	struct schema_list {
+		struct schema_list *next, *prev;
+		const struct drsuapi_DsReplicaObjectListItemEx *obj;
+	};
+
+	WERROR werr;
+	struct dsdb_schema_prefixmap *pfm_remote;
+	struct schema_list *schema_list = NULL, *schema_list_item, *schema_list_next_item;
+	struct dsdb_schema *working_schema;
+	const struct drsuapi_DsReplicaObjectListItemEx *cur;
+	int ret, pass_no;
+
+	/* make a copy of the iniatial_scheam so we don't mess with it */
+	working_schema = dsdb_schema_copy_shallow(mem_ctx, ldb, initial_schema);
+	if (!working_schema) {
+		DEBUG(0,(__location__ ": schema copy failed!\n"));
+		return WERR_NOMEM;
+	}
+
+	/* we are going to need remote prefixMap for decoding */
+	werr = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true,
+						mem_ctx, &pfm_remote, NULL);
+	if (!W_ERROR_IS_OK(werr)) {
+		DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s",
+			 win_errstr(werr)));
+		return werr;
+	}
+
+	/* create a list of objects yet to be converted */
+	for (cur = first_object; cur; cur = cur->next_object) {
+		schema_list_item = talloc(mem_ctx, struct schema_list);
+		schema_list_item->obj = cur;
+		DLIST_ADD_END(schema_list, schema_list_item, struct schema_list);
+	}
+
+	/* resolve objects until all are resolved and in local schema */
+	pass_no = 1;
+
+	while (schema_list) {
+		uint32_t converted_obj_count = 0;
+		uint32_t failed_obj_count = 0;
+		TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+		W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+
+		for (schema_list_item = schema_list; schema_list_item; schema_list_item=schema_list_next_item) {
+			struct dsdb_extended_replicated_object object;
+
+			cur = schema_list_item->obj;
+
+			/* Save the next item, now we have saved out
+			 * the current one, so we can DLIST_REMOVE it
+			 * safely */
+			schema_list_next_item = schema_list_item->next;
+
+			/*
+			 * Convert the objects into LDB messages using the
+			 * schema we have so far. It's ok if we fail to convert
+			 * an object. We should convert more objects on next pass.
+			 */
+			werr = dsdb_convert_object_ex(ldb, working_schema, pfm_remote,
+						      cur, gensec_skey,
+						      tmp_ctx, &object);
+			if (!W_ERROR_IS_OK(werr)) {
+				DEBUG(1,("Warning: Failed to convert schema object %s into ldb msg\n",
+					 cur->object.identifier->dn));
+
+				failed_obj_count++;
+			} else {
+				/*
+				 * Convert the schema from ldb_message format
+				 * (OIDs as OID strings) into schema, using
+				 * the remote prefixMap
+				 */
+				werr = dsdb_schema_set_el_from_ldb_msg(ldb,
+								       working_schema,
+								       object.msg);
+				if (!W_ERROR_IS_OK(werr)) {
+					DEBUG(1,("Warning: failed to convert object %s into a schema element: %s\n",
+						 ldb_dn_get_linearized(object.msg->dn),
+						 win_errstr(werr)));
+					failed_obj_count++;
+				} else {
+					DLIST_REMOVE(schema_list, schema_list_item);
+					talloc_free(schema_list_item);
+					converted_obj_count++;
+				}
+			}
+		}
+		talloc_free(tmp_ctx);
+
+		DEBUG(4,("Schema load pass %d: %d/%d of %d objects left to be converted.\n",
+			 pass_no, failed_obj_count, converted_obj_count, object_count));
+		pass_no++;
+
+		/* check if we converted any objects in this pass */
+		if (converted_obj_count == 0) {
+			DEBUG(0,("Can't continue Schema load: didn't manage to convert any objects: all %d remaining of %d objects failed to convert\n", failed_obj_count, object_count));
+			return WERR_INTERNAL_ERROR;
+		}
+
+		/* rebuild indexes */
+		ret = dsdb_setup_sorted_accessors(ldb, working_schema);
+		if (LDB_SUCCESS != ret) {
+			DEBUG(0,("Failed to create schema-cache indexes!\n"));
+			return WERR_INTERNAL_ERROR;
+		}
+	};
+
+	*_schema_out = working_schema;
+
+	return WERR_OK;
+}
+
 WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
 			      const struct dsdb_schema *schema,
 			      const struct dsdb_schema_prefixmap *pfm_remote,
@@ -199,6 +331,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
 }
 
 WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb,
+				       const struct dsdb_schema *schema,
 				       const char *partition_dn_str,
 				       const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
 				       uint32_t object_count,
@@ -213,7 +346,6 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb,
 {
 	WERROR status;
 	struct ldb_dn *partition_dn;
-	const struct dsdb_schema *schema;
 	struct dsdb_schema_prefixmap *pfm_remote;
 	struct dsdb_extended_replicated_objects *out;
 	const struct drsuapi_DsReplicaObjectListItemEx *cur;
@@ -223,12 +355,11 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb,
 	W_ERROR_HAVE_NO_MEMORY(out);
 	out->version		= DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION;
 
-	/* Get the schema, and ensure it's kept valid for as long as 'out' which may contain pointers to it */
-	schema = dsdb_get_schema(ldb, out);
-	if (!schema) {
-		talloc_free(out);
-		return WERR_DS_SCHEMA_NOT_LOADED;
-	}
+	/*
+	 * Ensure schema is kept valid for as long as 'out'
+	 * which may contain pointers to it
+	 */
+	talloc_reference(out, schema);
 
 	partition_dn = ldb_dn_new(out, ldb, partition_dn_str);
 	W_ERROR_HAVE_NO_MEMORY_AND_FREE(partition_dn, out);
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index bcb51f6..977941e 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -43,6 +43,63 @@ struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx)
 	return schema;
 }
 
+struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx,
+					     struct ldb_context *ldb,
+					     const struct dsdb_schema *schema)
+{
+	int ret;
+	struct dsdb_class *cls;
+	struct dsdb_attribute *attr;
+	struct dsdb_schema *schema_copy;
+
+	schema_copy = dsdb_new_schema(mem_ctx);
+	if (!schema_copy) {
+		return NULL;
+	}
+
+	/* copy prexiMap & schemaInfo */
+	schema_copy->prefixmap = dsdb_schema_pfm_copy_shallow(schema_copy,
+							      schema->prefixmap);
+	if (!schema_copy->prefixmap) {
+		return NULL;
+	}
+
+	schema_copy->schema_info = talloc_strdup(schema_copy, schema->schema_info);
+
+	/* copy classes and attributes*/
+	for (cls = schema->classes; cls; cls = cls->next) {
+		struct dsdb_class *class_copy = talloc_memdup(schema_copy,
+							      cls, sizeof(*cls));
+		if (!class_copy) {
+			goto failed;
+		}
+		DLIST_ADD(schema_copy->classes, class_copy);
+	}
+	schema_copy->num_classes = schema->num_classes;
+
+	for (attr = schema->attributes; attr; attr = attr->next) {
+		struct dsdb_attribute *a_copy = talloc_memdup(schema_copy,
+							      attr, sizeof(*attr));
+		if (!a_copy) {
+			goto failed;
+		}
+		DLIST_ADD(schema_copy->attributes, a_copy);
+	}
+	schema_copy->num_attributes = schema->num_attributes;
+
+	/* rebuild indexes */
+	ret = dsdb_setup_sorted_accessors(ldb, schema_copy);
+	if (ret != LDB_SUCCESS) {
+		goto failed;
+	}
+
+	return schema_copy;
+
+failed:
+	talloc_free(schema_copy);
+	return NULL;
+}
+
 
 WERROR dsdb_load_prefixmap_from_drsuapi(struct dsdb_schema *schema,
 					const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
diff --git a/source4/dsdb/schema/schema_prefixmap.c b/source4/dsdb/schema/schema_prefixmap.c
index 18b22ff..f900f40 100644
--- a/source4/dsdb/schema/schema_prefixmap.c
+++ b/source4/dsdb/schema/schema_prefixmap.c
@@ -121,6 +121,23 @@ WERROR dsdb_schema_pfm_new(TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_
 }
 
 
+struct dsdb_schema_prefixmap *dsdb_schema_pfm_copy_shallow(TALLOC_CTX *mem_ctx,
+							   const struct dsdb_schema_prefixmap *pfm)
+{
+	uint32_t i;
+	struct dsdb_schema_prefixmap *pfm_copy;
+
+	pfm_copy = _dsdb_schema_prefixmap_talloc(mem_ctx, pfm->length);
+	if (!pfm_copy) {
+		return NULL;
+	}
+	for (i = 0; i < pfm_copy->length; i++) {
+		pfm_copy->prefixes[i] = pfm->prefixes[i];
+	}
+
+	return pfm_copy;
+}
+
 /**
  * Adds oid to prefix map.
  * On success returns ID for newly added index
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index 0d1d274..ab37f66 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -70,6 +70,41 @@ uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr,
 	return attr->attributeID_id;
 }
 
+/**
+ * Map an ATTID from remote DC to a local ATTID
+ * using remote prefixMap
+ */
+static bool dsdb_syntax_attid_from_remote_attid(const struct dsdb_syntax_ctx *ctx,
+						TALLOC_CTX *mem_ctx,
+						uint32_t id_remote,
+						uint32_t *id_local)
+{
+	WERROR werr;
+	const char *oid;
+
+	/*
+	 * map remote ATTID to local directly in case
+	 * of no remote prefixMap (during provision for instance)
+	 */
+	if (!ctx->pfm_remote) {
+		*id_local = id_remote;
+		return true;
+	}
+
+	werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, id_remote, mem_ctx, &oid);
+	if (!W_ERROR_IS_OK(werr)) {
+		DEBUG(0,("ATTID->OID failed (%s) for: 0x%08X\n", win_errstr(werr), id_remote));
+		return false;
+	}
+
+	werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap, oid, id_local);
+	if (!W_ERROR_IS_OK(werr)) {
+		DEBUG(0,("OID->ATTID failed (%s) for: %s\n", win_errstr(werr), oid));
+		return false;
+	}
+
+	return true;
+}
 
 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
 						const struct dsdb_attribute *attr,
@@ -995,6 +1030,12 @@ static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx
 
 		v = IVAL(in->value_ctr.values[i].blob->data, 0);
 
+		/* convert remote ATTID to local ATTID */
+		if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
+			DEBUG(0,(__location__ "Failed to map remote ATTID to local ATTID!\n"));
+			return WERR_FOOBAR;
+		}
+
 		a = dsdb_attribute_by_attributeID_id(ctx->schema, v);
 		if (!a) {
 			return WERR_FOOBAR;
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index 164dcde..1d7d726 100644
--- a/source4/libnet/libnet_vampire.c
+++ b/source4/libnet/libnet_vampire.c
@@ -419,6 +419,7 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
 
 	/* Now convert the schema elements again, using the schema we finalised, ready to actually import */
 	status = dsdb_replicated_objects_convert(s->ldb,
+						 s->schema,
 						 c->partition->nc.dn,
 						 mapping_ctr,
 						 object_count,
@@ -606,6 +607,7 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data,
 {
 	struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state);
 	WERROR status;
+	struct dsdb_schema *schema;
 	const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
 	uint32_t nc_object_count;
 	uint32_t object_count;
@@ -685,7 +687,14 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data,
 	}
 
 
+	schema = dsdb_get_schema(s->ldb, NULL);
+	if (!schema) {
+		DEBUG(0,(__location__ ": Schema is not loaded yet!\n"));
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
 	status = dsdb_replicated_objects_convert(s->ldb,
+						 schema,
 						 c->partition->nc.dn,
 						 mapping_ctr,
 						 object_count,
diff --git a/source4/torture/drs/python/repl_schema.py b/source4/torture/drs/python/repl_schema.py
index 55e653b..02e2afe 100644
--- a/source4/torture/drs/python/repl_schema.py
+++ b/source4/torture/drs/python/repl_schema.py
@@ -41,6 +41,7 @@ from ldb import (
     LdbError,
     SCOPE_BASE,
     Message,
+    FLAG_MOD_ADD,
     FLAG_MOD_REPLACE,
     )
 
@@ -176,10 +177,17 @@ class DrsReplSchemaTestCase(samba.tests.TestCase):
            and attributeSchema objects, replicate Schema NC
            and then check all objects are replicated correctly"""
 
-        # add new attributeSchema object
-        (a_ldn, a_dn) = self._schema_new_attr(self.ldb_dc1, "attr-A")
         # add new classSchema object
         (c_ldn, c_dn) = self._schema_new_class(self.ldb_dc1, "cls-A")
+        # add new attributeSchema object
+        (a_ldn, a_dn) = self._schema_new_attr(self.ldb_dc1, "attr-A")
+
+        # add attribute to the class we have
+        m = Message.from_dict(self.ldb_dc1,
+                              {"dn": c_dn,
+                               "mayContain": a_ldn},
+                              FLAG_MOD_ADD)
+        self.ldb_dc1.modify(m)
 
         # force replication from DC1 to DC2
         self._net_drs_replicate(DC=self.dnsname_dc2, fromDC=self.dnsname_dc1, nc_dn=self.schema_dn)
diff --git a/source4/torture/drs/rpc/dssync.c b/source4/torture/drs/rpc/dssync.c
index 9c65b91..cd9a733 100644
--- a/source4/torture/drs/rpc/dssync.c
+++ b/source4/torture/drs/rpc/dssync.c
@@ -341,6 +341,7 @@ static bool test_analyse_objects(struct torture_context *tctx,
 	ldap_schema = dsdb_get_schema(ldb, NULL);
 
 	status = dsdb_replicated_objects_convert(ldb,
+						 ldap_schema,
 						 partition,
 						 mapping_ctr,
 						 object_count,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list