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 <tri...@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 <abart...@samba.org>
    
    Autobuild-User: Andrew Tridgell <tri...@samba.org>
    Autobuild-Date: Wed Jul 13 14:03:30 CEST 2011 on sn-devel-104

commit 18995cde5c5d2e647d94f9dcde4ba9261464c217
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 80c8f42f058bdcdf639037927c5941190f019a67
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 43c0a92d23c2be446a9568b9d937e525d676f85e
Author: Andrew Bartlett <abart...@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 <tri...@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 <abart...@samba.org>

commit fc476ec8ac3357c81b805e0634624f183a6f7b49
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 23b6af10f6ab3852ca28338b8d58342be816f0a2
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 2087eb1602d647a7b14523820834231f50dea79d
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit c60a48948a75a6d300e31c2a2629daa4a48cbeb1
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 58e89443e2e1722dec85ec426a63449b53b19ea3
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit eb7c2af83bbebd9e32fdfd459cfef7db15918911
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

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

    s4-test: fixed usage message on renamedc.sh

commit 182fd31be57907e252c86506b1c2dac5c40fe244
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit afe4b77d35a95d2338094b8cbc96ca421a023413
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>

commit 303b57c295c4712c0bd606e893e39dff1cbe3e65
Author: Andrew Tridgell <tri...@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 <ami...@gmail.com>

commit 5064d73672eecb2750d64f84c126f82781b0191b
Author: Andrew Tridgell <tri...@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 <ami...@gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit b66c57751a0f217b5dbd7b3b75cf13c3ae465855
Author: Andrew Tridgell <tri...@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 <ami...@gmail.com>

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

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

commit 0ab3086b46259a4627eabab93ebda41fd21408b0
Author: Andrew Tridgell <tri...@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 <ami...@gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit 6bc1957a54ba2e3c73b0cf580c94e8055d451b03
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>
    Pair-Programmed-With: Amitay Isaacs <ami...@gmail.com>

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

    dbcheck: added checking of backlinks
    
    Pair-Programmed-With: Amitay Isaacs <ami...@gmail.com>
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

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

    pydsdb: added get_backlink_from_lDAPDisplayName()
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>
    Pair-Programmed-With: Amitay Isaacs <ami...@gmail.com>

commit 0214b7f20cfcecd3d51aa12ae4e31cc4e095d73b
Author: Andrew Tridgell <tri...@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 <abart...@samba.org>
    Pair-Programmed-With: Amitay Isaacs <ami...@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

Reply via email to