[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Jul 13 06:04:04 MDT 2011


The branch, master has been updated
       via  3dae323 s4-dsdb: fixed the defaultObjectCategory to have a full GUID
       via  18995cd s4-fault: changed to use %d for PID, instead of %PID%
       via  80c8f42 s4-dsdb: another special case for the "member" attribute
       via  43c0a92 s4-dsdb Don't process deletion of member attributes here.
       via  014fca1 dsdb: fixed special case of zero NTTIME
       via  fc476ec dbcheck: use samdb_schema for getting the backlink
       via  23b6af1 ldb: added ldb_val_string_cmp()
       via  2087eb1 ldb: use base searches for @ special DNs
       via  c60a489 ldb: don't return special DNs on non-base searches
       via  58e8944 ldb: don't shortcut dn comparison for mismatched special DNs
       via  eb7c2af dbcheck: only do the provision dbcheck if there are objects to check
       via  1ee67df s4-test: fixed usage message on renamedc.sh
       via  182fd31 s4-provision: fixed the GUIDs in the provision using dbcheck
       via  afe4b77 s4-dsdb: fixed modify of ACLs on deleted objects
       via  303b57c dbcheck: only fix replPropertyMetaData if we included it in the search
       via  5064d73 dbcheck: added checks for missing and orphansed backlinks
       via  b66c577 s4-dsdb: raise debug level for backlink errors
       via  534c1ca dbcheck: fixed ldap check with no database specified
       via  0ab3086 dbcheck: added --reindex option
       via  6bc1957 samba-tool: fixed ldapcmp to run as non-root
       via  d9e2317 dbcheck: added checking of backlinks
       via  94b820a pydsdb: added get_backlink_from_lDAPDisplayName()
       via  0214b7f s4-dsdb: moved checking of duplicate member entries to repl_meta_data.c
      from  e858ec6 s3-rpc_server: Removed no longer used functions.

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


- Log -----------------------------------------------------------------
commit 3dae32397a87534ff1cf764260e7fcadd6665a49
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 19:36:59 2011 +1000

    s4-dsdb: fixed the defaultObjectCategory to have a full GUID
    
    this fixes the DN to have a full GUID for new objects
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Wed Jul 13 14:03:30 CEST 2011 on sn-devel-104

commit 18995cde5c5d2e647d94f9dcde4ba9261464c217
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 17:26:31 2011 +1000

    s4-fault: changed to use %d for PID, instead of %PID%
    
    this matches the s3 behaviour
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 80c8f42f058bdcdf639037927c5941190f019a67
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 15:58:45 2011 +1000

    s4-dsdb: another special case for the "member" attribute
    
    thanks to Matthias for his great test suite work!
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 43c0a92d23c2be446a9568b9d937e525d676f85e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jul 13 15:31:19 2011 +1000

    s4-dsdb Don't process deletion of member attributes here.
    
    We don't need to compare the delete against the primaryGroupID check
    here - that test is for adds.
    
    Andrew Bartlett

commit 014fca10697c80d49d2c3438089935c63f445644
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 13:26:48 2011 +1000

    dsdb: fixed special case of zero NTTIME
    
    we can't convert 0 NTTIME via a unix time_t
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit fc476ec8ac3357c81b805e0634624f183a6f7b49
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 13:26:19 2011 +1000

    dbcheck: use samdb_schema for getting the backlink
    
    this is not available on an ldap samdb
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 23b6af10f6ab3852ca28338b8d58342be816f0a2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 13:25:34 2011 +1000

    ldb: added ldb_val_string_cmp()
    
    this should help fix some places where we run past the end of a string
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 2087eb1602d647a7b14523820834231f50dea79d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 13:05:19 2011 +1000

    ldb: use base searches for @ special DNs
    
    subtree searches on these DNs don't work any more
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit c60a48948a75a6d300e31c2a2629daa4a48cbeb1
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 12:25:09 2011 +1000

    ldb: don't return special DNs on non-base searches
    
    to look at a special DN, give the full DN
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 58e89443e2e1722dec85ec426a63449b53b19ea3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 12:24:25 2011 +1000

    ldb: don't shortcut dn comparison for mismatched special DNs
    
    DNs that start with @ can't be compared via string comparison with
    normal DNs
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit eb7c2af83bbebd9e32fdfd459cfef7db15918911
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 10:54:50 2011 +1000

    dbcheck: only do the provision dbcheck if there are objects to check
    
    when in FILL_DRS mode, there are no objects to check yet
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 1ee67df307f27f2787793b7304a333a563f247c3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 10:49:45 2011 +1000

    s4-test: fixed usage message on renamedc.sh

commit 182fd31be57907e252c86506b1c2dac5c40fe244
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 10:31:15 2011 +1000

    s4-provision: fixed the GUIDs in the provision using dbcheck
    
    some DNs are are not setup with GUIDs during the provision because of
    circular dependencies between objects. This adds a dbcheck pass to the
    provision to fix those DNs
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit afe4b77d35a95d2338094b8cbc96ca421a023413
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 10:28:07 2011 +1000

    s4-dsdb: fixed modify of ACLs on deleted objects
    
    this is needed for the dbcheck code
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 303b57c295c4712c0bd606e893e39dff1cbe3e65
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Jul 13 10:12:48 2011 +1000

    dbcheck: only fix replPropertyMetaData if we included it in the search
    
    if we didn't find a replPropertyMetaData attribute at all then don't
    try fixing it
    
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

commit 5064d73672eecb2750d64f84c126f82781b0191b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Jul 12 11:26:29 2011 +1000

    dbcheck: added checks for missing and orphansed backlinks
    
    this checks for missing backlinks or backlinks without a forward link
    and optionally fixes them
    
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit b66c57751a0f217b5dbd7b3b75cf13c3ae465855
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Jul 12 11:25:39 2011 +1000

    s4-dsdb: raise debug level for backlink errors
    
    when dbcheck is fixing missing backlinks we don't want a DEBUG 0
    message
    
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

commit 534c1ca00ef1d658c4cefe72fcc3acb101635ae9
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Jul 12 11:12:21 2011 +1000

    dbcheck: fixed ldap check with no database specified
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

commit 0ab3086b46259a4627eabab93ebda41fd21408b0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Jul 12 11:05:43 2011 +1000

    dbcheck: added --reindex option
    
    this allows you to force a reindex of the database
    
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 6bc1957a54ba2e3c73b0cf580c94e8055d451b03
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Jul 12 10:41:52 2011 +1000

    samba-tool: fixed ldapcmp to run as non-root
    
    this avoids the need for access to the secrets database
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

commit d9e2317f491cbf532c7bc186d91c6d270a2f583e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jul 11 16:55:36 2011 +1000

    dbcheck: added checking of backlinks
    
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 94b820af56f841ae755822a421a5c7066b7921d0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jul 11 16:55:11 2011 +1000

    pydsdb: added get_backlink_from_lDAPDisplayName()
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

commit 0214b7f20cfcecd3d51aa12ae4e31cc4e095d73b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Jul 11 15:32:12 2011 +1000

    s4-dsdb: moved checking of duplicate member entries to repl_meta_data.c
    
    the samldb checks failed to account for the possibility of a member
    being removed and added in the same modify operation. This happens
    (for example) when dbcheck is fixing a SID in a DN.
    
    The repl_meta_data.c code already has this check, it just wasn't
    giving the right specialised error code for the 'member' attribute
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Pair-Programmed-With: Amitay Isaacs <amitay at gmail.com>

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

Summary of changes:
 lib/ldb/ABI/{ldb-1.1.0.sigs => ldb-1.1.1.sigs}     |    1 +
 lib/ldb/common/ldb_dn.c                            |    2 +-
 lib/ldb/common/ldb_match.c                         |    5 +
 lib/ldb/common/ldb_msg.c                           |   12 ++
 lib/ldb/include/ldb.h                              |    5 +
 lib/ldb/wscript                                    |    2 +-
 lib/util/fault.c                                   |    2 +-
 selftest/selftest.pl                               |    2 +-
 selftest/target/Samba4.pm                          |    2 +-
 source4/dsdb/pydsdb.c                              |   45 +++++
 source4/dsdb/samdb/ldb_modules/acl.c               |    6 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |   29 +++-
 source4/dsdb/samdb/ldb_modules/samldb.c            |   68 ++++----
 source4/dsdb/schema/schema_syntax.c                |   20 +++
 source4/scripting/bin/upgradeprovision             |    2 +-
 source4/scripting/python/samba/dbchecker.py        |  180 +++++++++++++-------
 source4/scripting/python/samba/netcmd/dbcheck.py   |   15 ++-
 source4/scripting/python/samba/netcmd/ldapcmp.py   |   11 +-
 .../scripting/python/samba/provision/__init__.py   |   42 ++++--
 source4/scripting/python/samba/samdb.py            |    5 +
 .../python/samba/tests/upgradeprovision.py         |    8 +-
 source4/scripting/python/samba/upgradehelpers.py   |    6 +-
 testprogs/blackbox/renamedc.sh                     |    2 +-
 wintest/test-s4-howto.py                           |    2 +-
 24 files changed, 336 insertions(+), 138 deletions(-)
 copy lib/ldb/ABI/{ldb-1.1.0.sigs => ldb-1.1.1.sigs} (99%)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/ABI/ldb-1.1.0.sigs b/lib/ldb/ABI/ldb-1.1.1.sigs
similarity index 99%
copy from lib/ldb/ABI/ldb-1.1.0.sigs
copy to lib/ldb/ABI/ldb-1.1.1.sigs
index 149d4bc..2fe215c 100644
--- a/lib/ldb/ABI/ldb-1.1.0.sigs
+++ b/lib/ldb/ABI/ldb-1.1.1.sigs
@@ -248,6 +248,7 @@ ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *)
 ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *)
 ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
 ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_string_cmp: int (const struct ldb_val *, const char *)
 ldb_val_to_time: int (const struct ldb_val *, time_t *)
 ldb_valid_attr_name: int (const char *)
 ldb_wait: int (struct ldb_handle *, enum ldb_wait_type)
diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c
index cd9055d..6b1ef03 100644
--- a/lib/ldb/common/ldb_dn.c
+++ b/lib/ldb/common/ldb_dn.c
@@ -1034,7 +1034,7 @@ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
 	if ( ! dn || dn->invalid) return -1;
 
 	if (( ! base->valid_case) || ( ! dn->valid_case)) {
-		if (base->linearized && dn->linearized) {
+		if (base->linearized && dn->linearized && dn->special == base->special) {
 			/* try with a normal compare first, if we are lucky
 			 * we will avoid exploding and casfolding */
 			int dif;
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index a42cf94..c23e804 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -463,6 +463,11 @@ static int ldb_match_message(struct ldb_context *ldb,
 
 	*matched = false;
 
+	if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) {
+		/* don't match special records except on base searches */
+		return LDB_SUCCESS;
+	}
+
 	switch (tree->operation) {
 	case LDB_OP_AND:
 		for (i=0;i<tree->u.list.num_elements;i++) {
diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c
index 28c414e..1a2bebc 100644
--- a/lib/ldb/common/ldb_msg.c
+++ b/lib/ldb/common/ldb_msg.c
@@ -1185,3 +1185,15 @@ int ldb_msg_check_string_attribute(const struct ldb_message *msg,
 	return 0;
 }
 
+
+/*
+  compare a ldb_val to a string
+*/
+int ldb_val_string_cmp(const struct ldb_val *v, const char *str)
+{
+	size_t len = strlen(str);
+	if (len != v->length) {
+		return len - v->length;
+	}
+	return strncmp((const char *)v->data, str, len);
+}
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index d745f37..1305d8e 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -2251,4 +2251,9 @@ const char *ldb_req_location(struct ldb_request *req);
  */
 bool ldb_dn_minimise(struct ldb_dn *dn);
 
+/*
+  compare a ldb_val to a string
+*/
+int ldb_val_string_cmp(const struct ldb_val *v, const char *str);
+
 #endif
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index a8d9bf7..d05453e 100755
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'ldb'
-VERSION = '1.1.0'
+VERSION = '1.1.1'
 
 blddir = 'bin'
 
diff --git a/lib/util/fault.c b/lib/util/fault.c
index 708dc67..ed7684a 100644
--- a/lib/util/fault.c
+++ b/lib/util/fault.c
@@ -121,7 +121,7 @@ static void smb_panic_default(const char *why)
 		char cmdstring[200];
 		strlcpy(cmdstring, panic_action, sizeof(cmdstring));
 		snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
-		all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring));
+		all_string_sub(cmdstring, "%d", pidstr, sizeof(cmdstring));
 		DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
 		result = system(cmdstring);
 
diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index 808be22..218f83b 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -643,7 +643,7 @@ sub write_clientconf($$$)
 	cache dir = $clientdir/cachedir
 	ncalrpc dir = $clientdir/ncalrpcdir
 	name resolve order = file bcast
-	panic action = $RealBin/gdb_backtrace \%PID\%
+	panic action = $RealBin/gdb_backtrace \%d
 	max xmit = 32K
 	notify:inotify = false
 	ldb:nosync = true
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 2bb74ca..2610232 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -606,7 +606,7 @@ sub provision_raw_step1($$)
 	name resolve order = file bcast
 	interfaces = $ctx->{interfaces}
 	tls dh params file = $ctx->{tlsdir}/dhparms.pem
-	panic action = $RealBin/gdb_backtrace \%PID%
+	panic action = $RealBin/gdb_backtrace \%d
 	wins support = yes
 	server role = $ctx->{server_role}
 	server services = +echo
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 463a2f9..e74f2bb 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -394,6 +394,49 @@ static PyObject *py_dsdb_get_linkId_from_lDAPDisplayName(PyObject *self, PyObjec
 	return PyInt_FromLong(attribute->linkID);
 }
 
+/*
+  return the backlink attribute name (if any) for an attribute
+ */
+static PyObject *py_dsdb_get_backlink_from_lDAPDisplayName(PyObject *self, PyObject *args)
+{
+	PyObject *py_ldb;
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	const char *ldap_display_name;
+	const struct dsdb_attribute *attribute, *target_attr;
+
+	if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
+		return NULL;
+
+	PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+	schema = dsdb_get_schema(ldb, NULL);
+
+	if (!schema) {
+		PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
+		return NULL;
+	}
+
+	attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
+	if (attribute == NULL) {
+		PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+		return NULL;
+	}
+
+	if (attribute->linkID == 0) {
+		Py_RETURN_NONE;
+	}
+
+	target_attr = dsdb_attribute_by_linkID(schema, attribute->linkID ^ 1);
+	if (target_attr == NULL) {
+		/* when we add pseudo-backlinks we'll need to handle
+		   them here */
+		Py_RETURN_NONE;
+	}
+
+	return PyString_FromString(target_attr->lDAPDisplayName);
+}
+
 
 static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *args)
 {
@@ -937,6 +980,8 @@ static PyMethodDef py_dsdb_methods[] = {
 		METH_VARARGS, NULL },
 	{ "_dsdb_get_lDAPDisplayName_by_attid", (PyCFunction)py_dsdb_get_lDAPDisplayName_by_attid,
 		METH_VARARGS, NULL },
+	{ "_dsdb_get_backlink_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_backlink_from_lDAPDisplayName,
+		METH_VARARGS, NULL },
 	{ "_dsdb_set_ntds_invocation_id",
 		(PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
 		NULL },
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 49152d4..12a4028 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -902,7 +902,8 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
 	}
 	ret = dsdb_module_search_dn(module, tmp_ctx, &acl_res, req->op.mod.message->dn,
 				    acl_attrs,
-				    DSDB_FLAG_NEXT_MODULE, req);
+				    DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
+				    req);
 
 	if (ret != LDB_SUCCESS) {
 		goto fail;
@@ -1337,7 +1338,8 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 		    || ac->sDRightsEffective) {
 			ret = dsdb_module_search_dn(ac->module, ac, &acl_res, ares->message->dn, 
 						    acl_attrs,
-						    DSDB_FLAG_NEXT_MODULE, req);
+						    DSDB_FLAG_NEXT_MODULE |
+						    DSDB_SEARCH_SHOW_DELETED, req);
 			if (ret != LDB_SUCCESS) {
 				return ldb_module_done(ac->req, NULL, NULL, ret);
 			}
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index a76b88e..706ca33 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -258,7 +258,7 @@ static int replmd_process_backlink(struct ldb_module *module, struct la_backlink
 		/* we allow LDB_ERR_NO_SUCH_ATTRIBUTE as success to
 		   cope with possible corruption where the backlink has
 		   already been removed */
-		DEBUG(0,("WARNING: backlink from %s already removed from %s - %s\n",
+		DEBUG(3,("WARNING: backlink from %s already removed from %s - %s\n",
 			 ldb_dn_get_linearized(target_dn),
 			 ldb_dn_get_linearized(source_dn),
 			 ldb_errstring(ldb)));
@@ -395,7 +395,7 @@ static int replmd_op_callback(struct ldb_request *req, struct ldb_reply *ares)
 	}
 
 	if (ares->error != LDB_SUCCESS) {
-		DEBUG(0,("%s failure. Error is: %s\n", __FUNCTION__, ldb_strerror(ares->error)));
+		DEBUG(5,("%s failure. Error is: %s\n", __FUNCTION__, ldb_strerror(ares->error)));
 		return ldb_module_done(ac->req, controls,
 					ares->response, ares->error);
 	}
@@ -1457,6 +1457,11 @@ static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
 			if (ret != LDB_SUCCESS) {
 				ldb_asprintf_errstring(ldb, "Unable to find GUID for DN %s\n",
 						       ldb_dn_get_linearized(dn));
+				if (ret == LDB_ERR_NO_SUCH_OBJECT &&
+				    LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE &&
+				    ldb_attr_cmp(el->name, "member") == 0) {
+					return LDB_ERR_UNWILLING_TO_PERFORM;
+				}
 				return ret;
 			}
 			ret = dsdb_set_extended_dn_guid(dn, p->guid, "GUID");
@@ -1774,7 +1779,13 @@ static int replmd_modify_la_add(struct ldb_module *module,
 				ldb_asprintf_errstring(ldb, "Attribute %s already exists for target GUID %s",
 						       el->name, GUID_string(tmp_ctx, p->guid));
 				talloc_free(tmp_ctx);
-				return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+				/* error codes for 'member' need to be
+				   special cased */
+				if (ldb_attr_cmp(el->name, "member") == 0) {
+					return LDB_ERR_ENTRY_ALREADY_EXISTS;
+				} else {
+					return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+				}
 			}
 			ret = replmd_update_la_val(old_el->values, p->v, dns[i].dsdb_dn, p->dsdb_dn,
 						   invocation_id, seq_num, seq_num, now, 0, false);
@@ -1886,13 +1897,21 @@ static int replmd_modify_la_delete(struct ldb_module *module,
 		if (!p2) {
 			ldb_asprintf_errstring(ldb, "Attribute %s doesn't exist for target GUID %s",
 					       el->name, GUID_string(tmp_ctx, p->guid));
-			return LDB_ERR_NO_SUCH_ATTRIBUTE;
+			if (ldb_attr_cmp(el->name, "member") == 0) {
+				return LDB_ERR_UNWILLING_TO_PERFORM;
+			} else {
+				return LDB_ERR_NO_SUCH_ATTRIBUTE;
+			}
 		}
 		rmd_flags = dsdb_dn_rmd_flags(p2->dsdb_dn->dn);
 		if (rmd_flags & DSDB_RMD_FLAG_DELETED) {
 			ldb_asprintf_errstring(ldb, "Attribute %s already deleted for target GUID %s",
 					       el->name, GUID_string(tmp_ctx, p->guid));
-			return LDB_ERR_NO_SUCH_ATTRIBUTE;
+			if (ldb_attr_cmp(el->name, "member") == 0) {
+				return LDB_ERR_UNWILLING_TO_PERFORM;
+			} else {
+				return LDB_ERR_NO_SUCH_ATTRIBUTE;
+			}
 		}
 	}
 
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index a61920f..5c94099 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -379,6 +379,30 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
 		return ret;
 	}
 
+	if (ret == LDB_SUCCESS) {
+		/* ensure the defaultObjectCategory has a full GUID */
+		struct ldb_message *m;
+		m = ldb_msg_new(ac->msg);
+		if (m == NULL) {
+			return ldb_oom(ldb);
+		}
+		m->dn = ac->msg->dn;
+		if (ldb_msg_add_string(m, "defaultObjectCategory",
+				       ldb_dn_get_extended_linearized(m, res->msgs[0]->dn, 1)) !=
+		    LDB_SUCCESS) {
+			return ldb_oom(ldb);
+		}
+		m->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+		ret = dsdb_module_modify(ac->module, m,
+					 DSDB_FLAG_NEXT_MODULE,
+					 ac->req);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+
 	ac->res_dn = ac->dn;
 
 	return samldb_next_step(ac);
@@ -1568,7 +1592,6 @@ static int samldb_member_check(struct samldb_ctx *ac)
 	struct ldb_result *res;
 	struct dom_sid *group_sid;
 	unsigned int i, j;
-	int cnt;
 	int ret;
 
 	/* Fetch information from the existing object */
@@ -1596,47 +1619,25 @@ static int samldb_member_check(struct samldb_ctx *ac)
 
 		el = &ac->msg->elements[i];
 		for (j = 0; j < el->num_values; j++) {
-			struct ldb_message_element *mo;
 			struct ldb_result *group_res;
 			const char *group_attrs[] = { "primaryGroupID" , NULL };
 			uint32_t prim_group_rid;
 
+			if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
+				/* Deletes will be handled in
+				 * repl_meta_data, and deletes not
+				 * matching a member will return
+				 * LDB_ERR_UNWILLING_TO_PERFORM
+				 * there */
+				continue;
+			}
+
 			member_dn = ldb_dn_from_ldb_val(ac, ldb,
 							&el->values[j]);
 			if (!ldb_dn_validate(member_dn)) {
 				return ldb_operr(ldb);
 			}
 
-			/* The "member" attribute can be modified with the
-			 * following restrictions (beside a valid DN):
-			 *
-			 * - "add" operations can only be performed when the
-			 *   member still doesn't exist - if not then return
-			 *   ERR_ENTRY_ALREADY_EXISTS (not
-			 *   ERR_ATTRIBUTE_OR_VALUE_EXISTS!)
-			 * - "delete" operations can only be performed when the
-			 *   member does exist - if not then return
-			 *   ERR_UNWILLING_TO_PERFORM (not
-			 *   ERR_NO_SUCH_ATTRIBUTE!)
-			 * - primary group check
-			 */
-			mo = samdb_find_attribute(ldb, res->msgs[0], "member",
-						  ldb_dn_get_linearized(member_dn));
-			if (mo == NULL) {
-				cnt = 0;
-			} else {
-				cnt = 1;
-			}
-
-			if ((cnt > 0) && (LDB_FLAG_MOD_TYPE(el->flags)
-			    == LDB_FLAG_MOD_ADD)) {
-				return LDB_ERR_ENTRY_ALREADY_EXISTS;
-			}
-			if ((cnt == 0) && LDB_FLAG_MOD_TYPE(el->flags)
-			    == LDB_FLAG_MOD_DELETE) {
-				return LDB_ERR_UNWILLING_TO_PERFORM;
-			}
-
 			/* Denies to add "member"s to groups which are primary
 			 * ones for them - in this case return
 			 * ERR_ENTRY_ALREADY_EXISTS. */
@@ -1665,6 +1666,9 @@ static int samldb_member_check(struct samldb_ctx *ac)
 			}
 
 			if (dom_sid_equal(group_sid, sid)) {
+				ldb_asprintf_errstring(ldb,
+						       "samldb: member %s already set via primaryGroupID %u",
+						       ldb_dn_get_linearized(member_dn), prim_group_rid);
 				return LDB_ERR_ENTRY_ALREADY_EXISTS;
 			}
 		}
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index a93cdfa..d443c00 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -554,6 +554,11 @@ static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx
 		}
 
 		v = BVAL(in->value_ctr.values[i].blob->data, 0);
+		if (v == 0) {
+			/* special case for 1601 zero timestamp */
+			out->values[i] = data_blob_string_const("16010101000000.0Z");
+			continue;
+		}
 		v *= 10000000;
 		t = nt_time_to_unix(v);
 
@@ -607,6 +612,11 @@ static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx
 		blobs[i] = data_blob_talloc(blobs, NULL, 8);
 		W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
 
+		if (ldb_val_string_cmp("16010101000000.0Z", &in->values[i]) == 0) {
+			SBVALS(blobs[i].data, 0, 0);
+			continue;
+		}
+
 		t = ldb_string_utc_to_time((const char *)in->values[i].data);
 		unix_to_nt_time(&v, t);
 		v /= 10000000;
@@ -693,6 +703,11 @@ static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ct
 		}
 
 		v = BVAL(in->value_ctr.values[i].blob->data, 0);
+		if (v == 0) {
+			/* special case for 1601 zero timestamp */
+			out->values[i] = data_blob_string_const("16010101000000.0Z");
+			continue;
+		}
 		v *= 10000000;
 		t = nt_time_to_unix(v);
 
@@ -739,6 +754,11 @@ static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ct
 		blobs[i] = data_blob_talloc(blobs, NULL, 8);
 		W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
 
+		if (ldb_val_string_cmp("16010101000000.0Z", &in->values[i]) == 0) {
+			SBVALS(blobs[i].data, 0, 0);
+			continue;
+		}
+
 		ret = ldb_val_to_time(&in->values[i], &t);
 		if (ret != LDB_SUCCESS) {
 			return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index d2a645a..54f3cf1 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -1349,7 +1349,7 @@ def rebuild_sd(samdb, names):
 def removeProvisionUSN(samdb):
         attrs = [samba.provision.LAST_PROVISION_USN_ATTRIBUTE, "dn"]
         entry = samdb.search(expression="dn=@PROVISION", base = "",
-                                scope=SCOPE_SUBTREE,
+                                scope=SCOPE_BASE,
                                 attrs=attrs)
         empty = Message()
         empty.dn = entry[0].dn
diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py
index f914bbb..a1836cf 100644
--- a/source4/scripting/python/samba/dbchecker.py
+++ b/source4/scripting/python/samba/dbchecker.py
@@ -68,6 +68,8 @@ class dbcheck(object):
         self.remove_all_deleted_DN_links = False
         self.fix_all_target_mismatch = False
         self.fix_all_metadata = False
+        self.fix_all_missing_backlinks = False
+        self.fix_all_orphaned_backlinks = False
 
     def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=[], attrs=['*']):
         '''perform a database check, returning the number of errors found'''
@@ -126,6 +128,18 @@ class dbcheck(object):
         return c
 
 
+    def do_modify(self, m, controls, msg, validate=True):
+        '''perform a modify with optional verbose output'''
+        if self.verbose:
+            self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY))
+        try:
+            self.samdb.modify(m, controls=controls, validate=validate)
+        except Exception, err:
+            self.report("%s : %s" % (msg, err))
+            return False
+        return True
+
+
     ################################################################
     # handle empty attributes
     def err_empty_attribute(self, dn, attrname):
@@ -138,14 +152,9 @@ class dbcheck(object):
         m = ldb.Message()
         m.dn = dn


-- 
Samba Shared Repository


More information about the samba-cvs mailing list