The branch, master has been updated
       via  c0213308bbde59270f681ce7c55a44bda34a980f (commit)
       via  ce1045983fd294b95dfe91524b5d8b80a35df448 (commit)
       via  5a39817212aa34ef181e9ed72851b077ba088260 (commit)
      from  ae1c2415e23b56db7ffb8dc96425a8588401b03d (commit)

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


- Log -----------------------------------------------------------------
commit c0213308bbde59270f681ce7c55a44bda34a980f
Author: Andrew Tridgell <[email protected]>
Date:   Mon Jun 1 16:37:28 2009 +1000

    we don't need the unique checks in the samldb code now
    
    These attributes now use the unique indexing flag

commit ce1045983fd294b95dfe91524b5d8b80a35df448
Author: Andrew Tridgell <[email protected]>
Date:   Mon Jun 1 16:36:56 2009 +1000

    mark samAccountName, objectGUID and objectSID as unique indexed

commit 5a39817212aa34ef181e9ed72851b077ba088260
Author: Andrew Tridgell <[email protected]>
Date:   Mon Jun 1 16:36:21 2009 +1000

    added support for unique indexing in ldb
    
    When a attribute is marked as LDB_ATTR_FLAG_UNIQUE_INDEX then attempts
    to add a 2nd record that has the same attribute value for this
    attribute as another record will fail.
    
    This provides a much more efficient mechanism for ensuring that
    attributes like objectGUID are unique

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/samldb.c |  164 +------------------------------
 source4/dsdb/schema/schema_init.c       |   20 ++++
 source4/lib/ldb/include/ldb.h           |    6 +
 source4/lib/ldb/ldb_tdb/ldb_index.c     |   33 +++++--
 4 files changed, 54 insertions(+), 169 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c 
b/source4/dsdb/samdb/ldb_modules/samldb.c
index 65e3641..dad5ff2 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -466,91 +466,19 @@ static int samldb_generate_samAccountName(struct 
ldb_message *msg)
        return ldb_msg_add_steal_string(msg, "samAccountName", name);
 }
 
-static int samldb_check_samAccountName_callback(struct ldb_request *req,
-                                               struct ldb_reply *ares)
-{
-       struct samldb_ctx *ac;
-       int ret;
-
-       ac = talloc_get_type(req->context, struct samldb_ctx);
-
-       if (!ares) {
-               ret = LDB_ERR_OPERATIONS_ERROR;
-               goto done;
-       }
-       if (ares->error != LDB_SUCCESS) {
-               return ldb_module_done(ac->req, ares->controls,
-                                       ares->response, ares->error);
-       }
-
-       switch (ares->type) {
-       case LDB_REPLY_ENTRY:
-
-               /* if we get an entry it means this samAccountName
-                * already exists */
-               return ldb_module_done(ac->req, NULL, NULL,
-                                       LDB_ERR_ENTRY_ALREADY_EXISTS);
-
-       case LDB_REPLY_REFERRAL:
-               /* ignore */
-               talloc_free(ares);
-               ret = LDB_SUCCESS;
-               break;
-
-       case LDB_REPLY_DONE:
-
-               /* not found, go on */
-               talloc_free(ares);
-               ret = samldb_next_step(ac);
-               break;
-       }
-
-done:
-       if (ret != LDB_SUCCESS) {
-               return ldb_module_done(ac->req, NULL, NULL, ret);
-       }
-
-       return LDB_SUCCESS;
-}
 
 static int samldb_check_samAccountName(struct samldb_ctx *ac)
 {
-       struct ldb_context *ldb;
-       struct ldb_request *req;
-       const char *name;
-       char *filter;
        int ret;
 
-       ldb = ldb_module_get_ctx(ac->module);
-
        if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
                ret = samldb_generate_samAccountName(ac->msg);
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
        }
-
-       name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
-       if (name == NULL) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-       filter = talloc_asprintf(ac, "samAccountName=%s", name);
-       if (filter == NULL) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = ldb_build_search_req(&req, ldb, ac,
-                               ac->domain_dn, LDB_SCOPE_SUBTREE,
-                               filter, NULL,
-                               NULL,
-                               ac, samldb_check_samAccountName_callback,
-                               ac->req);
-       talloc_free(filter);
-       if (ret != LDB_SUCCESS) {
-               return ret;
-       }
-       ac->ares = NULL;
-       return ldb_next_request(ac->module, req);
+       
+       return samldb_next_step(ac);
 }
 
 static int samldb_check_samAccountType(struct samldb_ctx *ac)
@@ -768,87 +696,6 @@ static int samldb_new_sid(struct samldb_ctx *ac)
        return samldb_next_step(ac);
 }
 
-static int samldb_check_sid_callback(struct ldb_request *req,
-                                    struct ldb_reply *ares)
-{
-       struct samldb_ctx *ac;
-       int ret;
-
-       ac = talloc_get_type(req->context, struct samldb_ctx);
-
-       if (!ares) {
-               ret = LDB_ERR_OPERATIONS_ERROR;
-               goto done;
-       }
-       if (ares->error != LDB_SUCCESS) {
-               return ldb_module_done(ac->req, ares->controls,
-                                       ares->response, ares->error);
-       }
-
-       switch (ares->type) {
-       case LDB_REPLY_ENTRY:
-
-               /* if we get an entry it means an object with the
-                * requested sid exists */
-               return ldb_module_done(ac->req, NULL, NULL,
-                                       LDB_ERR_CONSTRAINT_VIOLATION);
-
-       case LDB_REPLY_REFERRAL:
-               /* ignore */
-               talloc_free(ares);
-               break;
-
-       case LDB_REPLY_DONE:
-
-               /* not found, go on */
-               talloc_free(ares);
-               ret = samldb_next_step(ac);
-               break;
-       }
-
-done:
-       if (ret != LDB_SUCCESS) {
-               return ldb_module_done(ac->req, NULL, NULL, ret);
-       }
-
-       return LDB_SUCCESS;
-}
-
-static int samldb_check_sid(struct samldb_ctx *ac)
-{
-       struct ldb_context *ldb;
-       const char *const attrs[2] = { "objectSid", NULL };
-       struct ldb_request *req;
-       char *filter;
-       int ret;
-
-       if (ac->sid == NULL) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ldb = ldb_module_get_ctx(ac->module);
-
-       filter = talloc_asprintf(ac, "(objectSid=%s)",
-                                ldap_encode_ndr_dom_sid(ac, ac->sid));
-       if (filter == NULL) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = ldb_build_search_req(&req, ldb, ac,
-                                  ldb_get_default_basedn(ldb),
-                                  LDB_SCOPE_SUBTREE,
-                                  filter, attrs,
-                                  NULL,
-                                  ac, samldb_check_sid_callback,
-                                  ac->req);
-
-       if (ret != LDB_SUCCESS) {
-               return ret;
-       }
-
-       return ldb_next_request(ac->module, req);
-}
-
 static int samldb_notice_sid_callback(struct ldb_request *req,
                                        struct ldb_reply *ares)
 {
@@ -1051,9 +898,6 @@ static int samldb_fill_object(struct samldb_ctx *ac, const 
char *type)
                if (ret != LDB_SUCCESS) return ret;
        }
 
-       ret = samldb_add_step(ac, samldb_check_sid);
-       if (ret != LDB_SUCCESS) return ret;
-
        ret = samldb_add_step(ac, samldb_notice_sid);
        if (ret != LDB_SUCCESS) return ret;
 
@@ -1228,10 +1072,6 @@ static int 
samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
        ret = samldb_add_step(ac, samldb_apply_template);
        if (ret != LDB_SUCCESS) return ret;
 
-       /* check we do not already have this SID */
-       ret = samldb_add_step(ac, samldb_check_sid);
-       if (ret != LDB_SUCCESS) return ret;
-
        /* check if we need to notice this SID */
        ret = samldb_add_step(ac, samldb_foreign_notice_sid);
        if (ret != LDB_SUCCESS) return ret;
diff --git a/source4/dsdb/schema/schema_init.c 
b/source4/dsdb/schema/schema_init.c
index 3a65c47..76e7891 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -583,6 +583,22 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, 
struct ldb_context *ldb,
        return WERR_OK;
 }
 
+/*
+  this will be replaced with something that looks at the right part of
+  the schema once we know where unique indexing information is hidden
+ */
+static bool dsdb_schema_unique_attribute(const char *attr)
+{
+       const char *attrs[] = { "samAccountName", "objectGUID", "objectSID" , 
NULL };
+       int i;
+       for (i=0;attrs[i];i++) {
+               if (strcasecmp(attr, attrs[i]) == 0) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 
 /*
   setup the ldb_schema_attribute field for a dsdb_attribute
@@ -619,6 +635,10 @@ static int dsdb_schema_setup_ldb_schema_attribute(struct 
ldb_context *ldb,
        a->name = attr->lDAPDisplayName;
        a->flags = 0;
        a->syntax = s;
+
+       if (dsdb_schema_unique_attribute(a->name)) {
+               a->flags |= LDB_ATTR_FLAG_UNIQUE_INDEX;
+       }
        
        return LDB_SUCCESS;
 }
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 1b6b41a..8e4e2e0 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -375,6 +375,12 @@ const struct ldb_dn_extended_syntax 
*ldb_dn_extended_syntax_by_name(struct ldb_c
 */
 #define LDB_ATTR_FLAG_FIXED        (1<<2) 
 
+/*
+  when this is set, attempts to create two records which have the same
+  value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS
+ */
+#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3)
+
 /**
   LDAP attribute syntax for a DN
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c 
b/source4/lib/ldb/ldb_tdb/ldb_index.c
index db0c315..300cf7c 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -426,7 +426,8 @@ struct dn_list {
   caller frees
 */
 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
-                                    const char *attr, const struct ldb_val 
*value)
+                                    const char *attr, const struct ldb_val 
*value,
+                                    const struct ldb_schema_attribute **ap)
 {
        struct ldb_dn *ret;
        struct ldb_val v;
@@ -440,6 +441,9 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context 
*ldb,
        }
 
        a = ldb_schema_attribute_by_name(ldb, attr);
+       if (ap) {
+               *ap = a;
+       }
        r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
        if (r != LDB_SUCCESS) {
                const char *errstr = ldb_errstring(ldb);
@@ -531,7 +535,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
 
        /* the attribute is indexed. Pull the list of DNs that match the 
           search criterion */
-       dn = ltdb_index_key(ldb, tree->u.equality.attr, 
&tree->u.equality.value);
+       dn = ltdb_index_key(ldb, tree->u.equality.attr, 
&tree->u.equality.value, NULL);
        if (!dn) return LDB_ERR_OPERATIONS_ERROR;
 
        msg = talloc(list, struct ldb_message);
@@ -851,6 +855,11 @@ static int ltdb_index_dn_and(struct ldb_module *module,
                        talloc_free(list->dn);
                        return LDB_ERR_NO_SUCH_OBJECT;
                }
+
+               if (list->count == 1) {
+                       /* it isn't worth loading the next part of the tree */
+                       break;
+               }
        }
 
        return ret;
@@ -882,7 +891,7 @@ static int ltdb_index_dn_one(struct ldb_module *module,
           search criterion */
        val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
        val.length = strlen((char *)val.data);
-       key = ltdb_index_key(ldb, LTDB_IDXONE, &val);
+       key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
        if (!key) {
                talloc_free(list2);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -1181,7 +1190,8 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
 static int ltdb_index_add1_add(struct ldb_context *ldb,
                               struct ldb_message *msg,
                               int idx,
-                              const char *dn)
+                              const char *dn,
+                              const struct ldb_schema_attribute *a)
 {
        struct ldb_val *v2;
        unsigned int i;
@@ -1193,6 +1203,10 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
                }
        }
 
+       if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
+               return LDB_ERR_ENTRY_ALREADY_EXISTS;
+       }
+
        v2 = talloc_realloc(msg->elements, msg->elements[idx].values,
                              struct ldb_val,
                              msg->elements[idx].num_values+1);
@@ -1219,6 +1233,7 @@ static int ltdb_index_add1(struct ldb_module *module, 
const char *dn,
        struct ldb_dn *dn_key;
        int ret;
        unsigned int i;
+       const struct ldb_schema_attribute *a;
 
        ldb = ldb_module_get_ctx(module);
 
@@ -1228,7 +1243,7 @@ static int ltdb_index_add1(struct ldb_module *module, 
const char *dn,
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx]);
+       dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
        if (!dn_key) {
                talloc_free(msg);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -1256,7 +1271,7 @@ static int ltdb_index_add1(struct ldb_module *module, 
const char *dn,
        if (i == msg->num_elements) {
                ret = ltdb_index_add1_new(ldb, msg, dn);
        } else {
-               ret = ltdb_index_add1_add(ldb, msg, i, dn);
+               ret = ltdb_index_add1_add(ldb, msg, i, dn, a);
        }
 
        if (ret == LDB_SUCCESS) {
@@ -1339,7 +1354,7 @@ int ltdb_index_del_value(struct ldb_module *module, const 
char *dn,
                return LDB_SUCCESS;
        }
 
-       dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx]);
+       dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
        if (!dn_key) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -1455,6 +1470,10 @@ int ltdb_index_one(struct ldb_module *module, const 
struct ldb_message *msg, int
        const char *dn;
        int ret;
 
+       if (ldb_dn_is_special(msg->dn)) {
+               return LDB_SUCCESS;
+       }
+
        /* We index for ONE Level only if requested */
        ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
        if (ret != 0) {


-- 
Samba Shared Repository

Reply via email to