summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-11-03 12:34:47 +0100
committerStefan Metzmacher <metze@samba.org>2010-11-03 18:31:16 +0000
commit05088fb855a1fc043c3f75d01742cdbbfbb3330e (patch)
treedfadc6f449aa6e5a252ecbd58b1c306dd5b7e5c9
parent54d4ba7103d15a096cdd08ac21fca30811fbd48c (diff)
downloadsamba-05088fb855a1fc043c3f75d01742cdbbfbb3330e.tar.gz
samba-05088fb855a1fc043c3f75d01742cdbbfbb3330e.tar.bz2
samba-05088fb855a1fc043c3f75d01742cdbbfbb3330e.zip
s4:dsdb/samldb: avoid nested unindexed searches in samldb_member_check()
With 20000 objects in the database it's no fun to add members... metze
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 73776abc25..be8eb1abfc 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1368,13 +1368,33 @@ static int samldb_sam_accountname_check(struct samldb_ctx *ac)
static int samldb_member_check(struct samldb_ctx *ac)
{
+ static const char * const attrs[] = { "objectSid", "member", NULL };
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
struct ldb_message_element *el;
- struct ldb_dn *member_dn, *group_dn;
+ struct ldb_dn *member_dn;
uint32_t prim_group_rid;
struct dom_sid *sid;
+ struct ldb_result *res;
+ struct dom_sid *group_sid;
unsigned int i, j;
int cnt;
+ int ret;
+
+ /* Fetch informations from the existing object */
+
+ ret = ldb_search(ldb, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (res->count != 1) {
+ return ldb_operr(ldb);
+ }
+
+ group_sid = samdb_result_dom_sid(res, res->msgs[0], "objectSid");
+ if (group_sid == NULL) {
+ return ldb_operr(ldb);
+ }
/* We've to walk over all modification entries and consider the "member"
* ones. */
@@ -1385,6 +1405,8 @@ 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;
+
member_dn = ldb_dn_from_ldb_val(ac, ldb,
&el->values[j]);
if (!ldb_dn_validate(member_dn)) {
@@ -1404,12 +1426,14 @@ static int samldb_member_check(struct samldb_ctx *ac)
* ERR_NO_SUCH_ATTRIBUTE!)
* - primary group check
*/
- cnt = samdb_search_count(ldb, ac, ac->msg->dn,
- "(member=%s)",
- ldb_dn_get_linearized(member_dn));
- if (cnt < 0) {
- return ldb_operr(ldb);
+ 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;
@@ -1440,14 +1464,7 @@ static int samldb_member_check(struct samldb_ctx *ac)
return ldb_operr(ldb);
}
- group_dn = samdb_search_dn(ldb, ac, NULL,
- "(objectSid=%s)",
- ldap_encode_ndr_dom_sid(ac, sid));
- if (group_dn == NULL) {
- return ldb_operr(ldb);
- }
-
- if (ldb_dn_compare(group_dn, ac->msg->dn) == 0) {
+ if (dom_sid_equal(group_sid, sid)) {
return LDB_ERR_ENTRY_ALREADY_EXISTS;
}
}