The branch, master has been updated
       via  3fca66e samba-tool: add support for fixing broken backlinks in 
dbcheck
       via  d7f617e s4-dsdb: allow deletion of backlinks if 
DSDB_CONTROL_DBCHECK given
       via  c2d70af s4-dsdb: added DSDB_CONTROL_DBCHECK
       via  ea41860 ldb: support raw OIDs in control string parsing
       via  b3476f0 ldb: fixed memory leak in control string parsing
       via  2d63789 s4-dsdb: allow groupType update on deleted objects
       via  8976e1d s4-rodc: use the rodc_replica flag on the partition
       via  2a2deeb s4-rodc: ensure we load replicated partitions for RODCs
      from  e717af0 s4-dsdb: Do not assume that all deleted objects have an 
objectCategory and sAMAccountType

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


- Log -----------------------------------------------------------------
commit 3fca66e2b343c6386476a52832591ae4e435d6b2
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 14:21:41 2011 +1100

    samba-tool: add support for fixing broken backlinks in dbcheck
    
    this allows dangling backlinks to be removed
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>
    
    Autobuild-User: Andrew Tridgell <tri...@samba.org>
    Autobuild-Date: Thu Oct  6 07:08:35 CEST 2011 on sn-devel-104

commit d7f617e2e180eab6decb18e697f1e1294194a2cb
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 14:21:02 2011 +1100

    s4-dsdb: allow deletion of backlinks if DSDB_CONTROL_DBCHECK given
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit c2d70af1a7b0a67283837a9f823158fd7f8db574
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 14:20:25 2011 +1100

    s4-dsdb: added DSDB_CONTROL_DBCHECK
    
    this will be used for overrides by the dbcheck validator
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit ea41860d32d38448e08cefd79d30ee1150317a9e
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 14:19:24 2011 +1100

    ldb: support raw OIDs in control string parsing
    
    this makes it possible to use a raw OID string on the command line or
    in python scripts
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit b3476f00a621cf2d5d547ed479acf91b5cc0679c
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 14:18:49 2011 +1100

    ldb: fixed memory leak in control string parsing
    
    if parsing fails, free ctrl
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit 2d63789e4869c147364d4e58c678a0c08b2e6859
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 12:31:21 2011 +1100

    s4-dsdb: allow groupType update on deleted objects
    
    this allows dbcheck to fix groupType on objects that have been deleted
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit 8976e1d50d6dc6633af82e05afe51ef41b61c66c
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 11:24:28 2011 +1100

    s4-rodc: use the rodc_replica flag on the partition
    
    this sets DSDB_REPL_FLAG_PARTIAL_REPLICA when replicating a RODC
    partition, which tells the replication code to map instanceType to
    remove the INSTANCE_TYPE_WRITE bit
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

commit 2a2deeb3b43dcb11f2b604bdd20c1183e87522bb
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Oct 6 11:14:13 2011 +1100

    s4-rodc: ensure we load replicated partitions for RODCs
    
    Pair-Programmed-With: Andrew Bartlett <abart...@samba.org>

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

Summary of changes:
 lib/ldb/common/ldb_controls.c                      |   42 +++++++++
 lib/ldb/include/ldb_private.h                      |    1 +
 source4/dsdb/pydsdb.c                              |    1 +
 source4/dsdb/repl/drepl_out_helpers.c              |    4 +-
 source4/dsdb/repl/drepl_partitions.c               |   89 +++++++++-----------
 source4/dsdb/repl/drepl_service.h                  |    2 +-
 source4/dsdb/samdb/ldb_modules/objectclass_attrs.c |    3 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |    3 +
 source4/dsdb/samdb/ldb_modules/samldb.c            |    3 +-
 source4/dsdb/samdb/samdb.h                         |    3 +
 source4/scripting/python/samba/dbchecker.py        |   52 +++++++-----
 source4/setup/schema_samba4.ldif                   |    1 +
 12 files changed, 129 insertions(+), 75 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 3856167..42fabfc 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -428,6 +428,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, n = number, s = string, o = b64 binary blob");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
                ctrl->oid = LDB_CONTROL_VLV_REQ_OID;
@@ -435,6 +436,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                if (!(control = talloc(ctrl,
                                        struct ldb_vlv_req_control))) {
                        ldb_oom(ldb);
+                       talloc_free(ctrl);
                        return NULL;
                }
                control->beforeCount = bc;
@@ -477,6 +479,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, n = number, o = b64 binary blob");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -519,6 +522,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, s = string");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -551,6 +555,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                                error_string = 
talloc_asprintf_append(error_string, "                     1 - normal string 
representation");
                                ldb_set_errstring(ldb, error_string);
                                talloc_free(error_string);
+                               talloc_free(ctrl);
                                return NULL;
                        }
                        control = NULL;
@@ -580,6 +585,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, n = number");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -606,6 +612,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, n = number");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -630,6 +637,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -652,6 +660,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -674,6 +683,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -696,6 +706,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -719,6 +730,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, n = number");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -750,6 +762,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, s = string");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
                ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
@@ -780,6 +793,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -802,6 +816,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -824,6 +839,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -846,6 +862,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -868,6 +885,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -890,6 +908,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -912,6 +931,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -937,12 +957,14 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean, s = string");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
                ctrl->oid = talloc_strdup(ctrl, oid);
                if (!ctrl->oid) {
                        ldb_oom(ldb);
+                       talloc_free(ctrl);
                        return NULL;
                }
                ctrl->critical = crit;
@@ -963,6 +985,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -985,6 +1008,7 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                        error_string = talloc_asprintf_append(error_string, "   
note: b = boolean");
                        ldb_set_errstring(ldb, error_string);
                        talloc_free(error_string);
+                       talloc_free(ctrl);
                        return NULL;
                }
 
@@ -994,9 +1018,27 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
 
                return ctrl;
        }
+
+       /* support a raw OID */
+       if (isdigit(control_strings[0])) {
+               const char *p = strchr(control_strings, ':');
+               if (p == NULL) {
+                       goto failed;
+               }
+               if (strspn(control_strings, "0123456789.") != 
(p-control_strings)) {
+                       goto failed;
+               }
+               ctrl->oid = talloc_strndup(ctrl, control_strings, 
p-control_strings);
+               ctrl->critical = (p[1]=='1'?1:0);
+               ctrl->data = NULL;
+               return ctrl;
+       }
+
        /*
         * When no matching control has been found.
         */
+failed:
+       talloc_free(ctrl);
        return NULL;
 }
 
diff --git a/lib/ldb/include/ldb_private.h b/lib/ldb/include/ldb_private.h
index cafc020..db2457d 100644
--- a/lib/ldb/include/ldb_private.h
+++ b/lib/ldb/include/ldb_private.h
@@ -40,6 +40,7 @@
 #include "replace.h"
 #include "system/filesys.h"
 #include "system/time.h"
+#include "system/locale.h"
 #include "ldb.h"
 #include "ldb_module.h"
 
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 18c2f7b..2ff6b82 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -1151,4 +1151,5 @@ void initdsdb(void)
        ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN);
        ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN);
        ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME);
+       ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK);
 }
diff --git a/source4/dsdb/repl/drepl_out_helpers.c 
b/source4/dsdb/repl/drepl_out_helpers.c
index 7cb642a..71d2c3b 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -424,7 +424,7 @@ static void 
dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
                        return;
                }
                replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
-       } else if (service->am_rodc) {
+       } else if (partition->rodc_replica) {
                bool for_schema = false;
                if (ldb_dn_compare_base(ldb_get_schema_basedn(service->samdb), 
partition->dn) == 0) {
                        for_schema = true;
@@ -675,7 +675,7 @@ static void 
dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
                }
        }
 
-       if (partition->partial_replica) {
+       if (partition->partial_replica || partition->rodc_replica) {
                dsdb_repl_flags |= DSDB_REPL_FLAG_PARTIAL_REPLICA;
        }
        if (state->op->options & DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS) {
diff --git a/source4/dsdb/repl/drepl_partitions.c 
b/source4/dsdb/repl/drepl_partitions.c
index 7c54245..f2d4b13 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -34,11 +34,15 @@
 #include "param/param.h"
 #include "dsdb/common/util.h"
 
+/*
+  load the partitions list based on replicated NC attributes in our
+  NTDSDSA object
+ */
 WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 {
        WERROR status;
-       static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", 
NULL };
-       unsigned int i;
+       static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", 
"msDS-HasFullReplicaNCs", NULL };
+       unsigned int a;
        int ret;
        TALLOC_CTX *tmp_ctx;
        struct ldb_result *res;
@@ -62,57 +66,42 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
                return WERR_DS_DRA_INTERNAL_ERROR;
        }
 
-       el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
-
-       for (i=0; el && i<el->num_values; i++) {
-               struct ldb_dn *pdn;
-               struct dreplsrv_partition *p;
+       for (a=0; attrs[a]; a++) {
+               int i;
 
-               pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
-               if (pdn == NULL) {
-                       talloc_free(tmp_ctx);
-                       return WERR_DS_DRA_INTERNAL_ERROR;
+               el = ldb_msg_find_element(res->msgs[0], attrs[a]);
+               if (el == NULL) {
+                       continue;
                }
-               if (!ldb_dn_validate(pdn)) {
-                       return WERR_DS_DRA_INTERNAL_ERROR;
-               }
-
-               p = talloc_zero(s, struct dreplsrv_partition);
-               W_ERROR_HAVE_NO_MEMORY(p);
-
-               p->dn = talloc_steal(p, pdn);
-               p->service = s;
+               for (i=0; i<el->num_values; i++) {
+                       struct ldb_dn *pdn;
+                       struct dreplsrv_partition *p;
+
+                       pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, 
&el->values[i]);
+                       if (pdn == NULL) {
+                               talloc_free(tmp_ctx);
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
+                       if (!ldb_dn_validate(pdn)) {
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
 
-               DLIST_ADD(s->partitions, p);
+                       p = talloc_zero(s, struct dreplsrv_partition);
+                       W_ERROR_HAVE_NO_MEMORY(p);
 
-               DEBUG(2, ("dreplsrv_partition[%s] loaded\n", 
ldb_dn_get_linearized(p->dn)));
-       }
+                       p->dn = talloc_steal(p, pdn);
+                       p->service = s;
 
-       el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs");
+                       if (strcasecmp(attrs[a], "hasPartialReplicaNCs") == 0) {
+                               p->partial_replica = true;
+                       } else if (strcasecmp(attrs[a], 
"msDS-HasFullReplicaNCs") == 0) {
+                               p->rodc_replica = true;
+                       }
 
-       for (i=0; el && i<el->num_values; i++) {
-               struct ldb_dn *pdn;
-               struct dreplsrv_partition *p;
+                       DLIST_ADD(s->partitions, p);
 
-               pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
-               if (pdn == NULL) {
-                       talloc_free(tmp_ctx);
-                       return WERR_DS_DRA_INTERNAL_ERROR;
-               }
-               if (!ldb_dn_validate(pdn)) {
-                       return WERR_DS_DRA_INTERNAL_ERROR;
+                       DEBUG(2, ("dreplsrv_partition[%s] loaded\n", 
ldb_dn_get_linearized(p->dn)));
                }
-
-               p = talloc_zero(s, struct dreplsrv_partition);
-               W_ERROR_HAVE_NO_MEMORY(p);
-
-               p->dn = talloc_steal(p, pdn);
-               p->partial_replica = true;
-               p->service = s;
-
-               DLIST_ADD(s->partitions, p);
-
-               DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", 
ldb_dn_get_linearized(p->dn)));
        }
 
        talloc_free(tmp_ctx);
diff --git a/source4/dsdb/repl/drepl_service.h 
b/source4/dsdb/repl/drepl_service.h
index 9856452..6daf82d 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -106,8 +106,8 @@ struct dreplsrv_partition {
         */
        struct dreplsrv_partition_source_dsa *notifies;
 
-       bool incoming_only;
        bool partial_replica;
+       bool rodc_replica;
 };
 
 typedef void (*dreplsrv_extended_callback_t)(struct dreplsrv_service *,
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c 
b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index 9893ada..b6f9165 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -173,7 +173,8 @@ static int attr_handler(struct oc_context *ac)
                }
 
                if ((attr->linkID & 1) == 1 &&
-                   !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+                   !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+                   !ldb_request_get_control(ac->req, DSDB_CONTROL_DBCHECK)) {
                        /* Odd is for the target.  Illegal to modify */
                        ldb_asprintf_errstring(ldb, 
                                               "objectclass_attrs: attribute 
'%s' on entry '%s' must not be modified directly, it is a linked attribute", 
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 
b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index fff542a..2be0760 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -2179,6 +2179,9 @@ static int replmd_modify_handle_linked_attribs(struct 
ldb_module *module,
                        continue;
                }
                if ((schema_attr->linkID & 1) == 1) {
+                       if (parent && ldb_request_get_control(parent, 
DSDB_CONTROL_DBCHECK)) {
+                               continue;
+                       }
                        /* Odd is for the target.  Illegal to modify */
                        ldb_asprintf_errstring(ldb,
                                               "attribute %s must not be 
modified directly, it is a linked attribute", el->name);
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c 
b/source4/dsdb/samdb/ldb_modules/samldb.c
index b1f6b72..e0400fa 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1458,7 +1458,8 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
        talloc_free(tmp_msg);
 
        ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs,
-                                   DSDB_FLAG_NEXT_MODULE, ac->req);
+                                   DSDB_FLAG_NEXT_MODULE |
+                                   DSDB_SEARCH_SHOW_DELETED, ac->req);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 4c89f24..aedd3db 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -99,6 +99,9 @@ struct dsdb_control_password_change_status {
 /* passed when we want special behaviour for partial replicas */
 #define DSDB_CONTROL_PARTIAL_REPLICA "1.3.6.1.4.1.7165.4.3.18"
 
+/* passed when we want special behaviour for dbcheck */
+#define DSDB_CONTROL_DBCHECK "1.3.6.1.4.1.7165.4.3.19"
+
 struct dsdb_control_password_change {
        const struct samr_Password *old_nt_pwd_hash;
        const struct samr_Password *old_lm_pwd_hash;
diff --git a/source4/scripting/python/samba/dbchecker.py 
b/source4/scripting/python/samba/dbchecker.py
index ea5a903..f19891a 100644
--- a/source4/scripting/python/samba/dbchecker.py
+++ b/source4/scripting/python/samba/dbchecker.py
@@ -201,6 +201,32 @@ class dbcheck(object):
 
 
     ################################################################
+    # handle a DN pointing to a deleted object
+    def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn):
+        self.report("ERROR: target DN is deleted for %s in object %s - %s" % 
(attrname, dn, val))
+        self.report("Target GUID points at deleted DN %s" % correct_dn)
+        if not self.confirm_all('Remove DN link?', 
'remove_all_deleted_DN_links'):
+            self.report("Not removing")
+            return
+        m = ldb.Message()
+        m.dn = dn
+        m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
+        if self.do_modify(m, ["show_recycled:1", "%s:0" % 
dsdb.DSDB_CONTROL_DBCHECK],
+                          "Failed to remove deleted DN attribute %s" % 
attrname):
+            self.report("Removed deleted DN on attribute %s" % attrname)
+
+    ################################################################
+    # handle a missing target DN (both GUID and DN string form are missing)
+    def err_missing_dn_GUID(self, dn, attrname, val, dsdb_dn):
+        # check if its a backlink
+        linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)
+        if (linkID & 1 == 0) and str(dsdb_dn).find('DEL\\0A') == -1:
+            self.report("Not removing dangling forward link")
+            return
+        self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn)
+
+
+    ################################################################
     # handle a missing GUID extended DN component
     def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr):
         self.report("ERROR: %s component for %s in object %s - %s" % (errstr, 
attrname, dn, val))
@@ -209,10 +235,12 @@ class dbcheck(object):
             res = self.samdb.search(base=str(dsdb_dn.dn), scope=ldb.SCOPE_BASE,
                                     attrs=[], controls=controls)
         except ldb.LdbError, (enum, estr):
-            self.report("unable to find object for DN %s - cannot fix (%s)" % 
(dsdb_dn.dn, estr))
+            self.report("unable to find object for DN %s - (%s)" % 
(dsdb_dn.dn, estr))
+            self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn)
             return
         if len(res) == 0:
-            self.report("unable to find object for DN %s - cannot fix" % 
dsdb_dn.dn)
+            self.report("unable to find object for DN %s" % dsdb_dn.dn)
+            self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn)
             return
         dsdb_dn.dn = res[0].dn
 
@@ -230,22 +258,6 @@ class dbcheck(object):
 
 


-- 
Samba Shared Repository

Reply via email to