From 9189833a8753a723a8b8d0af9c8b096571b06a84 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 14 Jun 2005 19:15:17 +0000 Subject: r7582: Better way to have a fast path searching for a specific DN. Old way was ugly and had a bug, you couldn't add an attribute named dn or distinguishedName and search for it, tdb would change that search in a dn search. This makes it also possible to search by dn against an ldap server as the old method was not supported by ldap syntaxes. sss (This used to be commit a614466dec2484a0d39bdfae53da822cfcf80926) --- source4/dsdb/samdb/samdb.c | 8 ++-- source4/lib/gendb.c | 31 +++++++++++++++- source4/lib/ldb/Makefile.in | 2 + source4/lib/ldb/ldb_ldap/ldb_ldap.c | 4 ++ source4/lib/ldb/ldb_tdb/ldb_search.c | 23 ++++++------ source4/lib/ldb/ldb_tdb/ldb_tdb.h | 2 +- source4/lib/ldb/tests/start_slapd.sh | 2 + source4/rpc_server/lsa/dcesrv_lsa.c | 31 +++++++--------- source4/rpc_server/samr/dcesrv_samr.c | 66 +++++++++++++++------------------ source4/rpc_server/samr/samr_password.c | 13 +++---- 10 files changed, 103 insertions(+), 79 deletions(-) (limited to 'source4') diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index b337577ae7..642cff1a7a 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -370,8 +370,8 @@ NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb, return 0; } - minPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, NULL, - "minPwdAge", "dn=%s", domain_dn); + minPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, + domain_dn, "minPwdAge", NULL); /* yes, this is a -= not a += as minPwdAge is stored as the negative of the number of 100-nano-seconds */ @@ -397,7 +397,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb, return 0; } - maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, NULL, "maxPwdAge", "dn=%s", domain_dn); + maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, "maxPwdAge", NULL); if (maxPwdAge == 0) { return 0; } else { @@ -605,7 +605,7 @@ static NTSTATUS _samdb_allocate_next_id(struct ldb_context *sam_ldb, TALLOC_CTX struct ldb_val vals[2]; struct ldb_message_element els[2]; - str = samdb_search_string(sam_ldb, mem_ctx, NULL, attr, "dn=%s", dn); + str = samdb_search_string(sam_ldb, mem_ctx, dn, attr, NULL); if (!str) { DEBUG(1,("id not found at %s %s\n", dn, attr)); return NT_STATUS_OBJECT_NAME_INVALID; diff --git a/source4/lib/gendb.c b/source4/lib/gendb.c index 5b4f7b251e..dc5b7f39aa 100644 --- a/source4/lib/gendb.c +++ b/source4/lib/gendb.c @@ -61,7 +61,7 @@ int gendb_search_v(struct ldb_context *ldb, /* search the LDB for the specified attributes - varargs variant */ -int gendb_search(struct ldb_context *sam_ldb, +int gendb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *basedn, struct ldb_message ***res, @@ -72,12 +72,39 @@ int gendb_search(struct ldb_context *sam_ldb, int count; va_start(ap, format); - count = gendb_search_v(sam_ldb, mem_ctx, basedn, res, attrs, format, ap); + count = gendb_search_v(ldb, mem_ctx, basedn, res, attrs, format, ap); va_end(ap); return count; } +int gendb_search_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *dn, + struct ldb_message ***res, + const char * const *attrs) +{ + va_list ap; + int count; + + *res = NULL; + + count = ldb_search(ldb, dn, LDB_SCOPE_BASE, "", attrs, res); + + if (count > 1) { + DEBUG(1, ("DB Corruption ? - Found more then one entry for dn: %s", dn)); + return -1; + } + + if (*res) talloc_steal(mem_ctx, *res); + + DEBUG(4,("gendb_search_dn: %s -> %d (%s)\n", + dn, count, count==-1?ldb_errstring(ldb):"OK")); + + return count; +} + + /* setup some initial ldif in a ldb */ diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in index 3bfae08c27..88935b6f3a 100644 --- a/source4/lib/ldb/Makefile.in +++ b/source4/lib/ldb/Makefile.in @@ -148,9 +148,11 @@ test-sqlite3: @echo "SKIP SQLITE3 TEST - NO SQLITE3 SUPPORT" endif +ifeq (1,0) test-schema: @echo "STARTING SCHEMA MODULE TEST" tests/test-schema.sh +endif test: $(BINS) test-tdb test-ldap test-sqlite3 test-schema diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index fceaf02196..b3d8fcc1a5 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -196,6 +196,10 @@ static int lldb_search(struct ldb_module *module, const char *base, base = ""; } + if (expression == NULL || expression[0] == '\0') { + expression = "objectClass=*"; + } + lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope, expression, discard_const_p(char *, attrs), diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 17eff6f0a6..d210510ff2 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -272,7 +272,7 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag /* search the database for a single simple dn */ -int ltdb_search_dn(struct ldb_module *module, char *dn, +int ltdb_search_dn(struct ldb_module *module, const char *dn, const char * const attrs[], struct ldb_message ***res) { struct ldb_context *ldb = module->ldb; @@ -482,17 +482,9 @@ int ltdb_search_bytree(struct ldb_module *module, const char *base, *res = NULL; - if (tree->operation == LDB_OP_SIMPLE && - (ldb_attr_cmp(tree->u.simple.attr, "dn") == 0 || - ldb_attr_cmp(tree->u.simple.attr, "distinguishedName") == 0) && - !ltdb_has_wildcard(module, tree->u.simple.attr, &tree->u.simple.value)) { - /* yay! its a nice simple one */ - ret = ltdb_search_dn(module, tree->u.simple.value.data, attrs, res); - } else { - ret = ltdb_search_indexed(module, base, scope, tree, attrs, res); - if (ret == -1) { - ret = ltdb_search_full(module, base, scope, tree, attrs, res); - } + ret = ltdb_search_indexed(module, base, scope, tree, attrs, res); + if (ret == -1) { + ret = ltdb_search_full(module, base, scope, tree, attrs, res); } ltdb_unlock_read(module); @@ -513,6 +505,13 @@ int ltdb_search(struct ldb_module *module, const char *base, struct ldb_parse_tree *tree; int ret; + /* check if we are looking for a simple dn */ + if (scope == LDB_SCOPE_BASE && (expression == NULL || expression[0] == '\0')) { + ret = ltdb_search_dn(module, base, attrs, res); + ltdb_unlock_read(module); + return ret; + } + tree = ldb_parse_tree(ltdb, expression); if (tree == NULL) { ltdb->last_err_string = "expression parse failed"; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 891522f300..b77e02fba5 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -91,7 +91,7 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, const struct ldb_val *val); void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_message *msg); -int ltdb_search_dn(struct ldb_module *module, char *dn, +int ltdb_search_dn(struct ldb_module *module, const char *dn, const char * const attrs[], struct ldb_message ***res); int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, const char * const attrs[], diff --git a/source4/lib/ldb/tests/start_slapd.sh b/source4/lib/ldb/tests/start_slapd.sh index a7ec69c855..6dd3eaa9b8 100755 --- a/source4/lib/ldb/tests/start_slapd.sh +++ b/source4/lib/ldb/tests/start_slapd.sh @@ -3,3 +3,5 @@ mkdir -p tests/tmp/db slapd -f tests/slapd.conf -h "`tests/ldapi_url.sh`" $* + +sleep 2 diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index ea803559c4..b3de4e4ba1 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -266,8 +266,8 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ return NT_STATUS_NO_SUCH_DOMAIN; } - sid_str = samdb_search_string(state->sam_ldb, mem_ctx, NULL, - "objectSid", "dn=%s", state->domain_dn); + sid_str = samdb_search_string(state->sam_ldb, mem_ctx, + state->domain_dn, "objectSid", NULL); if (!sid_str) { return NT_STATUS_NO_SUCH_DOMAIN; } @@ -283,8 +283,8 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ } state->domain_name = talloc_reference(state, - samdb_search_string(state->sam_ldb, mem_ctx, NULL, - "name", "dn=%s", state->domain_dn)); + samdb_search_string(state->sam_ldb, mem_ctx, + state->domain_dn, "name", NULL)); if (!state->domain_name) { return NT_STATUS_NO_SUCH_DOMAIN; } @@ -359,8 +359,7 @@ static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CT int ret; struct ldb_message **res; - ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, - "dn=%s", state->domain_dn); + ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -381,8 +380,7 @@ static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx int ret; struct ldb_message **res; - ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, - "dn=%s", state->domain_dn); + ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -850,8 +848,8 @@ static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, T trusted_domain_state = h->data; /* pull all the user attributes */ - ret = gendb_search(trusted_domain_state->policy->sam_ldb, mem_ctx, NULL, &res, attrs, - "dn=%s", trusted_domain_state->trusted_domain_dn); + ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx, + trusted_domain_state->trusted_domain_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1373,8 +1371,8 @@ static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, r->out.privs->unknown = 0; r->out.privs->set = NULL; - ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, - "dn=%s", astate->account_dn); + ret = gendb_search_dn(astate->policy->sam_ldb, mem_ctx, + astate->account_dn, &res, attrs); if (ret != 1) { return NT_STATUS_OK; } @@ -2048,9 +2046,8 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me }; /* search for the secret record */ - ret = gendb_search(secret_state->sam_ldb, - mem_ctx, NULL, &res, attrs, - "(dn=%s)", secret_state->secret_dn); + ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx, + secret_state->secret_dn, &res, attrs); if (ret == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -2121,8 +2118,8 @@ static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX * secret_state = h->data; /* pull all the user attributes */ - ret = gendb_search(secret_state->sam_ldb, mem_ctx, NULL, &res, attrs, - "dn=%s", secret_state->secret_dn); + ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx, + secret_state->secret_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index b40028b880..337c300203 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -343,8 +343,8 @@ static NTSTATUS samr_info_DomInfo1(struct samr_domain_state *state, int ret; struct ldb_message **res; - ret = gendb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", state->domain_dn); + ret = gendb_search_dn(state->sam_ctx, mem_ctx, + state->domain_dn , &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -373,8 +373,8 @@ static NTSTATUS samr_info_DomInfo2(struct samr_domain_state *state, TALLOC_CTX * int ret; struct ldb_message **res; - ret = gendb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", state->domain_dn); + ret = gendb_search_dn(state->sam_ctx, mem_ctx, + state->domain_dn , &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -527,10 +527,8 @@ static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLO a_state->account_dn = talloc_steal(a_state, msg->dn); /* retrieve the sidstring for the group just created */ - sidstr = samdb_search_string(d_state->sam_ctx, a_state, NULL, - "objectSid", - "dn=%s", - msg->dn); + sidstr = samdb_search_string(d_state->sam_ctx, a_state, + msg->dn, "objectSid", NULL); if (sidstr == NULL) { return NT_STATUS_UNSUCCESSFUL; } @@ -759,10 +757,8 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX a_state->account_dn = talloc_steal(a_state, msg->dn); /* retrieve the sidstring for the group just created */ - sidstr = samdb_search_string(d_state->sam_ctx, a_state, NULL, - "objectSid", - "dn=%s", - msg->dn); + sidstr = samdb_search_string(d_state->sam_ctx, a_state, + msg->dn, "objectSid", NULL); if (sidstr == NULL) { return NT_STATUS_UNSUCCESSFUL; } @@ -965,10 +961,8 @@ static NTSTATUS samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_C a_state->account_dn = talloc_steal(a_state, msg->dn); /* retrieve the sidstring for the group just created */ - sidstr = samdb_search_string(d_state->sam_ctx, a_state, NULL, - "objectSid", - "dn=%s", - msg->dn); + sidstr = samdb_search_string(d_state->sam_ctx, a_state, + msg->dn, "objectSid", NULL); if (sidstr == NULL) { return NT_STATUS_UNSUCCESSFUL; } @@ -1490,8 +1484,8 @@ static NTSTATUS samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_C a_state = h->data; /* pull all the group attributes */ - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + a_state->account_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1750,8 +1744,8 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC a_state = h->data; /* pull the member attribute */ - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + a_state->account_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -1784,9 +1778,9 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC for (i=0; inum_values; i++) { struct ldb_message **res2; const char * const attrs2[2] = { "objectSid", NULL }; - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, - &res2, attrs2, "dn=%s", - (char *)el->values[i].data); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + (char *)el->values[i].data, + &res2, attrs2); if (ret != 1) return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -1916,8 +1910,8 @@ static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_C a_state = h->data; /* pull all the alias attributes */ - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + a_state->account_dn ,&res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -2229,8 +2223,8 @@ static NTSTATUS samr_GetMembersInAlias(struct dcesrv_call_state *dce_call, TALLO a_state = h->data; d_state = a_state->domain_state; - ret = gendb_search(d_state->sam_ctx, mem_ctx, NULL, &msgs, attrs, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(d_state->sam_ctx, mem_ctx, + a_state->account_dn, &msgs, attrs); if (ret != 1) return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2252,9 +2246,9 @@ static NTSTATUS samr_GetMembersInAlias(struct dcesrv_call_state *dce_call, TALLO for (i=0; inum_values; i++) { struct ldb_message **msgs2; const char * const attrs2[2] = { "objectSid", NULL }; - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, - &msgs2, attrs2, "dn=%s", - (char *)el->values[i].data); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + (char *)el->values[i].data, + &msgs2, attrs2); if (ret != 1) return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2391,8 +2385,8 @@ static NTSTATUS samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CT a_state = h->data; /* pull all the user attributes */ - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, &res, NULL, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + a_state->account_dn ,&res, NULL); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -3117,10 +3111,10 @@ static NTSTATUS samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CT a_state = h->data; - r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, NULL, "minPwdLength", - "dn=%s", a_state->domain_state->domain_dn); - r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, NULL, "pwdProperties", - "dn=%s", a_state->account_dn); + r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, + a_state->domain_state->domain_dn, "minPwdLength", NULL); + r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, + a_state->account_dn, "pwdProperties", NULL); return NT_STATUS_OK; } diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index f5390cc1d5..e7f547bbf3 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -50,8 +50,8 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX a_state = h->data; /* fetch the old hashes */ - ret = gendb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, - "dn=%s", a_state->account_dn); + ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + a_state->account_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -400,9 +400,8 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, return NT_STATUS_OK; failed: - ret = gendb_search(sam_ctx, - mem_ctx, NULL, &res, dom_attrs, - "dn=%s", domain_dn); + ret = gendb_search_dn(sam_ctx, mem_ctx, + domain_dn, &res, dom_attrs); if (ret != 1) { return status; @@ -517,7 +516,7 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, unix_to_nt_time(&now_nt, now); /* pull all the user parameters */ - count = gendb_search(ctx, mem_ctx, NULL, &res, user_attrs, "dn=%s", user_dn); + count = gendb_search_dn(ctx, mem_ctx, user_dn, &res, user_attrs); if (count != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -533,7 +532,7 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0); /* pull the domain parameters */ - count = gendb_search(ctx, mem_ctx, NULL, &res, domain_attrs, "dn=%s", domain_dn); + count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, domain_attrs); if (count != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit