ldb: changed DN matching rules to obey GUID/SID/string ordering
authorAndrew Tridgell <tridge@samba.org>
Tue, 2 Aug 2011 07:15:28 +0000 (17:15 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 4 Aug 2011 06:17:25 +0000 (16:17 +1000)
when matching two DNs, the GUID takes priority, then the SID, then the
string component

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
Pair-Programmed-With: Amitay Isaacs <amitay@gmail.com>

lib/ldb-samba/ldif_handlers.c

index ca6fa74b009c42e292e0ac5a519326bea65ceea2..a89749750ffb53dedd5d0380aaf96bdfe7b4a832 100644 (file)
@@ -1118,6 +1118,52 @@ static int samba_syntax_operator_fn(struct ldb_context *ldb, enum ldb_parse_op o
        return LDB_ERR_INAPPROPRIATE_MATCHING;
 }
 
+/*
+  see if two DNs match, comparing first by GUID, then by SID, and
+  finally by string components
+ */
+static int samba_dn_extended_match(struct ldb_context *ldb,
+                                  const struct ldb_val *v1,
+                                  const struct ldb_val *v2,
+                                  bool *matched)
+{
+       TALLOC_CTX *tmp_ctx;
+       struct ldb_dn *dn1, *dn2;
+       const struct ldb_val *guid1, *guid2, *sid1, *sid2;
+
+       tmp_ctx = talloc_new(ldb);
+
+       dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v1);
+       dn2 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v2);
+       if (!dn1 || !dn2) {
+               /* couldn't parse as DN's */
+               talloc_free(tmp_ctx);
+               (*matched) = false;
+               return LDB_SUCCESS;
+       }
+
+       guid1 = ldb_dn_get_extended_component(dn1, "GUID");
+       guid2 = ldb_dn_get_extended_component(dn2, "GUID");
+       if (guid1 && guid2) {
+               (*matched) = (data_blob_cmp(guid1, guid2) == 0);
+               talloc_free(tmp_ctx);
+               return LDB_SUCCESS;
+       }
+
+       sid1 = ldb_dn_get_extended_component(dn1, "SID");
+       sid2 = ldb_dn_get_extended_component(dn2, "SID");
+       if (sid1 && sid2) {
+               (*matched) = (data_blob_cmp(sid1, sid2) == 0);
+               talloc_free(tmp_ctx);
+               return LDB_SUCCESS;
+       }
+
+       (*matched) = (ldb_dn_compare(dn1, dn2) == 0);
+
+       talloc_free(tmp_ctx);
+       return LDB_SUCCESS;
+}
+
 /*
   special operation for DNs, to take account of the RMD_FLAGS deleted bit
  */
@@ -1127,9 +1173,17 @@ static int samba_syntax_operator_dn(struct ldb_context *ldb, enum ldb_parse_op o
 {
        if (operation == LDB_OP_PRESENT && dsdb_dn_is_deleted_val(v1)) {
                /* If the DN is deleted, then we can't search for it */
+
+               /* should this be for equality too? */
                *matched = false;
                return LDB_SUCCESS;
        }
+
+       if (operation == LDB_OP_EQUALITY &&
+           samba_dn_extended_match(ldb, v1, v2, matched) == LDB_SUCCESS) {
+               return LDB_SUCCESS;
+       }
+
        return samba_syntax_operator_fn(ldb, operation, a, v1, v2, matched);
 }