[SCM] Samba Shared Repository - branch master updated

Matthieu Patou mat at samba.org
Sat Jun 23 02:49:02 MDT 2012


The branch, master has been updated
       via  763f9e8 selftest: schema is not automatically reloaded now so if you modify it you have to reload it
       via  c00485b s4-dsdb: operational handle modifyTimeStamp on the CN=aggregate DN
       via  2f3adc0 s4-schema: improve the documentation of the dsdb_schema structure
       via  718ed84 s4-dsdb: Check for key SCHEMA_SEQ_NUM in metadata.tdb updates
       via  6f3a8b4 s4-dsdb: Add/Update SCHEMA_SEQ_NUM key in the metadata.tdb after schemaUpdateNow
       via  9f1213d s4-drs: if schema has changed during replication notify other process that they have to reload the schema
       via  f2deb05 s4-dsdb: move schema_load at the top of module stack
       via  283af38 s4-extended: do not try to fix if there is no schema
       via  9374ee1 s4-schema: keep track of the timestamp of the most recently changed/created object
       via  2d20a91 s4-schema: generalized time use its own syntax now
       via  1c850b2 ldb: lay foundation for proper utc/generalized time handling
       via  884d66d s4-drsuapi: Fix a const warning
       via  392e83f s4-drsuapi: rework the crackname implementation of functionnal names
       via  f421aa8 s4-dsdb-linkedattributes: register the VERIFY_NAME control, handle it when we are a GC
       via  f110f2d s4-ldap: handle VERIFY_NAME control encoding/decoding
       via  9ebb081 ldb: add the VERIFY_NAME control
       via  d7aa7e8 s4-dsdb: support otherWellKnownObjects
       via  6edd940 s4-dsdb: Try to avoid much of the time a db search for msDS-IntID
       via  1521bb9 dsdb-schema: do not reload more often than schema_reload_interval
       via  f8fd615 s4-dsdb: fix a warning about unused variable
      from  8558e32 s3: Correct documentation of case sensitive

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


- Log -----------------------------------------------------------------
commit 763f9e82010e4ff1c74aea651e3244063bbf7fbf
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 12 12:23:52 2012 -0700

    selftest: schema is not automatically reloaded now so if you modify it you have to reload it
    
    Autobuild-User(master): Matthieu Patou <mat at samba.org>
    Autobuild-Date(master): Sat Jun 23 10:48:13 CEST 2012 on sn-devel-104

commit c00485b25888b06a71a79d7c7cbf43f5445d33e0
Author: Matthieu Patou <mat at matws.net>
Date:   Thu May 17 23:58:36 2012 -0700

    s4-dsdb: operational handle modifyTimeStamp on the CN=aggregate DN
    
    modifyTimeStamp is a generated attribute, for most object it's generated
    directly from the whenChanged attribute. But for the CN=aggregate object
    in the schema we have to handle it in a different way, that's because
    for this object whenChanged!=modifyTimeStamp (as checked against Windows
    2003R2 DCs) instead the modifyTimeStamp reflect the timestamp of the
    most recently modified and loaded schema object (that is to the one with
    the highest USN before the schema was reload due to timeout or by the
    reloadSchemaNow command).
    Some third party are using this information to know if they have to
    update their schema cache and also to check that schema updates have
    been correctly reloaded by the DC, a good example of this behavior is
    exchange 2010.

commit 2f3adc001eba8027fb7ae46e2c0fa7342c166d1a
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 10 22:44:12 2012 -0700

    s4-schema: improve the documentation of the dsdb_schema structure

commit 718ed842ba0b56ec2310feb415e83ce15284868f
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 22 15:13:04 2012 -0700

    s4-dsdb: Check for key SCHEMA_SEQ_NUM in metadata.tdb updates
    
    If the value has changed then reload the schema, this means that now the
    schema is only reloaded on a periodical basis or if we have been asked
    explicitly to do it and not necesserly if the schema partition has
    changed.

commit 6f3a8b41f5b43c35263a401b2bddbe4e49812b85
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 30 10:43:27 2012 -0700

    s4-dsdb: Add/Update SCHEMA_SEQ_NUM key in the metadata.tdb after schemaUpdateNow
    
    The idea is to signal to other process accessing the database that the
    schema was forced to be reloaded and so they should reload as well.

commit 9f1213d954c72a46ac1f30e936e4004b1ed9ff76
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 30 10:42:56 2012 -0700

    s4-drs: if schema has changed during replication notify other process that they have to reload the schema

commit f2deb05f77e21c5c9106dac32202d0b92eca3f96
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 30 10:41:56 2012 -0700

    s4-dsdb: move schema_load at the top of module stack

commit 283af3857c13501b91484d86127f82d3cbfa936a
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 30 10:57:06 2012 -0700

    s4-extended: do not try to fix if there is no schema

commit 9374ee1ba1dc1df3d5cdab1755ca9bfac338a4ae
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 22 16:25:50 2012 -0700

    s4-schema: keep track of the timestamp of the most recently changed/created object

commit 2d20a918db646e9e48f296a46f1d672563730e03
Author: Matthieu Patou <mat at matws.net>
Date:   Thu May 17 23:59:06 2012 -0700

    s4-schema: generalized time use its own syntax now

commit 1c850b2f173678b0df7a2619024baf2d94011a7b
Author: Matthieu Patou <mat at matws.net>
Date:   Thu May 17 23:57:55 2012 -0700

    ldb: lay foundation for proper utc/generalized time handling
    
    We use to handle UTCtime and generalized time the same way. The thing is
    that it's not the case, they are different in the way they are set (most
    of the time) with different format and also stored and return in
    different format too.

commit 884d66d959e2eaa384bf9af6230ffb589a581b13
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 16 23:52:51 2012 -0700

    s4-drsuapi: Fix a const warning

commit 392e83ffe6f9096c5671c2fd92a338f1fa5abd30
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 16 23:52:30 2012 -0700

    s4-drsuapi: rework the crackname implementation of functionnal names

commit f421aa821869dd138fafe63faf1534a72dabb60e
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 15 19:25:25 2012 -0700

    s4-dsdb-linkedattributes: register the VERIFY_NAME control, handle it when we are a GC
    
    In theory when presented this control and not a GC we should use the
    specified name as the DC to contact for cross-domain link verification.
    But for the moment we don't support this so we just fail when we have
    this control and are not a GC.

commit f110f2d63fc931deb7fa44fbfee7235a5cb2cf56
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 15 11:15:38 2012 -0700

    s4-ldap: handle VERIFY_NAME control encoding/decoding

commit 9ebb081ccec0587736920e85a9de624e079836e5
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 15 10:14:55 2012 -0700

    ldb: add the VERIFY_NAME control

commit d7aa7e8ef0db7da07785994e3be7c3cf00289f4d
Author: Matthieu Patou <mat at matws.net>
Date:   Mon May 14 20:16:11 2012 -0700

    s4-dsdb: support otherWellKnownObjects

commit 6edd940135d97e80d70e2b48d8019be5d3557f64
Author: Matthieu Patou <mat at matws.net>
Date:   Sat May 12 02:13:42 2012 -0700

    s4-dsdb: Try to avoid much of the time a db search for msDS-IntID
    
    We search in the schema if we have already this intid (using dsdb_attribute_by_attributeID_id because
    in the range 0x80000000 0xBFFFFFFFF, attributeID is a DSDB_ATTID_TYPE_INTID).
    If so generate another random value.
    If not check if the highest USN in the database for the schema partition is the
    one that we know.
    If so it means that's only this ldb context that is touching the schema in the database.
    If not it means that's someone else has modified the database while we are doing our changes too
    (this case should be very bery rare) in order to be sure do the search in the database.

commit 1521bb95a7bb3df5cb3a128085a088cb09555f8b
Author: Matthieu Patou <mat at matws.net>
Date:   Wed May 9 22:08:55 2012 -0700

    dsdb-schema: do not reload more often than schema_reload_interval
    
    Samba 4 use to try to reload the schema every time dsdb_get_schema was
    called (which could be 20+ time per ldb request). Now we only reload at
    most every xx seconds (xx being the value of dsdb:"schema_reload_interval"
     or 120). The timestamp of the last reloaded schema is kept in the
     dsdb_schema object. There is also a timestamp in the ldb_context, that
     is used by the LDAP server to know if it has to reload the schema after
     handling the request. This is used to allow that the schema will be
     immediately reload after a schemaUpdateNow request has been issued, the
     reload can't occur in the handling of the LDAP request itself because
     we have a transaction autostarted.

commit f8fd615c5950bab9a38cd31872ae447ffdc974f3
Author: Matthieu Patou <mat at matws.net>
Date:   Tue May 29 23:03:09 2012 -0700

    s4-dsdb: fix a warning about unused variable

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

Summary of changes:
 lib/ldb/common/attrib_handlers.c                   |   28 +++
 lib/ldb/common/ldb_controls.c                      |   53 +++++
 lib/ldb/common/ldb_msg.c                           |   18 +-
 lib/ldb/include/ldb.h                              |   16 ++
 source4/dsdb/repl/replicated_objects.c             |   55 +++++
 source4/dsdb/samdb/cracknames.c                    |  148 +++++++++++--
 source4/dsdb/samdb/ldb_modules/extended_dn_in.c    |   59 +++--
 source4/dsdb/samdb/ldb_modules/linked_attributes.c |  107 ++++++++-
 source4/dsdb/samdb/ldb_modules/operational.c       |   38 +++-
 source4/dsdb/samdb/ldb_modules/partition.c         |    7 +
 .../dsdb/samdb/ldb_modules/partition_metadata.c    |   32 +++
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |   20 ++-
 source4/dsdb/samdb/ldb_modules/samba_dsdb.c        |    2 +-
 source4/dsdb/samdb/ldb_modules/samldb.c            |   90 +++++++--
 source4/dsdb/samdb/ldb_modules/schema_load.c       |  231 +++++++++++++++++++-
 source4/dsdb/samdb/samdb.h                         |   10 +
 source4/dsdb/schema/schema.h                       |   13 +-
 source4/dsdb/schema/schema_init.c                  |    1 +
 source4/dsdb/schema/schema_set.c                   |   12 +-
 source4/dsdb/schema/schema_syntax.c                |    1 -
 source4/dsdb/tests/python/ldap_schema.py           |    9 +
 source4/ldap_server/ldap_backend.c                 |   25 ++-
 source4/libcli/ldap/ldap_controls.c                |   96 ++++++++
 23 files changed, 976 insertions(+), 95 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c
index 73e1705..daeb422 100644
--- a/lib/ldb/common/attrib_handlers.c
+++ b/lib/ldb/common/attrib_handlers.c
@@ -387,6 +387,27 @@ static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx,
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
+	out->data = (uint8_t *)ldb_timestring_utc(mem_ctx, t);
+	if (out->data == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	out->length = strlen((char *)out->data);
+	return 0;
+}
+
+/*
+  canonicalise a generalized time
+*/
+static int ldb_canonicalise_generalizedtime(struct ldb_context *ldb, void *mem_ctx,
+				        const struct ldb_val *in, struct ldb_val *out)
+{
+	time_t t;
+	int ret;
+	ret = ldb_val_to_time(in, &t);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
 	out->data = (uint8_t *)ldb_timestring(mem_ctx, t);
 	if (out->data == NULL) {
 		ldb_oom(ldb);
@@ -443,6 +464,13 @@ static const struct ldb_schema_syntax ldb_standard_syntaxes[] = {
 		.comparison_fn   = ldb_comparison_utctime
 	},
 	{ 
+		.name            = LDB_SYNTAX_GENERALIZED_TIME,
+		.ldif_read_fn    = ldb_handler_copy,
+		.ldif_write_fn   = ldb_handler_copy,
+		.canonicalise_fn = ldb_canonicalise_generalizedtime,
+		.comparison_fn   = ldb_comparison_utctime
+	},
+	{
 		.name            = LDB_SYNTAX_BOOLEAN,
 		.ldif_read_fn    = ldb_handler_copy,
 		.ldif_write_fn   = ldb_handler_copy,
diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 7ce4fc3..097ae20 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -368,6 +368,25 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		return res;
 	}
 
+	if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) {
+		struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control);
+
+		if (rep_control->gc != NULL) {
+			res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
+						LDB_CONTROL_VERIFY_NAME_NAME,
+						control->critical,
+						rep_control->flags,
+						rep_control->gc);
+
+		} else {
+			res = talloc_asprintf(mem_ctx, "%s:%d:%d",
+						LDB_CONTROL_VERIFY_NAME_NAME,
+						control->critical,
+						rep_control->flags);
+		}
+		return res;
+	}
+
 	/*
 	 * From here we don't know the control
 	 */
@@ -1018,6 +1037,40 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 
 		return ctrl;
 	}
+	if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) {
+		const char *p;
+		char gc[1024];
+		int crit, flags, ret;
+		struct ldb_verify_name_control *control;
+
+		gc[0] = '\0';
+
+		p = &(control_strings[sizeof(LDB_CONTROL_VERIFY_NAME_NAME)]);
+		ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &flags, gc);
+		if ((ret != 3) || (crit < 0) || (crit > 1)) {
+			ret = sscanf(p, "%d:%d", &crit, &flags);
+			if ((ret != 2) || (crit < 0) || (crit > 1)) {
+				error_string = talloc_asprintf(mem_ctx, "invalid verify_name control syntax\n");
+				error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(i)[:gc(s)]\n");
+				error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+				error_string = talloc_asprintf_append(error_string, "   note: i = integer");
+				error_string = talloc_asprintf_append(error_string, "   note: s = string");
+				ldb_set_errstring(ldb, error_string);
+				talloc_free(error_string);
+				talloc_free(ctrl);
+				return NULL;
+			}
+		}
+
+		ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID;
+		ctrl->critical = crit;
+		control = talloc(ctrl, struct ldb_verify_name_control);
+		control->gc = talloc_strdup(control, gc);
+		control->gc_len = strlen(gc);
+		control->flags = flags;
+		ctrl->data = control;
+		return ctrl;
+	}
 	/*
 	 * When no matching control has been found.
 	 */
diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c
index 35c568a..809e3af 100644
--- a/lib/ldb/common/ldb_msg.c
+++ b/lib/ldb/common/ldb_msg.c
@@ -1092,16 +1092,24 @@ int ldb_val_to_time(const struct ldb_val *v, time_t *t)
 {
 	struct tm tm;
 
-	if (v == NULL || !v->data || v->length < 17) {
+	if (v == NULL || !v->data || (v->length != 17 && v->length != 13)) {
 		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
 	}
 
 	memset(&tm, 0, sizeof(tm));
 
-	if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z",
-		   &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
-		   &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
-		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+	if (v->length == 13) {
+		if (sscanf((char *)v->data, "%02u%02u%02u%02u%02u%02uZ",
+			&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+			&tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+		}
+	} else {
+		if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z",
+			&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+			&tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+		}
 	}
 	tm.tm_year -= 1900;
 	tm.tm_mon -= 1;
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index ae34019..b60fc9b 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -475,6 +475,7 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
   See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 
 */
 #define LDB_SYNTAX_UTC_TIME             "1.3.6.1.4.1.1466.115.121.1.53"
+#define LDB_SYNTAX_GENERALIZED_TIME     "1.3.6.1.4.1.1466.115.121.1.24"
 
 #define LDB_SYNTAX_OBJECTCLASS          "LDB_SYNTAX_OBJECTCLASS"
 
@@ -708,6 +709,15 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 #define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
 #define LDB_CONTROL_RELAX_NAME	"relax"
 
+/**
+   OID for the allowing some kind of relax check for attributes with DNs
+
+
+   \sa 3.1.1.3.4.1.16 in [MS-ADTS].pdf
+*/
+#define LDB_CONTROL_VERIFY_NAME_OID "1.2.840.113556.1.4.1338"
+#define LDB_CONTROL_VERIFY_NAME_NAME	"verify_name"
+
 /* Extended operations */
 
 /**
@@ -843,6 +853,12 @@ struct ldb_vlv_resp_control {
 	char *contextId;
 };
 
+struct ldb_verify_name_control {
+	int flags;
+	size_t gc_len;
+	char *gc;
+};
+
 struct ldb_control {
 	const char *oid;
 	int critical;
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index 5ccf052..481ff60 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -624,12 +624,67 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	 * a schema cache being refreshed from database.
 	 */
 	if (working_schema) {
+		struct ldb_message *msg;
+		struct ldb_request *req;
+
+		/* Force a reload */
+		working_schema->last_refresh = 0;
 		cur_schema = dsdb_get_schema(ldb, NULL);
 		/* TODO: What we do in case dsdb_get_schema() fail?
 		 *       We can't fallback at this point anymore */
 		if (cur_schema) {
 			dsdb_make_schema_global(ldb, cur_schema);
 		}
+		msg = ldb_msg_new(ldb);
+		if (msg == 0) {
+			return WERR_NOMEM;
+		}
+		msg->dn = NULL;
+
+		ret = ldb_msg_add_string(msg, "schemaUpdateNow", "1");
+		if (ret != LDB_SUCCESS) {
+			talloc_free(msg);
+			return WERR_INTERNAL_ERROR;
+		}
+
+		ret = ldb_build_mod_req(&req, ldb, ldb,
+				msg,
+				LDB_SCOPE_BASE,
+				NULL,
+				ldb_op_default_callback,
+				NULL);
+
+		if (ret != LDB_SUCCESS) {
+			talloc_free(msg);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		ret = ldb_transaction_start(ldb);
+		if (ret != LDB_SUCCESS) {
+			talloc_free(msg);
+			talloc_free(req);
+			DEBUG(0, ("Autotransaction start failed\n"));
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		ret = ldb_request(ldb, req);
+		if (ret == LDB_SUCCESS) {
+			ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+		}
+
+		if (ret == LDB_SUCCESS) {
+			ret = ldb_transaction_commit(ldb);
+		} else {
+			DEBUG(0, ("Schema update now failed: %s\n", ldb_strerror(ret)));
+			ldb_transaction_cancel(ldb);
+		}
+
+		talloc_free(msg);
+		talloc_free(req);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(0, ("Commit failed: %s\n", ldb_strerror(ret)));
+			return WERR_DS_INTERNAL_FAILURE;
+		}
 	}
 
 	DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n",
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index bac592c..504f1b2 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -1,11 +1,12 @@
 /* 
    Unix SMB/CIFS implementation.
 
-   endpoint server for the drsuapi pipe
+   crachnames implementation for the drsuapi pipe
    DsCrackNames()
 
    Copyright (C) Stefan Metzmacher 2004
    Copyright (C) Andrew Bartlett <abartlet at samba.org> 2004-2005
+   Copyright (C) Matthieu Patou <mat at matws.net> 2012
 
    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
@@ -41,7 +42,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
 				   enum drsuapi_DsNameFormat format_desired,
 				   struct ldb_dn *name_dn, const char *name, 
 				   const char *domain_filter, const char *result_filter, 
-				   struct drsuapi_DsNameInfo1 *info1);
+				   struct drsuapi_DsNameInfo1 *info1, int scope, struct ldb_dn *search_dn);
 static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx,
 					enum drsuapi_DsNameFormat format_offered,
 					enum drsuapi_DsNameFormat format_desired,
@@ -184,7 +185,7 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
 	WERROR wret;
 	krb5_error_code ret;
 	krb5_principal principal;
-	krb5_data *component;
+	const krb5_data *component;
 	const char *service, *dns_name;
 	char *new_service;
 	char *new_princ;
@@ -344,12 +345,100 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 				      smb_krb5_context, 
 				      format_flags, format_offered, format_desired, 
 				      NULL, unparsed_name_short, domain_filter, result_filter, 
-				      info1);
+				      info1, LDB_SCOPE_SUBTREE, NULL);
 	free(unparsed_name_short);
 
 	return status;
 }
 
+/*
+ * This function will workout the filtering parameter in order to be able to do
+ * the adapted search when the incomming format is format_functional.
+ * This boils down to defining the search_dn (passed as pointer to ldb_dn *) and the
+ * ldap filter request.
+ * Main input parameters are:
+ * * name, which is the portion of the functional name after the
+ * first '/'.
+ * * domain_filter, which is a ldap search filter used to find the NC DN given the
+ * function name to crack.
+ */
+static WERROR get_format_functional_filtering_param(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
+			char *name, struct drsuapi_DsNameInfo1 *info1,
+			struct ldb_dn **psearch_dn, const char *domain_filter, const char **presult_filter)
+{
+	struct ldb_result *domain_res = NULL;
+	const char * const domain_attrs[] = {"ncName", NULL};
+	struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
+	int ldb_ret;
+	char *account,  *s, *result_filter = NULL;
+	struct ldb_dn *search_dn = NULL;
+
+	*psearch_dn = NULL;
+	*presult_filter = NULL;
+
+	ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
+				partitions_basedn,
+				LDB_SCOPE_ONELEVEL,
+				domain_attrs,
+				"%s", domain_filter);
+
+	if (ldb_ret != LDB_SUCCESS) {
+		DEBUG(2, ("DsCrackNameOne domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
+		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+		return WERR_FOOBAR;
+	}
+
+	if (domain_res->count == 1) {
+		struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
+		const char * const name_attrs[] = {"name", NULL};
+
+		account = name;
+		s = strchr(account, '/');
+		while(s) {
+			s[0] = '\0';
+			s++;
+			talloc_free(domain_res);
+
+			ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
+						tmp_dn,
+						LDB_SCOPE_ONELEVEL,
+						name_attrs,
+						"name=%s", account);
+
+			if (ldb_ret != LDB_SUCCESS) {
+				DEBUG(2, ("DsCrackNameOne domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
+				info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+				return WERR_OK;
+			}
+			switch (domain_res->count) {
+			case 1:
+				break;
+			case 0:
+				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+				return WERR_OK;
+			default:
+				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+				return WERR_OK;
+			}
+
+			talloc_free(tmp_dn);
+			tmp_dn = talloc_steal(mem_ctx, domain_res->msgs[0]->dn);
+			talloc_free(domain_res);
+			search_dn = tmp_dn;
+			account = s;
+			s = strchr(account, '/');
+		}
+		account = ldb_binary_encode_string(mem_ctx, account);
+		W_ERROR_HAVE_NO_MEMORY(account);
+		result_filter = talloc_asprintf(mem_ctx, "(name=%s)",
+						account);
+		W_ERROR_HAVE_NO_MEMORY(result_filter);
+	}
+	*psearch_dn = search_dn;
+	*presult_filter = result_filter;
+	return WERR_OK;
+}
+
 /* Crack a single 'name', from format_offered into format_desired, returning the result in info1 */
 
 WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
@@ -361,8 +450,10 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 	const char *domain_filter = NULL;
 	const char *result_filter = NULL;
 	struct ldb_dn *name_dn = NULL;
+	struct ldb_dn *search_dn = NULL;
 
 	struct smb_krb5_context *smb_krb5_context = NULL;
+	int scope = LDB_SCOPE_SUBTREE;
 
 	info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
 	info1->dns_domain_name = NULL;
@@ -406,6 +497,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 	case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
 	{
 		char *str, *s, *account;
+		scope = LDB_SCOPE_ONELEVEL;
 
 		if (strlen(name) == 0) {
 			info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
@@ -442,19 +534,20 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 		W_ERROR_HAVE_NO_MEMORY(domain_filter);
 
 		/* There may not be anything after the domain component (search for the domain itself) */
-		if (s[0]) {
-
-			account = strrchr(s, '/');
-			if (!account) {
-				account = s;
-			} else {
-				account++;
+		account = s;
+		if (account && *account) {
+			WERROR werr = get_format_functional_filtering_param(sam_ctx,
+										mem_ctx,
+										account,
+										info1,
+										&search_dn,
+										domain_filter,
+										&result_filter);
+			if (!W_ERROR_IS_OK(werr)) {
+				return werr;
 			}
-			account = ldb_binary_encode_string(mem_ctx, account);
-			W_ERROR_HAVE_NO_MEMORY(account);
-			result_filter = talloc_asprintf(mem_ctx, "(name=%s)",
-							account);	       
-			W_ERROR_HAVE_NO_MEMORY(result_filter);
+			if (info1->status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR)
+				return WERR_OK;
 		}
 		break;
 	}
@@ -600,7 +693,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 	case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: {
 		krb5_principal principal;
 		char *unparsed_name_short;
-		krb5_data *component;
+		const krb5_data *component;
 		char *service;
 
 		ret = smb_krb5_init_context(mem_ctx, 
@@ -686,7 +779,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 				    format_flags, format_offered, format_desired, 
 				    name_dn, name, 
 				    domain_filter, result_filter, 
-				    info1);
+				    info1, scope, search_dn);
 }
 
 /* Subcase of CrackNames.  It is possible to translate a LDAP-style DN
@@ -738,7 +831,8 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
 				   enum drsuapi_DsNameFormat format_desired,
 				   struct ldb_dn *name_dn, const char *name, 
 				   const char *domain_filter, const char *result_filter, 
-				   struct drsuapi_DsNameInfo1 *info1)
+				   struct drsuapi_DsNameInfo1 *info1,
+				   int scope, struct ldb_dn *search_dn)
 {
 	int ldb_ret;
 	struct ldb_result *domain_res = NULL;
@@ -834,14 +928,18 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
 		int ret;
 		struct ldb_result *res;
 		uint32_t dsdb_flags = 0;
-		struct ldb_dn *search_dn;
+		struct ldb_dn *real_search_dn;
 
 		if (domain_res) {
-			dsdb_flags = 0;
-			search_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
+			if (!search_dn) {
+				struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
+				real_search_dn = tmp_dn;
+			} else {
+				real_search_dn = search_dn;
+			}
 		} else {
 			dsdb_flags = DSDB_SEARCH_SEARCH_ALL_PARTITIONS;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list