r19831: Big ldb_dn optimization and interfaces enhancement patch
authorSimo Sorce <idra@samba.org>
Wed, 22 Nov 2006 00:59:34 +0000 (00:59 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:28:22 +0000 (14:28 -0500)
This patch changes a lot of the code in ldb_dn.c, and also
removes and add a number of manipulation functions around.

The aim is to avoid validating a dn if not necessary as the
validation code is necessarily slow. This is mainly to speed up
internal operations where input is not user generated and so we
can assume the DNs need no validation. The code is designed to
keep the data as a string if possible.

The code is not yet 100% perfect, but pass all the tests so far.
A memleak is certainly present, I'll work on that next.

Simo.

80 files changed:
source/auth/auth_sam.c
source/auth/credentials/credentials_files.c
source/auth/gensec/schannel_state.c
source/auth/sam.c
source/cldap_server/netlogon.c
source/cldap_server/rootdse.c
source/dsdb/samdb/cracknames.c
source/dsdb/samdb/ldb_modules/entryUUID.c
source/dsdb/samdb/ldb_modules/extended_dn.c
source/dsdb/samdb/ldb_modules/kludge_acl.c
source/dsdb/samdb/ldb_modules/local_password.c
source/dsdb/samdb/ldb_modules/partition.c
source/dsdb/samdb/ldb_modules/password_hash.c
source/dsdb/samdb/ldb_modules/proxy.c
source/dsdb/samdb/ldb_modules/rootdse.c
source/dsdb/samdb/ldb_modules/samldb.c
source/dsdb/samdb/ldb_modules/schema.c
source/dsdb/samdb/ldb_modules/schema_syntax.c
source/dsdb/samdb/ldb_modules/schema_syntax.h
source/dsdb/samdb/samdb.c
source/kdc/hdb-ldb.c
source/ldap_server/ldap_backend.c
source/ldap_server/ldap_server.c
source/lib/gendb.c
source/lib/ldb/common/attrib_handlers.c
source/lib/ldb/common/ldb.c
source/lib/ldb/common/ldb_dn.c
source/lib/ldb/common/ldb_ldif.c
source/lib/ldb/common/ldb_match.c
source/lib/ldb/common/ldb_modules.c
source/lib/ldb/common/ldb_msg.c
source/lib/ldb/include/ldb.h
source/lib/ldb/include/ldb_private.h
source/lib/ldb/ldb_ildap/ldb_ildap.c
source/lib/ldb/ldb_ldap/ldb_ldap.c
source/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
source/lib/ldb/ldb_tdb/ldb_cache.c
source/lib/ldb/ldb_tdb/ldb_index.c
source/lib/ldb/ldb_tdb/ldb_pack.c
source/lib/ldb/ldb_tdb/ldb_search.c
source/lib/ldb/ldb_tdb/ldb_tdb.c
source/lib/ldb/ldb_tdb/ldb_tdb.h
source/lib/ldb/modules/asq.c
source/lib/ldb/modules/ldb_map.c
source/lib/ldb/modules/ldb_map.h
source/lib/ldb/modules/ldb_map_private.h
source/lib/ldb/modules/paged_searches.c
source/lib/ldb/nssldb/ldb-nss.c
source/lib/ldb/nssldb/ldb-nss.h
source/lib/ldb/samba/ldif_handlers.c
source/lib/ldb/tests/test-ldap.sh
source/lib/ldb/tools/ad2oLschema.c
source/lib/ldb/tools/ldbdel.c
source/lib/ldb/tools/ldbedit.c
source/lib/ldb/tools/ldbrename.c
source/lib/ldb/tools/ldbsearch.c
source/lib/ldb/tools/ldbtest.c
source/lib/ldb/tools/oLschema2ldif.c
source/lib/registry/reg_backend_ldb.c
source/libnet/libnet_join.c
source/libnet/libnet_samsync_ldb.c
source/libnet/libnet_site.c
source/nbt_server/dgram/netlogon.c
source/nbt_server/wins/winsdb.c
source/ntptr/simple_ldb/ntptr_simple_ldb.c
source/param/secrets.c
source/param/share_ldb.c
source/rpc_server/drsuapi/dcesrv_drsuapi.c
source/rpc_server/lsa/dcesrv_lsa.c
source/rpc_server/netlogon/dcerpc_netlogon.c
source/rpc_server/samr/dcesrv_samr.c
source/rpc_server/samr/dcesrv_samr.h
source/rpc_server/samr/samr_password.c
source/scripting/ejs/smbcalls_ldb.c
source/torture/ldap/cldap.c
source/torture/ldap/schema.c
source/torture/local/dbspeed.c
source/torture/rpc/drsuapi_cracknames.c
source/torture/rpc/testjoin.c
source/wrepl_server/wrepl_server.c

index 8bfcab1eafbd2f08a442cd9c4a58d55b8e48d215..08ba75e4f643723e5406c58e6de9f3dccdf39e17 100644 (file)
@@ -47,12 +47,12 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
        struct ldb_message **msgs_tmp;
        struct ldb_message **msgs;
        struct ldb_message **msgs_domain_ref;
-       const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
+       struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
 
        int ret;
        int ret_domain;
 
-       const struct ldb_dn *domain_dn = NULL;
+       struct ldb_dn *domain_dn = NULL;
 
        if (domain_name) {
                char *escaped_domain = ldb_binary_encode_string(mem_ctx, domain_name);
@@ -76,7 +76,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
-               domain_dn = samdb_result_dn(mem_ctx, msgs_domain_ref[0], "nCName", NULL);
+               domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msgs_domain_ref[0], "nCName", NULL);
        }
 
        /* pull the user attributes */
index ecd89d2259d792dce38f3bcfb25b35e09cca87cb..1cbc9d9c15d61c06e2d87643946ca3fb8ba6e646 100644 (file)
@@ -220,7 +220,7 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 
        /* search for the secret record */
        ldb_ret = gendb_search(ldb,
-                              mem_ctx, ldb_dn_explode(mem_ctx, base), 
+                              mem_ctx, ldb_dn_new(mem_ctx, ldb, base), 
                               &msgs, attrs,
                               "%s", filter);
        if (ldb_ret == 0) {
index 3c9ff6414766989dff18e4205cdbe0d6e4dfc4be..7ba35abd19470d022140fb2b4fe26423d0e30083 100644 (file)
@@ -93,8 +93,8 @@ NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       msg->dn = ldb_dn_build_child(msg, "computerName", creds->computer_name, NULL);
-       if (msg->dn == NULL) {
+       msg->dn = ldb_dn_new_fmt(msg, ldb, "computerName=%s", creds->computer_name);
+       if ( ! msg->dn) {
                return NT_STATUS_NO_MEMORY;
        }
 
index c7f0a74ac985a5e12046a5355d380ef35423c5db..34ce34540a28bfbae9c2c82748b78fe694f3d00b 100644 (file)
@@ -89,7 +89,7 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
        NTTIME must_change_time;
        NTTIME last_set_time;
 
-       struct ldb_dn *domain_dn = samdb_result_dn(mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx));
+       struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx, sam_ctx, NULL));
 
        NTTIME now;
        DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
@@ -287,7 +287,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
        server_info->acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
        server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
 
-       ncname = samdb_result_dn(mem_ctx, msg_domain_ref, "nCName", NULL);
+       ncname = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
        if (!ncname) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -322,7 +322,7 @@ _PUBLIC_ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
        NTSTATUS nt_status;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        int ret;
-       const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
+       struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
 
        if (!tmp_ctx) {
                return NT_STATUS_NO_MEMORY;
index fd00c43cda21f85e9e77abe052a01e570e4d39fb..6de505659faec9ba4aa6193354dcc27743be6d91 100644 (file)
@@ -62,7 +62,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
        const char *server_site;
        const char *client_site;
        const char *pdc_ip;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        partitions_basedn = samdb_partitions_dn(cldapd->samctx, mem_ctx);
 
@@ -79,7 +79,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
                                   "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))", 
                                   domain);
                if (count == 1) {
-                       dom_dn = samdb_result_dn(mem_ctx, ref_res[0], "ncName", NULL);
+                       dom_dn = samdb_result_dn(cldapd->samctx, mem_ctx, ref_res[0], "ncName", NULL);
                        if (!dom_dn) {
                                return NT_STATUS_NO_SUCH_DOMAIN;
                        }
index 966b90889c1b06c699f071ef69b2525801e81b85..0690e8769ab16a6cc0c17444f292cc98b0228b8e 100644 (file)
@@ -51,7 +51,7 @@ static void cldapd_rootdse_fill(struct cldapd_server *cldapd,
        int ret = 0;
        int ldb_ret = -1;
 
-       basedn = ldb_dn_explode(mem_ctx, "");
+       basedn = ldb_dn_new(mem_ctx, cldapd->samctx, NULL);
        if (basedn == NULL) goto nomem;
        scope = LDB_SCOPE_BASE;
 
index eb051a0fb2deb56b290ff813bc37a7ff3569d427..16aa616983c4b413f3d31453a1c756ee6ac44d74 100644 (file)
 static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
                                   struct smb_krb5_context *smb_krb5_context,
                                   uint32_t format_flags, uint32_t format_offered, uint32_t format_desired,
-                                  const struct ldb_dn *name_dn, const char *name, 
+                                  struct ldb_dn *name_dn, const char *name, 
                                   const char *domain_filter, const char *result_filter, 
                                   struct drsuapi_DsNameInfo1 *info1);
 static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx,
                                        uint32_t format_offered, uint32_t format_desired,
-                                       const struct ldb_dn *name_dn, const char *name, 
+                                       struct ldb_dn *name_dn, const char *name, 
                                        struct drsuapi_DsNameInfo1 *info1);
 
 static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, struct ldb_context *ldb_ctx, 
@@ -69,10 +69,14 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru
                return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
        }
 
-       service_dn = ldb_dn_string_compose(tmp_ctx, samdb_base_dn(ldb_ctx),
-                                          "CN=Directory Service,CN=Windows NT"
-                                          ",CN=Services,CN=Configuration");
+       service_dn = ldb_dn_new(tmp_ctx, ldb_ctx, "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration");
+       if ( ! ldb_dn_add_base(service_dn, samdb_base_dn(ldb_ctx))) {
+               return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+       }
        service_dn_str = ldb_dn_linearize(tmp_ctx, service_dn);
+       if ( ! service_dn_str) {
+               return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+       }
 
        ret = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)",
                         directory_attrs, &res);
@@ -358,9 +362,9 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 
                /* A LDAP DN as a string */
        case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: {
-               name_dn = ldb_dn_explode(mem_ctx, name);
                domain_filter = NULL;
-               if (!name_dn) {
+               name_dn = ldb_dn_new(mem_ctx, sam_ctx, name);
+               if (! ldb_dn_validate(name_dn)) {
                        info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                        return WERR_OK;
                }
@@ -534,7 +538,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 
 static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx,
                                        uint32_t format_offered, uint32_t format_desired,
-                                       const struct ldb_dn *name_dn, const char *name, 
+                                       struct ldb_dn *name_dn, const char *name, 
                                        struct drsuapi_DsNameInfo1 *info1)
 {
        char *cracked;
@@ -573,7 +577,7 @@ static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx,
 static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
                                   struct smb_krb5_context *smb_krb5_context,
                                   uint32_t format_flags, uint32_t format_offered, uint32_t format_desired,
-                                  const struct ldb_dn *name_dn, const char *name, 
+                                  struct ldb_dn *name_dn, const char *name, 
                                   const char *domain_filter, const char *result_filter, 
                                   struct drsuapi_DsNameInfo1 *info1)
 {
@@ -582,8 +586,8 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
        const char * const *domain_attrs;
        const char * const *result_attrs;
        struct ldb_message **result_res = NULL;
-       const struct ldb_dn *result_basedn;
-       const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
+       struct ldb_dn *result_basedn;
+       struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
 
        const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL};
        const char * const _result_attrs_null[] = { NULL };
@@ -655,7 +659,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
        info1->status           = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
 
        if (result_filter) {
-               result_basedn = samdb_result_dn(mem_ctx, domain_res[0], "ncName", NULL);
+               result_basedn = samdb_result_dn(sam_ctx, mem_ctx, domain_res[0], "ncName", NULL);
                
                ldb_ret = gendb_search(sam_ctx, mem_ctx, result_basedn, &result_res,
                                       result_attrs, "%s", result_filter);
@@ -663,7 +667,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
                ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
                                          result_attrs);
        } else {
-               name_dn = samdb_result_dn(mem_ctx, domain_res[0], "ncName", NULL);
+               name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res[0], "ncName", NULL);
                ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
                                          result_attrs);
        }
@@ -830,7 +834,7 @@ NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
        
-       *user_dn = ldb_dn_explode(mem_ctx, info1.result_name);
+       *user_dn = ldb_dn_new(mem_ctx, sam_ctx, info1.result_name);
        
        if (domain_dn) {
                werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0,
@@ -854,7 +858,7 @@ NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
                        return NT_STATUS_UNSUCCESSFUL;
                }
                
-               *domain_dn = ldb_dn_explode(mem_ctx, info1.result_name);
+               *domain_dn = ldb_dn_new(mem_ctx, sam_ctx, info1.result_name);
        }
 
        return NT_STATUS_OK;
@@ -893,7 +897,7 @@ NTSTATUS crack_service_principal_name(struct ldb_context *sam_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
        
-       *user_dn = ldb_dn_explode(mem_ctx, info1.result_name);
+       *user_dn = ldb_dn_new(mem_ctx, sam_ctx, info1.result_name);
        
        if (domain_dn) {
                werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0,
@@ -917,7 +921,7 @@ NTSTATUS crack_service_principal_name(struct ldb_context *sam_ctx,
                        return NT_STATUS_UNSUCCESSFUL;
                }
                
-               *domain_dn = ldb_dn_explode(mem_ctx, info1.result_name);
+               *domain_dn = ldb_dn_new(mem_ctx, sam_ctx, info1.result_name);
        }
 
        return NT_STATUS_OK;
index 38f366dfa2cf711ef8f44dde7bb39af685465ab6..2bc97f2040d4baf4887f5d3fb79a50c2bcf2643d 100644 (file)
@@ -112,7 +112,7 @@ static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC
        struct entryUUID_private *entryUUID_private;
        struct ldb_result *list;
 
-       if (ldb_dn_explode(ctx, (const char *)val->data)) {
+       if (ldb_dn_validate(ldb_dn_new(ctx, module->ldb, (const char *)val->data))) {
                return *val;
        }
        map_private = talloc_get_type(module->private_data, struct map_private);
@@ -415,7 +415,7 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
 {
        const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
        struct ldb_dn *schema_dn;
-       struct ldb_dn *basedn = ldb_dn_explode(mem_ctx, "");
+       struct ldb_dn *basedn = ldb_dn_new(mem_ctx, ldb, NULL);
        struct ldb_result *rootdse_res;
        int ldb_ret;
        if (!basedn) {
@@ -436,7 +436,7 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
        }
        
        /* Locate schema */
-       schema_dn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
+       schema_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
        if (!schema_dn) {
                return NULL;
        }
@@ -490,8 +490,8 @@ static int get_remote_rootdse(struct ldb_context *ldb, void *context,
                        if (!entryUUID_private->base_dns) {
                                return LDB_ERR_OPERATIONS_ERROR;
                        }
-                       entryUUID_private->base_dns[i] = ldb_dn_explode(entryUUID_private->base_dns, (const char *)el->values[i].data);
-                       if (!entryUUID_private->base_dns[i]) {
+                       entryUUID_private->base_dns[i] = ldb_dn_new(entryUUID_private->base_dns, ldb, (const char *)el->values[i].data);
+                       if ( ! ldb_dn_validate(entryUUID_private->base_dns[i])) {
                                return LDB_ERR_OPERATIONS_ERROR;
                        }
                }
@@ -517,7 +517,7 @@ static int find_base_dns(struct ldb_module *module,
        }
 
        req->operation = LDB_SEARCH;
-       req->op.search.base = ldb_dn_new(req);
+       req->op.search.base = ldb_dn_new(req, module->ldb, NULL);
        req->op.search.scope = LDB_SCOPE_BASE;
 
        req->op.search.tree = ldb_parse_tree(req, "objectClass=*");
index 64600fff8bd6f76927d68d42b2b1cf713582def3..012ac74514dc1b3ec3900da6719f5cf12ca1c093 100644 (file)
@@ -97,6 +97,7 @@ static BOOL add_attrs(void *mem_ctx, char ***attrs, const char *attr)
 }
 
 static BOOL inject_extended_dn(struct ldb_message *msg,
+                               struct ldb_context *ldb,
                                int type,
                                BOOL remove_guid,
                                BOOL remove_sid)
@@ -152,8 +153,8 @@ static BOOL inject_extended_dn(struct ldb_message *msg,
        if (!new_dn)
                return False;
 
-       msg->dn = ldb_dn_explode_or_special(msg, new_dn);
-       if (!msg->dn)
+       msg->dn = ldb_dn_new(msg, ldb, new_dn);
+       if (! ldb_dn_validate(msg->dn))
                return False;
 
        val = ldb_msg_find_ldb_val(msg, "distinguishedName");
@@ -193,7 +194,7 @@ static int extended_callback(struct ldb_context *ldb, void *context, struct ldb_
        if (ares->type == LDB_REPLY_ENTRY) {
                /* for each record returned post-process to add any derived
                   attributes that have been asked for */
-               if (!inject_extended_dn(ares->message, ac->extended_type, ac->remove_guid, ac->remove_sid)) {
+               if (!inject_extended_dn(ares->message, ldb, ac->extended_type, ac->remove_guid, ac->remove_sid)) {
                        goto error;
                }
        }
index 088f2657ccacc184f2da1939bff9f0ab66363543..176cfbf3a5f2b3d28e8997d8bdaef20920193475 100644 (file)
@@ -231,7 +231,7 @@ static int kludge_acl_init(struct ldb_module *module)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       ret = ldb_search(module->ldb, ldb_dn_explode(mem_ctx, "@KLUDGEACL"),
+       ret = ldb_search(module->ldb, ldb_dn_new(mem_ctx, module->ldb, "@KLUDGEACL"),
                         LDB_SCOPE_BASE,
                         NULL, attrs,
                         &res);
index b5cff0272d4d30f447f7411edf9d2860df9c5643..57323d859f8d28dbed020c1b46630b29fcb3e877 100644 (file)
@@ -140,8 +140,7 @@ static int local_password_add(struct ldb_module *module, struct ldb_request *req
        }
 
        /* If the caller is manipulating the local passwords directly, let them pass */
-       if (ldb_dn_compare_base(module->ldb, 
-                               ldb_dn_explode(req, LOCAL_BASE),
+       if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),
                                req->op.add.message->dn) == 0) {
                return ldb_next_request(module, req);
        }
@@ -225,9 +224,8 @@ static int local_password_add(struct ldb_module *module, struct ldb_request *req
        /* Find the objectGUID to use as the key */
        objectGUID = samdb_result_guid(ac->orig_req->op.add.message, "objectGUID");
        
-       local_message->dn = ldb_dn_string_compose(local_message,
-                                                 ldb_dn_explode(local_message, LOCAL_BASE),
-                                                 PASSWORD_GUID_ATTR "=%s", GUID_string(local_message, &objectGUID));
+       local_message->dn = ldb_dn_new(local_message, module->ldb, LOCAL_BASE);
+       ldb_dn_add_child_fmt(local_message->dn, PASSWORD_GUID_ATTR "=%s", GUID_string(local_message, &objectGUID));
 
        ac->local_req->op.add.message = local_message;
 
@@ -276,8 +274,7 @@ static int local_password_modify(struct ldb_module *module, struct ldb_request *
        }
 
        /* If the caller is manipulating the local passwords directly, let them pass */
-       if (ldb_dn_compare_base(module->ldb, 
-                               ldb_dn_explode(req, LOCAL_BASE),
+       if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),
                                req->op.mod.message->dn) == 0) {
                return ldb_next_request(module, req);
        }
@@ -447,9 +444,8 @@ static int local_password_mod_local(struct ldb_handle *h) {
        
        objectGUID = samdb_result_guid(ac->search_res->message, "objectGUID");
 
-       ac->local_message->dn = ldb_dn_string_compose(ac,
-                                                     ldb_dn_explode(ac, LOCAL_BASE),
-                                                     PASSWORD_GUID_ATTR "=%s", GUID_string(ac, &objectGUID));
+       ac->local_message->dn = ldb_dn_new(ac, ac->module->ldb, LOCAL_BASE);
+       ldb_dn_add_child_fmt(ac->local_message->dn, PASSWORD_GUID_ATTR "=%s", GUID_string(ac, &objectGUID));
 
        h->state = LDB_ASYNC_INIT;
        h->status = LDB_SUCCESS;
@@ -591,10 +587,8 @@ static int lpdb_remote_search_callback(struct ldb_context *ldb, void *context, s
                local_context->remote_res = ares;
                local_context->local_res = NULL;
 
-               req->op.search.base = ldb_dn_string_compose(ac,
-                                                           ldb_dn_explode(ac, LOCAL_BASE),
-                                                           PASSWORD_GUID_ATTR "=%s", GUID_string(ac, &objectGUID));
-               if (!req->op.search.base) {
+               req->op.search.base = ldb_dn_new(ac, ac->module->ldb, LOCAL_BASE);
+               if ( ! ldb_dn_add_child_fmt(req->op.search.base, PASSWORD_GUID_ATTR "=%s", GUID_string(ac, &objectGUID))) {
                        return LDB_ERR_OPERATIONS_ERROR;
                }
                req->operation = LDB_SEARCH;
@@ -642,8 +636,7 @@ static int local_password_search(struct ldb_module *module, struct ldb_request *
        }
 
        /* If the caller is searching for the local passwords directly, let them pass */
-       if (ldb_dn_compare_base(module->ldb, 
-                               ldb_dn_explode(req, LOCAL_BASE),
+       if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),
                                req->op.search.base) == 0) {
                return ldb_next_request(module, req);
        }
index d678364b6e7b6311dbafa9bcd80d2db847bb01aa..625c846bdcec15ef16270be3dc6ab27efed22261 100644 (file)
@@ -100,7 +100,7 @@ struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx,
        return current;
 }
 
-struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn)
+struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
 {
        int i;
        struct partition_private_data *data = talloc_get_type(module->private_data, 
@@ -109,8 +109,7 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r
        /* Figure out which partition it is under */
        /* Skip the lot if 'data' isn't here yet (initialistion) */
        for (i=0; data && data->partitions && data->partitions[i]; i++) {
-               if (ldb_dn_compare_base(module->ldb, 
-                                       data->partitions[i]->dn, 
+               if (ldb_dn_compare_base(data->partitions[i]->dn, 
                                        dn) == 0) {
                        return make_module_for_next_request(req, module->ldb, data->partitions[i]->module);
                }
@@ -210,8 +209,7 @@ static int partition_send_request(struct partition_context *ac, struct ldb_modul
                /* If the search is for 'more' than this partition,
                 * then change the basedn, so a remote LDAP server
                 * doesn't object */
-               if (ldb_dn_compare_base(ac->module->ldb, 
-                                       partition_base_dn, req->op.search.base) != 0) {
+               if (ldb_dn_compare_base(partition_base_dn, req->op.search.base) != 0) {
                        req->op.search.base = partition_base_dn;
                }
                req->callback = partition_search_callback;
@@ -253,7 +251,7 @@ static int partition_send_all(struct ldb_module *module,
 
 /* Figure out which backend a request needs to be aimed at.  Some
  * requests must be replicated to all backends */
-static int partition_replicate(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) 
+static int partition_replicate(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) 
 {
        int i;
        struct ldb_module *backend;
@@ -262,8 +260,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
        
        /* Is this a special DN, we need to replicate to every backend? */
        for (i=0; data->replicate && data->replicate[i]; i++) {
-               if (ldb_dn_compare(module->ldb, 
-                                  data->replicate[i], 
+               if (ldb_dn_compare(data->replicate[i], 
                                   dn) == 0) {
                        struct ldb_handle *h;
                        struct partition_context *ac;
@@ -316,13 +313,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
                ac = talloc_get_type(h->private_data, struct partition_context);
                
                /* Search from the base DN */
-               if (!req->op.search.base || (ldb_dn_get_comp_num(req->op.search.base) == 0)) {
+               if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) {
                        return partition_send_all(module, ac, req);
                }
                for (i=0; data && data->partitions && data->partitions[i]; i++) {
                        /* Find all partitions under the search base */
-                       if (ldb_dn_compare_base(module->ldb, 
-                                               req->op.search.base,
+                       if (ldb_dn_compare_base(req->op.search.base,
                                                data->partitions[i]->dn) == 0) {
                                ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn);
                                if (ret != LDB_SUCCESS) {
@@ -577,13 +573,12 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque
 static int sort_compare(void *void1,
                        void *void2, void *opaque)
 {
-       struct ldb_context *ldb = talloc_get_type(opaque, struct ldb_context);
        struct partition **pp1 = void1;
        struct partition **pp2 = void2;
        struct partition *partition1 = talloc_get_type(*pp1, struct partition);
        struct partition *partition2 = talloc_get_type(*pp2, struct partition);
 
-       return ldb_dn_compare(ldb, partition1->dn, partition2->dn);
+       return ldb_dn_compare(partition1->dn, partition2->dn);
 }
 
 static int partition_init(struct ldb_module *module)
@@ -608,7 +603,7 @@ static int partition_init(struct ldb_module *module)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       ret = ldb_search(module->ldb, ldb_dn_explode(mem_ctx, "@PARTITION"),
+       ret = ldb_search(module->ldb, ldb_dn_new(mem_ctx, module->ldb, "@PARTITION"),
                         LDB_SCOPE_BASE,
                         NULL, attrs,
                         &res);
@@ -665,7 +660,7 @@ static int partition_init(struct ldb_module *module)
                        return LDB_ERR_OPERATIONS_ERROR;
                }
 
-               data->partitions[i]->dn = ldb_dn_explode(data->partitions[i], base);
+               data->partitions[i]->dn = ldb_dn_new(data->partitions[i], module->ldb, base);
                if (!data->partitions[i]->dn) {
                        ldb_asprintf_errstring(module->ldb, 
                                                "partition_init: invalid DN in partition record: %s", base);
@@ -718,8 +713,8 @@ static int partition_init(struct ldb_module *module)
                }
                
                for (i=0; i < replicate_attributes->num_values; i++) {
-                       data->replicate[i] = ldb_dn_explode(data->replicate, (const char *)replicate_attributes->values[i].data);
-                       if (!data->replicate[i]) {
+                       data->replicate[i] = ldb_dn_new(data->replicate, module->ldb, (const char *)replicate_attributes->values[i].data);
+                       if (!ldb_dn_validate(data->replicate[i])) {
                                ldb_asprintf_errstring(module->ldb, 
                                                        "partition_init: "
                                                        "invalid DN in partition replicate record: %s", 
@@ -765,14 +760,14 @@ static int partition_init(struct ldb_module *module)
                        modules = ldb_modules_list_from_string(module->ldb, mem_ctx,
                                                               p);
                        
-                       base_dn = ldb_dn_explode(mem_ctx, base);
-                       if (!base_dn) {
+                       base_dn = ldb_dn_new(mem_ctx, module->ldb, base);
+                       if (!ldb_dn_validate(base_dn)) {
                                talloc_free(mem_ctx);
                                return LDB_ERR_OPERATIONS_ERROR;
                        }
                        
                        for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) {
-                               if (ldb_dn_compare(module->ldb, data->partitions[partition_idx]->dn, 
+                               if (ldb_dn_compare(data->partitions[partition_idx]->dn, 
                                                   base_dn) == 0) {
                                        partition = data->partitions[partition_idx];
                                        break;
index 1b35ec3e8c449e85d78fa3e2844cf799e889eb3a..b25beb7a8f56c24f7dd2a15c2ff0505586eb3e8a 100644 (file)
@@ -588,8 +588,7 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
        }
 
        /* If the caller is manipulating the local passwords directly, let them pass */
-       if (ldb_dn_compare_base(module->ldb, 
-                               ldb_dn_explode(req, LOCAL_BASE),
+       if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),
                                req->op.add.message->dn) == 0) {
                return ldb_next_request(module, req);
        }
@@ -783,8 +782,7 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r
        }
        
        /* If the caller is manipulating the local passwords directly, let them pass */
-       if (ldb_dn_compare_base(module->ldb, 
-                               ldb_dn_explode(req, LOCAL_BASE),
+       if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),
                                req->op.mod.message->dn) == 0) {
                return ldb_next_request(module, req);
        }
index d2628f5d1d05f05ce6076f9da041a551ba759b62..41fe8b68c923d043aeefa2ac46f21b573c79d0ad 100644 (file)
@@ -70,7 +70,7 @@ static int load_proxy_info(struct ldb_module *module)
                return 0;
        }
 
-       dn = ldb_dn_explode(proxy, "@PROXYINFO");
+       dn = ldb_dn_new(proxy, module->ldb, "@PROXYINFO");
        if (dn == NULL) {
                goto failed;
        }
@@ -94,13 +94,13 @@ static int load_proxy_info(struct ldb_module *module)
                goto failed;
        }
 
-       proxy->olddn = ldb_dn_explode(proxy, olddn);
+       proxy->olddn = ldb_dn_new(proxy, module->ldb, olddn);
        if (proxy->olddn == NULL) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Failed to explode olddn '%s'\n", olddn);
                goto failed;
        }
        
-       proxy->newdn = ldb_dn_explode(proxy, newdn);
+       proxy->newdn = ldb_dn_new(proxy, module->ldb, newdn);
        if (proxy->newdn == NULL) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Failed to explode newdn '%s'\n", newdn);
                goto failed;
@@ -226,9 +226,8 @@ static void proxy_convert_record(struct ldb_module *module, struct ldb_message *
        
        /* fix the message DN */
        if (ldb_dn_compare_base(module->ldb, proxy->olddn, msg->dn) == 0) {
-               struct ldb_dn *newdn = ldb_dn_copy(msg, msg->dn);
-               newdn->comp_num -= proxy->olddn->comp_num;
-               msg->dn = ldb_dn_compose(msg, newdn, proxy->newdn);
+               ldb_dn_remove_base_components(msg->dn, ldb_dn_get_comp_num(proxy->olddn));
+               ldb_dn_add_base(msg->dn, proxy->newdn);
        }
 
        /* fix any attributes */
@@ -282,8 +281,8 @@ static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *re
                talloc_free(newreq);
                goto failed;
        }
-       base->comp_num -= proxy->newdn->comp_num;
-       base = ldb_dn_compose(proxy, newreq->op.search.base, proxy->olddn);
+       ldb_dn_remove_base_components(base, ldb_dn_get_comp_num(proxy->newdn));
+       ldb_dn_add_base(base, proxy->olddn);
 
        ldb_debug(module->ldb, LDB_DEBUG_FATAL, "proxying: '%s' with dn '%s' \n", 
                  ldb_filter_from_tree(proxy, newreq->op.search.tree), ldb_dn_linearize(proxy, newreq->op.search.base));
index 371031be260152a6531430f86d65b71e0709e091..e073c8f89bd8d656940f0f971a32c79f31502d8c 100644 (file)
@@ -53,7 +53,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
        struct private_data *priv = talloc_get_type(module->private_data, struct private_data);
        char **server_sasl;
 
-       msg->dn = ldb_dn_explode(msg, "");
+       msg->dn = ldb_dn_new(msg, module->ldb, NULL);
 
        /* don't return the distinduishedName, cn and name attributes */
        ldb_msg_remove_attr(msg, "distinguishedName");
@@ -182,7 +182,7 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
 
        /* see if its for the rootDSE */
        if (req->op.search.scope != LDB_SCOPE_BASE ||
-           (req->op.search.base && ldb_dn_get_comp_num(req->op.search.base) != 0)) {
+           ( ! ldb_dn_is_null(req->op.search.base))) {
                return ldb_next_request(module, req);
        }
 
@@ -203,7 +203,7 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
 
        down_req->operation = req->operation;
        /* in our db we store the rootDSE with a DN of cn=rootDSE */
-       down_req->op.search.base = ldb_dn_explode(down_req, "cn=rootDSE");
+       down_req->op.search.base = ldb_dn_new(down_req, module->ldb, "cn=rootDSE");
        down_req->op.search.scope = LDB_SCOPE_BASE;
        down_req->op.search.tree = ldb_parse_tree(down_req, NULL);
        if (down_req->op.search.base == NULL || down_req->op.search.tree == NULL) {
index 3ce5cc1b5cb3e158f1f385de98983228f34d007e..667b0d5ca85244a41775eeb6fe088d24bbf202a4 100644 (file)
@@ -62,7 +62,7 @@ static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *ms
   return 0 on failure, the id on success
 */
 static int samldb_set_next_rid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
-                              const struct ldb_dn *dn, uint32_t old_id, uint32_t new_id)
+                              struct ldb_dn *dn, uint32_t old_id, uint32_t new_id)
 {
        struct ldb_message msg;
        int ret;
@@ -119,7 +119,7 @@ static int samldb_set_next_rid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
   return 0 on failure, the id on success
 */
 static int samldb_find_next_rid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
-                               const struct ldb_dn *dn, uint32_t *old_rid)
+                               struct ldb_dn *dn, uint32_t *old_rid)
 {
        const char * const attrs[2] = { "nextRid", NULL };
        struct ldb_result *res = NULL;
@@ -150,7 +150,7 @@ static int samldb_find_next_rid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
 }
 
 static int samldb_allocate_next_rid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
-                                   const struct ldb_dn *dn, const struct dom_sid *dom_sid, 
+                                   struct ldb_dn *dn, const struct dom_sid *dom_sid, 
                                    struct dom_sid **new_sid)
 {
        struct dom_sid *obj_sid;
@@ -185,7 +185,7 @@ static int samldb_allocate_next_rid(struct ldb_module *module, TALLOC_CTX *mem_c
 }
 
 /* Find a domain object in the parents of a particular DN.  */
-static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct ldb_dn *dn)
+static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
 {
        TALLOC_CTX *local_ctx;
        struct ldb_dn *sdn;
@@ -224,12 +224,12 @@ static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX
    return the new sid string
 */
 static int samldb_get_new_sid(struct ldb_module *module, 
-                             TALLOC_CTX *mem_ctx, const struct ldb_dn *obj_dn,
+                             TALLOC_CTX *mem_ctx, struct ldb_dn *obj_dn,
                              struct dom_sid **sid)
 {
        const char * const attrs[2] = { "objectSid", NULL };
        struct ldb_result *res = NULL;
-       const struct ldb_dn *dom_dn;
+       struct ldb_dn *dom_dn;
        int ret;
        struct dom_sid *dom_sid;
 
index fe275ce841622f4901c6e8a863c07ee56e19f810..f7bbb7b2c532feb1827e93c4f18edeb7063c0f08 100644 (file)
@@ -946,7 +946,7 @@ static int schema_check_attributes_syntax(struct schema_context *sctx)
                if (attr == NULL) {
                        return LDB_ERR_NO_SUCH_ATTRIBUTE;
                }
-               ret = schema_validate(&msg->elements[i], attr->syntax, attr->single, attr->min, attr->max);
+               ret = schema_validate(sctx->module->ldb, &msg->elements[i], attr->syntax, attr->single, attr->min, attr->max);
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
@@ -1187,7 +1187,7 @@ static int schema_init(struct ldb_module *module)
 
        /* find the schema partition */
        ret = ldb_search(module->ldb,
-                        ldb_dn_new(module),
+                        ldb_dn_new(module, module->ldb, NULL),
                         LDB_SCOPE_BASE,
                         "(objectClass=*)",
                         schema_attrs,
@@ -1200,7 +1200,7 @@ static int schema_init(struct ldb_module *module)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       data->schema_dn = ldb_msg_find_attr_as_dn(data, res->msgs[0], "schemaNamingContext");
+       data->schema_dn = ldb_msg_find_attr_as_dn(module->ldb, data, res->msgs[0], "schemaNamingContext");
        if (data->schema_dn == NULL) {
                /* FIXME: return a clear error string */
                talloc_free(data);
index f23c2d156dfb35b437d049c40b5c447611c6e7c7..f394c75047855ee2da312de624df886a09b7cda7 100644 (file)
@@ -137,7 +137,7 @@ int map_schema_syntax(uint32_t om_syntax, const char *attr_syntax, const struct
        return ret;
 }
 
-static int schema_validate_boolean(struct ldb_val *val, int min, int max)
+static int schema_validate_boolean(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
 
        if ((strncmp("TRUE", (const char *)val->data, val->length) != 0) &&
@@ -148,7 +148,7 @@ static int schema_validate_boolean(struct ldb_val *val, int min, int max)
        return LDB_SUCCESS;
 }
 
-static int schema_validate_integer(struct ldb_val *val, int min, int max)
+static int schema_validate_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        int value;
        char *endptr;
@@ -163,19 +163,19 @@ static int schema_validate_integer(struct ldb_val *val, int min, int max)
        return LDB_SUCCESS;
 }
 
-static int schema_validate_binary_blob(struct ldb_val *val, int min, int max)
+static int schema_validate_binary_blob(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* is there anythign we should check in a binary blob ? */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_sid(struct ldb_val *val, int min, int max)
+static int schema_validate_sid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate binary form of objectSid */
        return LDB_SUCCESS;     
 }
 
-static int schema_validate_oid(struct ldb_val *val, int min, int max)
+static int schema_validate_oid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        if (strspn((const char *)val->data, "0123456789.") != val->length)
                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
@@ -183,7 +183,7 @@ static int schema_validate_oid(struct ldb_val *val, int min, int max)
        return LDB_SUCCESS;
 }
 
-static int schema_validate_numeric_string(struct ldb_val *val, int min, int max)
+static int schema_validate_numeric_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        if (strspn((const char *)val->data, "0123456789") != val->length)
                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
@@ -191,80 +191,76 @@ static int schema_validate_numeric_string(struct ldb_val *val, int min, int max)
        return LDB_SUCCESS;
 }
 
-static int schema_validate_printable_string(struct ldb_val *val, int min, int max)
+static int schema_validate_printable_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what constitutes the printable character set */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_teletext_string(struct ldb_val *val, int min, int max)
+static int schema_validate_teletext_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what constitutes the teletext character set */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_ia5_string(struct ldb_val *val, int min, int max)
+static int schema_validate_ia5_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what constitutes the IA5 character set */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_utc_time(struct ldb_val *val, int min, int max)
+static int schema_validate_utc_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate syntax of UTC Time string */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_generalized_time(struct ldb_val *val, int min, int max)
+static int schema_validate_generalized_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate syntax of Generalized Time string */
        return LDB_SUCCESS;
 }
 
 /* NOTE: not a single attribute has this syntax in the basic w2k3 schema */
-static int schema_validate_sensitive_string(struct ldb_val *val, int min, int max)
+static int schema_validate_sensitive_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what constitutes a "case sensitive string" */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_unicode_string(struct ldb_val *val, int min, int max)
+static int schema_validate_unicode_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate utf8 string */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_large_integer(struct ldb_val *val, int min, int max)
+static int schema_validate_large_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate large integer/interval */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_object_sd(struct ldb_val *val, int min, int max)
+static int schema_validate_object_sd(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: validate object Security Descriptor */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_dn(struct ldb_val *val, int min, int max)
+static int schema_validate_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
-       TALLOC_CTX *memctx;
        struct ldb_dn *dn;
        int ret = LDB_SUCCESS;
 
-       memctx = talloc_new(NULL);
-       if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
-
-       dn = ldb_dn_explode(memctx, (const char *)val->data);
-       if (!dn) {
+       dn = ldb_dn_new(ldb, ldb, (const char *)val->data);
+       if ( ! ldb_dn_validate(dn)) {
                ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        }
 
-       talloc_free(memctx);
+       talloc_free(dn);
        return ret;
 }
 
-static int schema_validate_binary_plus_dn(struct ldb_val *val, int min, int max)
+static int schema_validate_binary_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        TALLOC_CTX *memctx;
@@ -319,8 +315,8 @@ static int schema_validate_binary_plus_dn(struct ldb_val *val, int min, int max)
 
        str = p + 1;
 
-       dn = ldb_dn_explode(memctx, str);
-       if (dn) {
+       dn = ldb_dn_new(memctx, ldb, str);
+       if (ldb_dn_validate(dn)) {
                ret = LDB_SUCCESS;
        }
 
@@ -329,26 +325,26 @@ done:
        return ret;
 }
 
-static int schema_validate_x400_or_name(struct ldb_val *val, int min, int max)
+static int schema_validate_x400_or_name(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what is the syntax of an X400 OR NAME */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_presentation_address(struct ldb_val *val, int min, int max)
+static int schema_validate_presentation_address(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what is the syntax of a presentation address */
        return LDB_SUCCESS;
 }
 
-static int schema_validate_x400_access_point(struct ldb_val *val, int min, int max)
+static int schema_validate_x400_access_point(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        /* TODO: find out what is the syntax of an X400 Access Point */
        return LDB_SUCCESS;
 }
 
 /* NOTE: seem there isn't a single attribute defined like this in the base w2k3 schema */
-static int schema_validate_string_plus_dn(struct ldb_val *val, int min, int max)
+static int schema_validate_string_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
 {
        int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        TALLOC_CTX *memctx;
@@ -403,8 +399,8 @@ static int schema_validate_string_plus_dn(struct ldb_val *val, int min, int max)
 
        str = p + 1;
 
-       dn = ldb_dn_explode(memctx, str);
-       if (dn) {
+       dn = ldb_dn_new(memctx, ldb, str);
+       if (ldb_dn_validate(dn)) {
                ret = LDB_SUCCESS;
        }
 
@@ -415,7 +411,7 @@ done:
 
 struct schema_syntax_validator {
        enum schema_internal_syntax type;
-       int (*validate)(struct ldb_val *, int, int);
+       int (*validate)(struct ldb_context *ldb, struct ldb_val *, int, int);
 };
 
 struct schema_syntax_validator schema_syntax_validators[] = {
@@ -445,7 +441,8 @@ struct schema_syntax_validator schema_syntax_validators[] = {
        { -1, NULL }
 };
 
-int schema_validate(struct ldb_message_element *el,
+int schema_validate(struct ldb_context *ldb,
+                   struct ldb_message_element *el,
                    enum schema_internal_syntax type,
                    bool single, int min, int max)
 {
@@ -466,7 +463,7 @@ int schema_validate(struct ldb_message_element *el,
        v = &schema_syntax_validators[i];
        
        for (i = 0; i < el->num_values; i++) {
-               ret = v->validate(&el->values[i], min, max);
+               ret = v->validate(ldb, &el->values[i], min, max);
        }
 
        return LDB_SUCCESS;
index 453f79a3c224aba5bb357ca415aa8f182793728c..39a5603caebb393246190b8bf3b9a5a2d8bba447 100644 (file)
@@ -67,7 +67,8 @@ int map_schema_syntax(uint32_t om_syntax,
                      const struct ldb_val *om_class,
                      enum schema_internal_syntax *syntax);
 
-int schema_validate(struct ldb_message_element *el,
+int schema_validate(struct ldb_context *ldb,
+                   struct ldb_message_element *el,
                    enum schema_internal_syntax type,
                    bool single, int min, int max);
 
index f9ef3bc907885a711a5a3e4309a0ba1d691f3b37..4439335ca5ecf4a9f54d8ec05e04194e28dc6b73 100644 (file)
@@ -59,7 +59,7 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
 */
 int samdb_search_domain(struct ldb_context *sam_ldb,
                        TALLOC_CTX *mem_ctx, 
-                       const struct ldb_dn *basedn,
+                       struct ldb_dn *basedn,
                        struct ldb_message ***res,
                        const char * const *attrs,
                        const struct dom_sid *domain_sid,
@@ -100,7 +100,7 @@ int samdb_search_domain(struct ldb_context *sam_ldb,
 */
 const char *samdb_search_string_v(struct ldb_context *sam_ldb,
                                  TALLOC_CTX *mem_ctx,
-                                 const struct ldb_dn *basedn,
+                                 struct ldb_dn *basedn,
                                  const char *attr_name,
                                  const char *format, va_list ap) _PRINTF_ATTRIBUTE(5,0)
 {
@@ -129,7 +129,7 @@ const char *samdb_search_string_v(struct ldb_context *sam_ldb,
 */
 const char *samdb_search_string(struct ldb_context *sam_ldb,
                                TALLOC_CTX *mem_ctx,
-                               const struct ldb_dn *basedn,
+                               struct ldb_dn *basedn,
                                const char *attr_name,
                                const char *format, ...) _PRINTF_ATTRIBUTE(5,6)
 {
@@ -145,7 +145,7 @@ const char *samdb_search_string(struct ldb_context *sam_ldb,
 
 struct ldb_dn *samdb_search_dn(struct ldb_context *sam_ldb,
                               TALLOC_CTX *mem_ctx,
-                              const struct ldb_dn *basedn,
+                              struct ldb_dn *basedn,
                               const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
 {
        va_list ap;
@@ -170,7 +170,7 @@ struct ldb_dn *samdb_search_dn(struct ldb_context *sam_ldb,
 */
 struct dom_sid *samdb_search_dom_sid(struct ldb_context *sam_ldb,
                                     TALLOC_CTX *mem_ctx,
-                                    const struct ldb_dn *basedn,
+                                    struct ldb_dn *basedn,
                                     const char *attr_name,
                                     const char *format, ...) _PRINTF_ATTRIBUTE(5,6)
 {
@@ -203,7 +203,7 @@ struct dom_sid *samdb_search_dom_sid(struct ldb_context *sam_ldb,
 */
 int samdb_search_count(struct ldb_context *sam_ldb,
                       TALLOC_CTX *mem_ctx,
-                      const struct ldb_dn *basedn,
+                      struct ldb_dn *basedn,
                       const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
 {
        va_list ap;
@@ -225,7 +225,7 @@ int samdb_search_count(struct ldb_context *sam_ldb,
 uint_t samdb_search_uint(struct ldb_context *sam_ldb,
                         TALLOC_CTX *mem_ctx,
                         uint_t default_value,
-                        const struct ldb_dn *basedn,
+                        struct ldb_dn *basedn,
                         const char *attr_name,
                         const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
 {
@@ -253,7 +253,7 @@ uint_t samdb_search_uint(struct ldb_context *sam_ldb,
 int64_t samdb_search_int64(struct ldb_context *sam_ldb,
                           TALLOC_CTX *mem_ctx,
                           int64_t default_value,
-                          const struct ldb_dn *basedn,
+                          struct ldb_dn *basedn,
                           const char *attr_name,
                           const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
 {
@@ -281,7 +281,7 @@ int64_t samdb_search_int64(struct ldb_context *sam_ldb,
 */
 int samdb_search_string_multiple(struct ldb_context *sam_ldb,
                                 TALLOC_CTX *mem_ctx,
-                                const struct ldb_dn *basedn,
+                                struct ldb_dn *basedn,
                                 const char ***strs,
                                 const char *attr_name,
                                 const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
@@ -350,12 +350,18 @@ const char *samdb_result_string(const struct ldb_message *msg, const char *attr,
        return ldb_msg_find_attr_as_string(msg, attr, default_value);
 }
 
-struct ldb_dn *samdb_result_dn(TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
+struct ldb_dn *samdb_result_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
                               const char *attr, struct ldb_dn *default_value)
 {
+       struct ldb_dn *res_dn;
        const char *string = samdb_result_string(msg, attr, NULL);
        if (string == NULL) return default_value;
-       return ldb_dn_explode(mem_ctx, string);
+       res_dn = ldb_dn_new(mem_ctx, ldb, string);
+       if ( ! ldb_dn_validate(res_dn)) {
+               talloc_free(res_dn);
+               return NULL;
+       }
+       return res_dn;
 }
 
 /*
@@ -467,7 +473,7 @@ uint64_t samdb_result_uint64(struct ldb_message *msg, const char *attr, uint64_t
 */
 NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb, 
                                          TALLOC_CTX *mem_ctx, 
-                                         const struct ldb_dn *domain_dn, 
+                                         struct ldb_dn *domain_dn, 
                                          struct ldb_message *msg, 
                                          const char *attr)
 {
@@ -493,7 +499,7 @@ NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb,
 */
 NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb, 
                                          TALLOC_CTX *mem_ctx, 
-                                         const struct ldb_dn *domain_dn, 
+                                         struct ldb_dn *domain_dn, 
                                          struct ldb_message *msg)
 {
        uint64_t attr_time = samdb_result_uint64(msg, "pwdLastSet", 0);
@@ -679,7 +685,7 @@ int samdb_copy_template(struct ldb_context *ldb,
        struct ldb_result *res;
        struct ldb_message *t;
        int ret, i, j;
-       struct ldb_dn *basedn = ldb_dn_explode(ldb, "cn=Templates");
+       struct ldb_dn *basedn = ldb_dn_new(ldb, ldb, "cn=Templates");
 
        *errstring = NULL;      
 
@@ -982,7 +988,7 @@ int samdb_add(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_messa
 /*
   delete a record
 */
-int samdb_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, const struct ldb_dn *dn)
+int samdb_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
 {
        return ldb_delete(sam_ldb, dn);
 }
@@ -1023,19 +1029,23 @@ struct security_descriptor *samdb_default_security_descriptor(TALLOC_CTX *mem_ct
        return sd;
 }
 
-const struct ldb_dn *samdb_base_dn(struct ldb_context *sam_ctx) 
+struct ldb_dn *samdb_base_dn(struct ldb_context *sam_ctx) 
 {
        return ldb_get_default_basedn(sam_ctx);
 }
 
 
-const struct ldb_dn *samdb_partitions_dn(struct ldb_context *sam_ctx,
-                                  TALLOC_CTX *mem_ctx)
+struct ldb_dn *samdb_partitions_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
 {
-       return ldb_dn_string_compose(mem_ctx, samdb_base_dn(sam_ctx), 
-                                    "CN=Partitions,CN=Configuration");
-}
+       struct ldb_dn *new_dn;
 
+       new_dn = ldb_dn_copy(mem_ctx, samdb_base_dn(sam_ctx));
+       if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Partitions,CN=Configuration")) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+       return new_dn;
+}
 
 /*
   work out the domain sid for the current open ldb
@@ -1061,7 +1071,7 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
                goto failed;
        }
 
-       basedn = ldb_dn_explode(tmp_ctx, "");
+       basedn = ldb_dn_new(tmp_ctx, ldb, NULL);
        if (basedn == NULL) {
                goto failed;
        }
@@ -1078,8 +1088,8 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
                goto failed;
        }
 
-       basedn = ldb_dn_explode(tmp_ctx, basedn_s);
-       if (basedn == NULL) {
+       basedn = ldb_dn_new(tmp_ctx, ldb, basedn_s);
+       if ( ! ldb_dn_validate(basedn)) {
                goto failed;
        }
 
@@ -1129,8 +1139,8 @@ static BOOL samdb_password_complexity_ok(const char *pass)
   The caller should probably have a transaction wrapping this
 */
 _PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
-                           const struct ldb_dn *user_dn,
-                           const struct ldb_dn *domain_dn,
+                           struct ldb_dn *user_dn,
+                           struct ldb_dn *domain_dn,
                            struct ldb_message *mod,
                            const char *new_pass,
                            struct samr_Password *lmNewHash, 
@@ -1542,8 +1552,8 @@ NTSTATUS samdb_create_foreign_security_principal(struct ldb_context *sam_ctx, TA
        }
        
        /* add core elements to the ldb_message for the alias */
-       msg->dn = ldb_dn_build_child(mem_ctx, "CN", sidstr, basedn);
-       if (msg->dn == NULL)
+       msg->dn = ldb_dn_copy(mem_ctx, basedn);
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
                return NT_STATUS_NO_MEMORY;
        
        samdb_msg_add_string(sam_ctx, mem_ctx, msg,
index 00c89f9c0afa46f569c0188af31014098989e598..fd6ebfbe1bd5ee77f41bde09cb7b9530df504151 100644 (file)
@@ -212,7 +212,11 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        krb5_boolean is_computer = FALSE;
        const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL);
        char *realm = strupper_talloc(mem_ctx, dnsdomain);
-       struct ldb_dn *domain_dn = samdb_result_dn(mem_ctx, realm_ref_msg, "nCName", ldb_dn_new(mem_ctx));
+       struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db,
+                                                       mem_ctx,
+                                                       realm_ref_msg,
+                                                       "nCName",
+                                                       ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL));
 
        struct hdb_ldb_private *private;
        NTTIME acct_expiry;
@@ -449,7 +453,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
                                            TALLOC_CTX *mem_ctx,
                                            krb5_const_principal principal,
                                            enum hdb_ldb_ent_type ent_type,
-                                           const struct ldb_dn *realm_dn,
+                                           struct ldb_dn *realm_dn,
                                            struct ldb_message ***pmsg)
 {
        krb5_error_code ret;
@@ -523,7 +527,7 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context
        int ret;
        char *cross_ref_filter;
        struct ldb_result *cross_ref_res;
-       const struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);
+       struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);
 
        cross_ref_filter = talloc_asprintf(mem_ctx, 
                                           "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
@@ -630,7 +634,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
        krb5_error_code ret;
        struct ldb_message **msg = NULL;
        struct ldb_message **realm_ref_msg = NULL;
-       const struct ldb_dn *realm_dn;
+       struct ldb_dn *realm_dn;
 
        if (principal->name.name_string.len != 2
            || (strcmp(principal->name.name_string.val[0], KRB5_TGS_NAME) != 0)) {
@@ -642,13 +646,13 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
        if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
                              mem_ctx, principal->name.name_string.val[1], &realm_ref_msg) == 0)) {
                /* us */                
-               realm_dn = samdb_result_dn(mem_ctx, realm_ref_msg[0], "nCName", NULL);
+               realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);
        } else {
                /* we should lookup trusted domains */
                return HDB_ERR_NOENTRY;
        }
 
-       realm_dn = samdb_result_dn(mem_ctx, realm_ref_msg[0], "nCName", NULL);
+       realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);
        
        ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                   mem_ctx, 
@@ -679,7 +683,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
        const char *realm;
        struct ldb_message **msg = NULL;
        struct ldb_message **realm_ref_msg = NULL;
-       const struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx);
+       struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx);
        if (principal->name.name_string.len >= 2) {
                /* 'normal server' case */
                int ldb_ret;
@@ -722,7 +726,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                }
                
        } else {
-               const struct ldb_dn *realm_dn;
+               struct ldb_dn *realm_dn;
                /* server as client principal case, but we must not lookup userPrincipalNames */
 
                realm = krb5_principal_get_realm(context, principal);
@@ -733,7 +737,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                        return HDB_ERR_NOENTRY;
                }
                
-               realm_dn = samdb_result_dn(mem_ctx, realm_ref_msg[0], "nCName", NULL);
+               realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);
                
                ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                           mem_ctx, 
@@ -898,7 +902,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
                return HDB_ERR_NOENTRY;
        }
 
-       realm_dn = samdb_result_dn(mem_ctx, realm_ref_msgs[0], "nCName", NULL);
+       realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL);
 
        priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs);
 
index 1a2206b831f9a8b126f75e94c42ca56c06004997..de99280ded60df63725946a6c22676449ea6d1be 100644 (file)
 #define VALID_DN_SYNTAX(dn,i) do {\
        if (!(dn)) {\
                return NT_STATUS_NO_MEMORY;\
+       } else if ( ! ldb_dn_validate(dn)) {\
+               result = LDAP_INVALID_DN_SYNTAX;\
+               errstr = "Invalid DN format";\
+               goto reply;\
        } else if (ldb_dn_get_comp_num(dn) < (i)) {\
                result = LDAP_INVALID_DN_SYNTAX;\
                errstr = "Invalid DN (" #i " components needed for '" #dn "')";\
@@ -169,7 +173,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
        local_ctx = talloc_new(call);
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       basedn = ldb_dn_explode(local_ctx, req->basedn);
+       basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
        VALID_DN_SYNTAX(basedn, 0);
 
        DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
@@ -327,7 +331,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
        local_ctx = talloc_named(call, 0, "ModifyRequest local memory context");
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       dn = ldb_dn_explode(local_ctx, req->dn);
+       dn = ldb_dn_new(local_ctx, samdb, req->dn);
        VALID_DN_SYNTAX(dn, 1);
 
        DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
@@ -431,7 +435,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call)
        local_ctx = talloc_named(call, 0, "AddRequest local memory context");
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       dn = ldb_dn_explode(local_ctx, req->dn);
+       dn = ldb_dn_new(local_ctx, samdb, req->dn);
        VALID_DN_SYNTAX(dn,1);
 
        DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
@@ -522,7 +526,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call)
        local_ctx = talloc_named(call, 0, "DelRequest local memory context");
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       dn = ldb_dn_explode(local_ctx, req->dn);
+       dn = ldb_dn_new(local_ctx, samdb, req->dn);
        VALID_DN_SYNTAX(dn,1);
 
        DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn));
@@ -568,10 +572,10 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
        local_ctx = talloc_named(call, 0, "ModifyDNRequest local memory context");
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       olddn = ldb_dn_explode(local_ctx, req->dn);
+       olddn = ldb_dn_new(local_ctx, samdb, req->dn);
        VALID_DN_SYNTAX(olddn, 2);
 
-       newrdn = ldb_dn_explode(local_ctx, req->newrdn);
+       newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn);
        VALID_DN_SYNTAX(newrdn, 1);
 
        DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn));
@@ -584,14 +588,8 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
                goto reply;
        }
 
-       if (ldb_dn_get_comp_num(newrdn) > 1) {
-               result = LDAP_NAMING_VIOLATION;
-               errstr = "Error new RDN invalid";
-               goto reply;
-       }
-
        if (req->newsuperior) {
-               parentdn = ldb_dn_explode(local_ctx, req->newsuperior);
+               parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
                VALID_DN_SYNTAX(parentdn, 0);
                DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
                
@@ -607,11 +605,13 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
                NT_STATUS_HAVE_NO_MEMORY(parentdn);
        }
 
-       newdn = ldb_dn_build_child(local_ctx,
-                                  ldb_dn_get_rdn_name(newrdn),
-                                  (char *)ldb_dn_get_rdn_val(newrdn)->data,
-                                  parentdn);
-       NT_STATUS_HAVE_NO_MEMORY(newdn);
+       if ( ! ldb_dn_add_child_fmt(parentdn,
+                               "%s=%s",
+                               ldb_dn_get_rdn_name(newrdn),
+                               (char *)ldb_dn_get_rdn_val(newrdn)->data)) {
+               result = LDAP_OTHER;
+               goto reply;
+       }
 
 reply:
        modifydn_r = ldapsrv_init_reply(call, LDAP_TAG_ModifyDNResponse);
@@ -655,7 +655,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
        local_ctx = talloc_named(call, 0, "CompareRequest local_memory_context");
        NT_STATUS_HAVE_NO_MEMORY(local_ctx);
 
-       dn = ldb_dn_explode(local_ctx, req->dn);
+       dn = ldb_dn_new(local_ctx, samdb, req->dn);
        VALID_DN_SYNTAX(dn, 1);
 
        DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn));
index 29555b14e16f68a6127dffca8fa8116a6588859d..82fc1d966011d0c89234e4bde0f69e7aa8b49942 100644 (file)
@@ -239,8 +239,8 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
                return -1;
        }
 
-       basedn = ldb_dn_new(tmp_ctx);
-       if (basedn == NULL) {
+       basedn = ldb_dn_new(tmp_ctx, conn->ldb, NULL);
+       if ( ! ldb_dn_validate(basedn)) {
                goto failed;
        }
 
@@ -250,12 +250,13 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
                goto failed;
        }
 
-       conf_dn = ldb_msg_find_attr_as_dn(tmp_ctx, res->msgs[0], "configurationNamingContext");
+       conf_dn = ldb_msg_find_attr_as_dn(conn->ldb, tmp_ctx, res->msgs[0], "configurationNamingContext");
        if (conf_dn == NULL) {
                goto failed;
        }
 
-       policy_dn = ldb_dn_string_compose(tmp_ctx, conf_dn, "CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services");
+       policy_dn = ldb_dn_copy(tmp_ctx, conf_dn);
+       ldb_dn_add_child_fmt(policy_dn, "CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services");
        if (policy_dn == NULL) {
                goto failed;
        }
index faaca3877efd6cd61c07979d60f6afc67a7f5ccc..035ef01a8f553ed1b48492c7e70481c9ea4c1cff 100644 (file)
@@ -30,7 +30,7 @@
 */
 int gendb_search_v(struct ldb_context *ldb, 
                   TALLOC_CTX *mem_ctx,
-                  const struct ldb_dn *basedn,
+                  struct ldb_dn *basedn,
                   struct ldb_message ***msgs,
                   const char * const *attrs,
                   const char *format, 
@@ -79,7 +79,7 @@ int gendb_search_v(struct ldb_context *ldb,
 */
 int gendb_search(struct ldb_context *ldb,
                 TALLOC_CTX *mem_ctx, 
-                const struct ldb_dn *basedn,
+                struct ldb_dn *basedn,
                 struct ldb_message ***res,
                 const char * const *attrs,
                 const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
@@ -100,7 +100,7 @@ int gendb_search(struct ldb_context *ldb,
 
 int gendb_search_dn(struct ldb_context *ldb,
                 TALLOC_CTX *mem_ctx, 
-                const struct ldb_dn *dn,
+                struct ldb_dn *dn,
                 struct ldb_message ***res,
                 const char * const *attrs)
 {
index cb1dfa105f0959d35f8e08587a9eb20e8c772626..372793a103c78cbb975ac356d09017f6fd3f8e1b 100644 (file)
@@ -234,8 +234,8 @@ static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx,
        out->length = 0;
        out->data = NULL;
 
-       dn = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)in->data);
-       if (dn == NULL) {
+       dn = ldb_dn_new(ldb, mem_ctx, (char *)in->data);
+       if ( ! ldb_dn_validate(dn)) {
                return -1;
        }
 
@@ -262,16 +262,16 @@ static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx,
        struct ldb_dn *dn1 = NULL, *dn2 = NULL;
        int ret;
 
-       dn1 = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)v1->data);
-       if (dn1 == NULL) return -1;
+       dn1 = ldb_dn_new(ldb, mem_ctx, (char *)v1->data);
+       if ( ! ldb_dn_validate(dn1)) return -1;
 
-       dn2 = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)v2->data);
-       if (dn2 == NULL) {
+       dn2 = ldb_dn_new(ldb, mem_ctx, (char *)v2->data);
+       if ( ! ldb_dn_validate(dn2)) {
                talloc_free(dn1);
                return -1;
        } 
 
-       ret = ldb_dn_compare(ldb, dn1, dn2);
+       ret = ldb_dn_compare(dn1, dn2);
 
        talloc_free(dn1);
        talloc_free(dn2);
index 9e0ee6ebca96bea13fe5cf705ee0f847b869402a..c05f8313f1dcb5d674bfbfd6cf435b50236c1e00 100644 (file)
@@ -153,7 +153,7 @@ int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *op
   pet hates about ldapsearch, which is that you have to get a long,
   complex basedn right to make any use of it.
 */
-static const struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb)
+static struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb)
 {
        TALLOC_CTX *tmp_ctx;
        int ret;
@@ -167,11 +167,11 @@ static const struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb)
        }
 
        tmp_ctx = talloc_new(ldb);
-       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx), LDB_SCOPE_BASE, 
+       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, NULL), LDB_SCOPE_BASE, 
                         "(objectClass=*)", attrs, &res);
        if (ret == LDB_SUCCESS) {
                if (res->count == 1) {
-                       basedn = ldb_msg_find_attr_as_dn(ldb, res->msgs[0], "defaultNamingContext");
+                       basedn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "defaultNamingContext");
                        ldb_set_opaque(ldb, "default_baseDN", basedn);
                }
                talloc_free(res);
@@ -181,9 +181,9 @@ static const struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb)
        return basedn;
 }
 
-const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
+struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
 {
-       return (const struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN");
+       return (struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN");
 }
 
 /* 
@@ -582,7 +582,7 @@ error:
 int ldb_build_search_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *base,
+                       struct ldb_dn *base,
                        enum ldb_scope scope,
                        const char *expression,
                        const char * const *attrs,
@@ -602,7 +602,7 @@ int ldb_build_search_req(struct ldb_request **ret_req,
 
        req->operation = LDB_SEARCH;
        if (base == NULL) {
-               req->op.search.base = ldb_dn_new(req);
+               req->op.search.base = ldb_dn_new(req, ldb, NULL);
        } else {
                req->op.search.base = base;
        }
@@ -685,7 +685,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
 int ldb_build_del_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *dn,
+                       struct ldb_dn *dn,
                        struct ldb_control **controls,
                        void *context,
                        ldb_request_callback_t callback)
@@ -714,8 +714,8 @@ int ldb_build_del_req(struct ldb_request **ret_req,
 int ldb_build_rename_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *olddn,
-                       const struct ldb_dn *newdn,
+                       struct ldb_dn *olddn,
+                       struct ldb_dn *newdn,
                        struct ldb_control **controls,
                        void *context,
                        ldb_request_callback_t callback)
@@ -747,7 +747,7 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
   defaultNamingContext from the rootDSE if available.
 */
 int ldb_search(struct ldb_context *ldb, 
-              const struct ldb_dn *base,
+              struct ldb_dn *base,
               enum ldb_scope scope,
               const char *expression,
               const char * const *attrs, 
@@ -861,7 +861,7 @@ int ldb_modify(struct ldb_context *ldb,
 /*
   delete a record from the database
 */
-int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
+int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
 {
        struct ldb_request *req;
        int ret;
@@ -886,7 +886,7 @@ int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
 /*
   rename a record in the database
 */
-int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
+int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn)
 {
        struct ldb_request *req;
        int ret;
index 48f471bf6fdf86a1d8a1b439ff7db02a01c36bd6..0a10ed6f2e5fc81bf7bab1eff7fd344ad26999a6 100644 (file)
 /*
  *  Name: ldb
  *
- *  Component: ldb dn explode and utility functions
+ *  Component: ldb dn creation and manipulation utility functions
  *
  *  Description: - explode a dn into it's own basic elements
- *                 and put them in a structure
+ *                 and put them in a structure (only if necessary)
  *               - manipulate ldb_dn structures
  *
  *  Author: Simo Sorce
  */
 
 #include "includes.h"
+#include <ctype.h>
 #include "ldb/include/includes.h"
 
 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
 
-#define LDB_SPECIAL "@SPECIAL"
+#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
 
 /**
    internal ldb exploded dn structures
 */
 struct ldb_dn_component {
-       char *name;  
+
+       char *name;
        struct ldb_val value;
+
+       char *cf_name;
+       struct ldb_val cf_value;
 };
 
 struct ldb_dn {
-       int comp_num;
+
+       struct ldb_context *ldb;
+
+       /* Special DNs are always linearized */
+       bool special;
+       bool invalid;
+
+       bool valid_lin;
+       bool valid_comp;
+       bool valid_case;
+
+       char *linearized;
+       char *casefold;
+
+       unsigned int comp_num;
        struct ldb_dn_component *components;
+
 };
 
-int ldb_dn_is_special(const struct ldb_dn *dn)
+/* strdn may be NULL */
+struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
 {
-       if (dn == NULL || dn->comp_num != 1) return 0;
+       struct ldb_dn *dn;
 
-       return ! strcmp(dn->components[0].name, LDB_SPECIAL);
-}
+       if ( (! mem_ctx) || (! ldb)) return NULL;
 
-int ldb_dn_check_special(const struct ldb_dn *dn, const char *check)
-{
-       if (dn == NULL || dn->comp_num != 1) return 0;
+       dn = talloc_zero(mem_ctx, struct ldb_dn);
+       LDB_DN_NULL_FAILED(dn);
+
+       dn->ldb = ldb;
+
+       if (strdn) {
+               if (strdn[0] == '@') {
+                       dn->special = true;
+               }
+               if (strncasecmp(strdn, "<GUID=", 6) == 0) {
+                       /* this is special DN returned when the
+                        * exploded_dn control is used */
+                       dn->special = true;
+                       /* FIXME: add a GUID string to ldb_dn structure */
+               }
+               dn->linearized = talloc_strdup(dn, strdn);
+       } else {
+               dn->linearized = talloc_strdup(dn, "");
+       }
+       LDB_DN_NULL_FAILED(dn->linearized);
+
+       dn->valid_lin = true;
+
+       return dn;
 
-       return ! strcmp((char *)dn->components[0].value.data, check);
+failed:
+       talloc_free(dn);
+       return NULL;
 }
 
-char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
+struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
 {
-       const char *p, *s, *src;
-       char *d, *dst;
-       int len;
+       struct ldb_dn *dn;
+       char *strdn;
+       va_list ap;
 
-       if (!value.length)
-               return NULL;
+       if ( (! mem_ctx) || (! ldb)) return NULL;
+
+       dn = talloc_zero(mem_ctx, struct ldb_dn);
+       LDB_DN_NULL_FAILED(dn);
 
-       p = s = src = (const char *)value.data;
-       len = value.length;
+       dn->ldb = ldb;
 
-       /* allocate destination string, it will be at most 3 times the source */
-       dst = d = talloc_array(mem_ctx, char, len * 3 + 1);
-       LDB_DN_NULL_FAILED(dst);
+       va_start(ap, new_fmt);
+       strdn = talloc_vasprintf(dn, new_fmt, ap);
+       va_end(ap);
+       LDB_DN_NULL_FAILED(strdn);
+
+       if (strdn[0] == '@') {
+               dn->special = true;
+       }
+       if (strncasecmp(strdn, "<GUID=", 6) == 0) {
+               /* this is special DN returned when the
+                * exploded_dn control is used */
+               dn->special = true;
+               /* FIXME: add a GUID string to ldb_dn structure */
+       }
+       dn->linearized = strdn;
+
+       dn->valid_lin = true;
+
+       return dn;
+
+failed:
+       talloc_free(dn);
+       return NULL;
+}
+
+static int ldb_dn_escape_internal(char *dst, const char *src, int len)
+{
+       const char *p, *s;
+       char *d;
+       int l;
+
+       p = s = src;
+       d = dst;
 
        while (p - src < len) {
 
@@ -99,404 +173,500 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
                        *d++ = *p++;
                } else { /* we have a zero byte in the string */
                        strncpy(d, "\00", 3); /* escape the zero */
-                       d = d + 3;
+                       d += 3;
                        p++; /* skip the zero */
                }
                s = p; /* move forward */
        }
 
        /* copy the last part (with zero) and return */
-       memcpy(d, s, &src[len] - s + 1);
+       l = len - (s - src);
+       memcpy(d, s, l + 1);
 
-       return dst;
-
-failed:
-       talloc_free(dst);
-       return NULL;
-}
+       /* return the length of the resulting string */
+       return (l + (d - dst));
+} 
 
-static struct ldb_val ldb_dn_unescape_value(void *mem_ctx, const char *src)
+char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
 {
-       struct ldb_val value;
-       unsigned x;
-       char *p, *dst = NULL, *end;
-
-       memset(&value, 0, sizeof(value));
-
-       LDB_DN_NULL_FAILED(src);
-
-       dst = p = (char *)talloc_memdup(mem_ctx, src, strlen(src) + 1);
-       LDB_DN_NULL_FAILED(dst);
-
-       end = &dst[strlen(dst)];
-
-       while (*p) {
-               p += strcspn(p, ",=\n+<>#;\\\"");
-
-               if (*p == '\\') {
-                       if (strchr(",=\n+<>#;\\\"", p[1])) {
-                               memmove(p, p + 1, end - (p + 1) + 1);
-                               end--;
-                               p++;
-                               continue;
-                       }
+       char *dst;
 
-                       if (sscanf(p + 1, "%02x", &x) == 1) {
-                               *p = (unsigned char)x;
-                               memmove(p + 1, p + 3, end - (p + 3) + 1);
-                               end -= 2;
-                               p++;
-                               continue;
-                       }
-               }
+       if (!value.length)
+               return NULL;
 
-               /* a string with not escaped specials is invalid (tested) */
-               if (*p != '\0') {
-                       goto failed;
-               }
+       /* allocate destination string, it will be at most 3 times the source */
+       dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
+       if ( ! dst) {
+               talloc_free(dst);
+               return NULL;
        }
 
-       value.length = end - dst;
-       value.data = (uint8_t *)dst;
-       return value;
+       ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
 
-failed:
-       talloc_free(dst);
-       return value;
+       return dst;
 }
 
-/* check if the string contains quotes
- * skips leading and trailing spaces
- * - returns 0 if no quotes found
- * - returns 1 if quotes are found and put their position
- *   in *quote_start and *quote_end parameters
- * - return -1 if there are open quotes
- */
-
-static int get_quotes_position(const char *source, int *quote_start, int *quote_end)
+/*
+  explode a DN string into a ldb_dn structure
+  based on RFC4514 except that we don't support multiple valued RDNs
+*/
+static bool ldb_dn_explode(struct ldb_dn *dn)
 {
-       const char *p;
-
-       if (source == NULL || quote_start == NULL || quote_end == NULL) return -1;
-
-       p = source;
-
-       /* check if there are quotes surrounding the value */
-       p += strspn(p, " \n"); /* skip white spaces */
+       char *p, *data, *d, *dt, *t;
+       bool trim = false;
+       bool in_attr = false;
+       bool in_value = false;
+       bool in_quote = false;
+       bool is_oid = false;
+       bool escape = false;
+       unsigned x;
+       int l;
 
-       if (*p == '\"') {
-               *quote_start = p - source;
+       if ( ! dn || dn->invalid) return false;
 
-               p++;
-               while (*p != '\"') {
-                       p = strchr(p, '\"');
-                       LDB_DN_NULL_FAILED(p);
+       if (dn->valid_comp) {
+               return true;
+       }
 
-                       if (*(p - 1) == '\\')
-                               p++;
-               }
+       if ( ! dn->valid_lin) {
+               return false;
+       }
 
-               *quote_end = p - source;
-               return 1;
+       /* Empty DNs */
+       if (dn->linearized[0] == '\0') {
+               dn->valid_comp = true;
+               return true;
        }
 
-       return 0;
+       /* Special DNs case */
+       if (dn->special) {
+               return true;
+       }
 
-failed:
-       return -1;
-}
+       /* in the common case we have 3 or more components */
+       /* make sure all components are zeroed, other functions depend on this */
+       dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
+       if ( ! dn->components) {
+               return false;
+       }
+       dn->comp_num = 0;
 
-static char *seek_to_separator(char *string, const char *separators)
-{
-       char *p, *q;
-       int ret, qs, qe, escaped;
+       /* Components data space is allocated here once */
+       data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
 
-       if (string == NULL || separators == NULL) return NULL;
+       p = dn->linearized;
+       in_attr = true;
+       trim = true;
+       t = NULL;
+       d = dt = data;
 
-       p = strchr(string, '=');
-       LDB_DN_NULL_FAILED(p);
+       while (*p) {
 
-       p++;
+               if (in_attr) {
+                       if (trim) {
+                               if (*p == ' ') {
+                                       p++;
+                                       continue;
+                               }
+
+                               /* first char */
+                               trim = false;
+
+                               if (isdigit(*p)) {
+                                       is_oid = true;
+                               } else
+                               if ( ! isalpha(*p)) {
+                                       /* not a digit nor an alpha, invalid attribute name */
+                                       dn->invalid = true;
+                                       goto failed;
+                               }
+                               
+                               *d++ = *p++;
+                               continue;
+                       }
 
-       /* check if there are quotes surrounding the value */
+                       if (*p == ' ') {
+                               p++;
+                               /* valid only if we are at the end */
+                               trim = true;
+                               continue;
+                       }
 
-       ret = get_quotes_position(p, &qs, &qe);
-       if (ret == -1)
-               return NULL;
+                       if (trim && (*p != '=')) {
+                               /* spaces/tabs are not allowed in attribute names */
+                               dn->invalid = true;
+                               goto failed;
+                       }
 
-       if (ret == 1) { /* quotes found */
+                       if (*p == '=') {
+                               /* attribute terminated */
+                               in_attr = false;
+                               in_value = true;
+                               trim = true;
+                               l = 0;
 
-               p += qe; /* positioning after quotes */
-               p += strspn(p, " \n"); /* skip white spaces after the quote */
+                               *d++ = '\0';
+                               dn->components[dn->comp_num].name = dt;
+                               dt = d;
 
-               if (strcspn(p, separators) != 0) /* if there are characters between quotes */
-                       return NULL;        /* and separators, the dn is invalid */
+                               p++;
+                               continue;
+                       }
 
-               return p; /* return on the separator */
-       }
+                       if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
+                               /* not a digit nor a dot, invalid attribute oid */
+                               dn->invalid = true;
+                               goto failed;
+                       } else
+                       if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
+                               /* not ALPHA, DIGIT or HYPHEN */
+                               dn->invalid = true;
+                               goto failed;
+                       }
 
-       /* no quotes found seek to separators */
-       q = p;
-       do {
-               escaped = 0;
-               ret = strcspn(q, separators);
-               
-               if (q[ret - 1] == '\\') {
-                       escaped = 1;
-                       q = q + ret + 1;
+                       *d++ = *p++;
+                       continue;
                }
-       } while (escaped);
-
-       if (ret == 0 && p == q) /* no separators ?! bail out */
-               return NULL;
 
-       return q + ret;
+               if (in_value) {
+                       if (in_quote) {
+                               if (*p == '\"') {
+                                       if (p[-1] != '\\') {
+                                               p++;
+                                               in_quote = false;
+                                               continue;
+                                       }
+                               }
+                               *d++ = *p++;
+                               l++;
+                               continue;
+                       }
 
-failed:
-       return NULL;
-}
+                       if (trim) {
+                               if (*p == ' ') {
+                                       p++;
+                                       continue;
+                               }
 
-static char *ldb_dn_trim_string(char *string, const char *edge)
-{
-       char *s, *p;
+                               /* first char */
+                               trim = false;
 
-       /* seek out edge from start of string */
-       s = string + strspn(string, edge);
+                               if (*p == '\"') {
+                                       in_quote = true;
+                                       p++;
+                                       continue;
+                               }
+                       }
 
-       /* backwards skip from end of string */
-       p = &s[strlen(s) - 1];
-       while (p > s && strchr(edge, *p)) {
-               *p = '\0';
-               p--;
-       }
+                       switch (*p) {
 
-       return s;
-}
+                       /* TODO: support ber encoded values
+                       case '#':
+                       */
 
-/* we choosed to not support multpile valued components */
-static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw_component)
-{
-       struct ldb_dn_component dc;
-       char *p;
-       int ret, qs, qe;
+                       case ',':
+                               if (escape) {
+                                       *d++ = *p++;
+                                       l++;
+                                       escape = false;
+                                       continue;
+                               }
+                               /* ok found value terminator */
 
-       memset(&dc, 0, sizeof(dc));
+                               if ( t ) {
+                                       /* trim back */
+                                       d -= (p - t);
+                                       l -= (p - t);
+                               }
 
-       if (raw_component == NULL) {
-               return dc;
-       }
+                               in_attr = true;
+                               in_value = false;
+                               trim = true;
 
-       /* find attribute type/value separator */
-       p = strchr(raw_component, '=');
-       LDB_DN_NULL_FAILED(p);
+                               p++;
+                               *d++ = '\0';
+                               dn->components[dn->comp_num].value.data = (uint8_t *)dt;
+                               dn->components[dn->comp_num].value.length = l;
+                               dt = d;
+
+                               dn->comp_num++;
+                               if (dn->comp_num > 2) {
+                                       dn->components = talloc_realloc(dn,
+                                                                       dn->components,
+                                                                       struct ldb_dn_component,
+                                                                       dn->comp_num + 1);
+                                       if ( ! dn->components) {
+                                               /* ouch ! */
+                                               goto failed;
+                                       }
+                                       /* make sure all components are zeroed, other functions depend on this */
+                                       memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
+                               }
 
-       *p++ = '\0'; /* terminate name and point to value */
+                               continue;
 
-       /* copy and trim name in the component */
-       dc.name = talloc_strdup(mem_ctx, ldb_dn_trim_string(raw_component, " \n"));
-       if (!dc.name)
-               return dc;
+                       case '=':
+                       case '\n':
+                       case '+':
+                       case '<':
+                       case '>':
+                       case '#':
+                       case ';':
+                       case '\"':
+                               /* a string with not escaped specials is invalid (tested) */
+                               if ( ! escape) {
+                                       dn->invalid = true;
+                                       goto failed;
+                               }
+                               escape = false;
+
+                               *d++ = *p++;
+                               l++;
+
+                               if ( t ) t = NULL;
+                               break;
+
+                       case '\\':
+                               if ( ! escape) {
+                                       escape = true;
+                                       p++;
+                                       continue;
+                               }
+                               escape = false;
+
+                               *d++ = *p++;
+                               l++;
+
+                               if ( t ) t = NULL;
+                               break;
+
+                       default:
+                               if (escape) {
+                                       if (sscanf(p, "%02x", &x) != 1) {
+                                               /* invalid escaping sequence */
+                                               dn->invalid = true;
+                                               goto failed;
+                                       }
+                                       escape = false;
+
+                                       p += 2;
+                                       *d++ = (unsigned char)x;
+                                       l++;
+
+                                       if ( t ) t = NULL;
+                                       break;
+                               }
+
+                               if (*p == ' ') { 
+                                       if ( ! t) t = p;
+                               } else {
+                                       if ( t ) t = NULL;
+                               }
+
+                               *d++ = *p++;
+                               l++;
+                               
+                               break;
+                       }
 
-       if (! ldb_valid_attr_name(dc.name)) {
-               goto failed;
+               }
        }
 
-       ret = get_quotes_position(p, &qs, &qe);
-
-       switch (ret) {
-       case 0: /* no quotes trim the string */
-               p = ldb_dn_trim_string(p, " \n");
-               dc.value = ldb_dn_unescape_value(mem_ctx, p);
-               break;
-
-       case 1: /* quotes found get the unquoted string */
-               p[qe] = '\0';
-               p = p + qs + 1;
-               dc.value.length = strlen(p);
-               dc.value.data = (uint8_t *)talloc_memdup(mem_ctx, p,
-                                                        dc.value.length + 1);
-               break;
-
-       default: /* mismatched quotes ot other error, bail out */
+       if (in_attr || in_quote) {
+               /* invalid dn */
+               dn->invalid = true;
                goto failed;
        }
 
-       if (dc.value.length == 0) {
-               goto failed;
+       /* save last element */
+       if ( t ) {
+               /* trim back */
+               d -= (p - t);
+               l -= (p - t);
        }
 
-       return dc;
+       *d++ = '\0';
+       dn->components[dn->comp_num].value.data = (uint8_t *)dt;
+       dn->components[dn->comp_num].value.length = l;
+
+       dn->comp_num++;
+
+       dn->valid_comp = true;
+       return true;
 
 failed:
-       talloc_free(dc.name);
-       dc.name = NULL;
-       return dc;
+       talloc_free(dn->components);
+       return false;
 }
 
-struct ldb_dn *ldb_dn_new(void *mem_ctx)
+bool ldb_dn_validate(struct ldb_dn *dn)
 {
-       struct ldb_dn *edn;
-
-       edn = talloc(mem_ctx, struct ldb_dn);
-       LDB_DN_NULL_FAILED(edn);
-
-       /* Initially there are no components */
-       edn->comp_num = 0;
-       edn->components = NULL;
-
-       return edn;
-
-failed:
-       return NULL;
+       return ldb_dn_explode(dn);
 }
 
-/*
-  explode a DN string into a ldb_dn structure
-*/
-struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
+const char *ldb_dn_get_linearized(struct ldb_dn *dn)
 {
-       struct ldb_dn *edn; /* the exploded dn */
-       char *pdn, *p;
+       int i, len;
+       char *d, *n;
+
+       if ( ! dn || ( dn->invalid)) return NULL;
 
-       if (dn == NULL) return NULL;
+       if (dn->valid_lin) return dn->linearized;
 
-       /* Allocate a structure to hold the exploded DN */
-       edn = ldb_dn_new(mem_ctx);
-       if (edn == NULL) {
+       if ( ! dn->valid_comp) {
+               dn->invalid = true;
                return NULL;
        }
 
-       pdn = NULL;
-
-       /* Empty DNs */
-       if (dn[0] == '\0') {
-               return edn;
+       if (dn->comp_num == 0) {
+               dn->linearized = talloc_strdup(dn, "");
+               if ( ! dn->linearized) return NULL;
+               dn->valid_lin = true;
+               return dn->linearized;
        }
 
-       /* Special DNs case */
-       if (dn[0] == '@') {
-               edn->comp_num = 1;
-               edn->components = talloc(edn, struct ldb_dn_component);
-               if (edn->components == NULL) goto failed;
-               edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL);
-               if (edn->components[0].name == NULL) goto failed;
-               edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn);
-               if (edn->components[0].value.data== NULL) goto failed;
-               edn->components[0].value.length = strlen(dn);
-               return edn;
+       /* calculate maximum possible length of DN */
+       for (len = 0, i = 0; i < dn->comp_num; i++) {
+               len += strlen(dn->components[i].name); /* name len */
+               len += (dn->components[i].value.length * 3); /* max escaped data len */
+               len += 2; /* '=' and ',' */
        }
+       dn->linearized = talloc_array(dn, char, len);
+       if ( ! dn->linearized) return NULL;
 
-       pdn = p = talloc_strdup(edn, dn);
-       LDB_DN_NULL_FAILED(pdn);
+       d = dn->linearized;
 
-       /* get the components */
-       do {
-               char *t;
+       for (i = 0; i < dn->comp_num; i++) {
 
-               /* terminate the current component and return pointer to the next one */
-               t = seek_to_separator(p, ",;");
-               LDB_DN_NULL_FAILED(t);
+               /* copy the name */
+               n = dn->components[i].name;
+               while (*n) *d++ = *n++;
 
-               if (*t) { /* here there is a separator */
-                       *t = '\0'; /*terminate */
-                       t++; /* a separtor means another component follows */
-               }
-
-               /* allocate space to hold the dn component */
-               edn->components = talloc_realloc(edn, edn->components,
-                                                struct ldb_dn_component,
-                                                edn->comp_num + 1);
-               if (edn->components == NULL)
-                       goto failed;
+               *d++ = '=';
 
-               /* store the exploded component in the main structure */
-               edn->components[edn->comp_num] = ldb_dn_explode_component(edn, p);
-               LDB_DN_NULL_FAILED(edn->components[edn->comp_num].name);
+               /* and the value */
+               d += ldb_dn_escape_internal( d,
+                               (char *)dn->components[i].value.data,
+                               dn->components[i].value.length);
+               *d++ = ',';
+       }
 
-               edn->comp_num++;
+       *(--d) = '\0';
 
-               /* jump to the next component if any */
-               p = t;
+       dn->valid_lin = true;
 
-       } while(*p);
+       /* don't waste more memory than necessary */
+       dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
 
-       talloc_free(pdn);
-       return edn;
+       return dn->linearized;
+}
 
-failed:
-       talloc_free(pdn);
-       talloc_free(edn);
-       return NULL;
+char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *dn)
+{
+       return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
 }
 
-struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn)
+/*
+  casefold a dn. We need to casefold the attribute names, and canonicalize 
+  attribute values of case insensitive attributes.
+*/
+
+static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
 {
-       struct ldb_dn *edn; /* the exploded dn */
+       int i, ret;
 
-       if (dn == NULL) return NULL;
+       if ( ! dn || dn->invalid) return false;
 
-       if (strncasecmp(dn, "<GUID=", 6) == 0) {
-               /* this is special DN returned when the
-                * exploded_dn control is used
-                */
+       if (dn->valid_case) return true;
+
+       if (( ! dn->valid_comp) && ( ! ldb_dn_explode(dn))) {
+               return false;
+       }
 
-               /* Allocate a structure to hold the exploded DN */
-               edn = ldb_dn_new(mem_ctx);
+       for (i = 0; i < dn->comp_num; i++) {
+               struct ldb_dn_component dc;
+               const struct ldb_attrib_handler *h;
 
-               edn->comp_num = 1;
-               edn->components = talloc(edn, struct ldb_dn_component);
-               if (edn->components == NULL) goto failed;
-               edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL);
-               if (edn->components[0].name == NULL) goto failed;
-               edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn);
-               if (edn->components[0].value.data== NULL) goto failed;
-               edn->components[0].value.length = strlen(dn);
-               return edn;
+               memset(&dc, 0, sizeof(dc));
+               dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
+               if (!dn->components[i].cf_name) {
+                       return false;
+               }
 
+               h = ldb_attrib_handler(dn->ldb, dn->components[i].cf_name);
+               ret = h->canonicalise_fn(dn->ldb, dn->components,
+                                        &(dn->components[i].value),
+                                        &(dn->components[i].cf_value));
+               if (ret != 0) {
+                       return false;
+               }
        }
-       
-       return ldb_dn_explode(mem_ctx, dn);
 
-failed:
-       talloc_free(edn);
-       return NULL;
+       return true;
 }
 
-char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn)
+const char *ldb_dn_get_casefold(struct ldb_dn *dn)
 {
-       char *dn, *value;
-       int i;
-
-       if (edn == NULL) return NULL;
+       int i, len;
+       char *d, *n;
 
-       /* Special DNs */
-       if (ldb_dn_is_special(edn)) {
-               dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data);
-               return dn;
+       if ( ! ldb_dn_casefold_internal(dn)) {
+               return NULL;
        }
 
-       dn = talloc_strdup(mem_ctx, "");
-       LDB_DN_NULL_FAILED(dn);
-
-       for (i = 0; i < edn->comp_num; i++) {
-               value = ldb_dn_escape_value(dn, edn->components[i].value);
-               LDB_DN_NULL_FAILED(value);
+       if (dn->casefold) return dn->casefold;
 
-               if (i == 0) {
-                       dn = talloc_asprintf_append(dn, "%s=%s", edn->components[i].name, value);
+       if (dn->comp_num == 0) {
+               if (dn->special) {
+                       len = strlen(dn->linearized);
+                       dn->casefold = talloc_array(dn, char, len * 3 + 1);
+                       if ( ! dn->casefold) return NULL;
+                       ldb_dn_escape_internal(dn->casefold, dn->linearized, len);
+                       /* don't waste more memory than necessary */
+                       dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
                } else {
-                       dn = talloc_asprintf_append(dn, ",%s=%s", edn->components[i].name, value);
+                       dn->casefold = talloc_strdup(dn, "");
+                       if ( ! dn->casefold) return NULL;
                }
-               LDB_DN_NULL_FAILED(dn);
+               dn->valid_case = true;
+               return dn->casefold;
+       }
 
-               talloc_free(value);
+       /* calculate maximum possible length of DN */
+       for (len = 0, i = 0; i < dn->comp_num; i++) {
+               len += strlen(dn->components[i].cf_name); /* name len */
+               len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
+               len += 2; /* '=' and ',' */
        }
+       dn->casefold = talloc_array(dn, char, len);
+       if ( ! dn->casefold) return NULL;
 
-       return dn;
+       d = dn->casefold;
 
-failed:
-       talloc_free(dn);
-       return NULL;
+       for (i = 0; i < dn->comp_num; i++) {
+
+               /* copy the name */
+               n = dn->components[i].cf_name;
+               while (*n) *d++ = *n++;
+
+               *d++ = '=';
+
+               /* and the value */
+               d += ldb_dn_escape_internal( d,
+                               (char *)dn->components[i].cf_value.data,
+                               dn->components[i].cf_value.length);
+               *d++ = ',';
+       }
+       *(--d) = '\0';
+
+       dn->valid_case = true;
+
+       return dn->casefold;
+}
+
+char *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *dn)
+{
+       return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
 }
 
 /* Determine if dn is below base, in the ldap tree.  Used for
@@ -504,42 +674,65 @@ failed:
  * 0 if they match, otherwise non-zero
  */
 
-int ldb_dn_compare_base(struct ldb_context *ldb,
-                       const struct ldb_dn *base,
-                       const struct ldb_dn *dn)
+int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
 {
        int ret;
-       int n0, n1;
+       int n_base, n_dn;
+
+       if ( ! base || base->invalid) return 1;
+       if ( ! dn || dn->invalid) return -1;
+
+       if (( ! base->valid_case) || ( ! dn->valid_case)) {
+               if (base->valid_lin && dn->valid_lin) {
+                       /* try with a normal compare first, if we are lucky
+                        * we will avoid exploding and casfolding */
+                       int dif;
+                       dif = strlen(dn->linearized) - strlen(base->linearized);
+                       if (dif < 0) return dif;
+                       if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
+               }
 
-       if (base == NULL || base->comp_num == 0) return 0;
-       if (dn == NULL || dn->comp_num == 0) return -1;
+               if ( ! ldb_dn_casefold_internal(base)) {
+                       return 1;
+               }
 
-       /* if the base has more componts than the dn, then they differ */
+               if ( ! ldb_dn_casefold_internal(dn)) {
+                       return -1;
+               }
+
+       }
+
+       /* if base has more components,
+        * they don't have the same base */
        if (base->comp_num > dn->comp_num) {
                return (dn->comp_num - base->comp_num);
        }
 
-       n0 = base->comp_num - 1;
-       n1 = dn->comp_num - 1;
-       while (n0 >= 0 && n1 >= 0) {
-               const struct ldb_attrib_handler *h;
-
-               /* compare names (attribute names are guaranteed to be ASCII only) */
-               ret = ldb_attr_cmp(base->components[n0].name,
-                                  dn->components[n1].name);
-               if (ret) {
-                       return ret;
+       if (dn->comp_num == 0) {
+               if (dn->special && base->special) {
+                       return strcmp(base->linearized, dn->linearized);
+               } else {
+                       return 0;
                }
+       }
+
+       n_base = base->comp_num - 1;
+       n_dn = dn->comp_num - 1;
 
-               /* names match, compare values */
-               h = ldb_attrib_handler(ldb, base->components[n0].name);
-               ret = h->comparison_fn(ldb, ldb, &(base->components[n0].value),
-                                                 &(dn->components[n1].value));
-               if (ret) {
-                       return ret;
+       while (n_base >= 0) {
+               /* compare attr names */
+               ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
+               if (ret != 0) return ret;
+
+               /* compare attr.cf_value. */ 
+               if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
+                       return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
                }
-               n1--;
-               n0--;
+               ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
+               if (ret != 0) return ret;
+
+               n_base--;
+               n_dn--;
        }
 
        return 0;
@@ -550,350 +743,433 @@ int ldb_dn_compare_base(struct ldb_context *ldb,
    If they match, then return 0
  */
 
-int ldb_dn_compare(struct ldb_context *ldb,
-                  const struct ldb_dn *edn0,
-                  const struct ldb_dn *edn1)
+int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
 {
-       if (edn0 == NULL || edn1 == NULL) return edn1 - edn0;
+       int i, ret;
 
-       if (edn0->comp_num != edn1->comp_num)
-               return (edn1->comp_num - edn0->comp_num);
+       if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
 
-       return ldb_dn_compare_base(ldb, edn0, edn1);
+       if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
+               if (dn0->valid_lin && dn1->valid_lin) {
+                       /* try with a normal compare first, if we are lucky
+                        * we will avoid exploding and casfolding */
+                       if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
+               }
+
+               if ( ! ldb_dn_casefold_internal(dn0)) {
+                       return 1;
+               }
+
+               if ( ! ldb_dn_casefold_internal(dn1)) {
+                       return -1;
+               }
+
+       }
+
+       if (dn0->comp_num != dn1->comp_num) {
+               return (dn1->comp_num - dn0->comp_num);
+       }
+
+       if (dn0->comp_num == 0) {
+               if (dn0->special && dn1->special) {
+                       return strcmp(dn0->linearized, dn1->linearized);
+               } else {
+                       return 0;
+               }
+       }
+
+       for (i = 0; i < dn0->comp_num; i++) {
+               /* compare attr names */
+               ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
+               if (ret != 0) return ret;
+
+               /* compare attr.cf_value. */ 
+               if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
+                       return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
+               }
+               ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
+               if (ret != 0) return ret;
+       }
+
+       return 0;
 }
 
-int ldb_dn_cmp(struct ldb_context *ldb, const char *dn0, const char *dn1)
+static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
 {
-       struct ldb_dn *edn0;
-       struct ldb_dn *edn1;
-       int ret;
+       struct ldb_dn_component dst;
+
+       memset(&dst, 0, sizeof(dst));
 
-       if (dn0 == NULL || dn1 == NULL) return dn1 - dn0;
+       if (src == NULL) {
+               return dst;
+       }
 
-       edn0 = ldb_dn_explode_casefold(ldb, ldb, dn0);
-       if (edn0 == NULL) return 1;
+       dst.value = ldb_val_dup(mem_ctx, &(src->value));
+       if (dst.value.data == NULL) {
+               return dst;
+       }
 
-       edn1 = ldb_dn_explode_casefold(ldb, ldb, dn1);
-       if (edn1 == NULL) {
-               talloc_free(edn0);
-               return -1;
+       dst.name = talloc_strdup(mem_ctx, src->name);
+       if (dst.name == NULL) {
+               LDB_FREE(dst.value.data);
        }
 
-       ret = ldb_dn_compare(ldb, edn0, edn1);
+       if (src->cf_value.data) {
+               dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
+               if (dst.cf_value.data == NULL) {
+                       LDB_FREE(dst.value.data);
+                       LDB_FREE(dst.name);
+                       return dst;
+               }
 
-       talloc_free(edn0);
-       talloc_free(edn1);
+               dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
+               if (dst.cf_name == NULL) {
+                       LDB_FREE(dst.cf_name);
+                       LDB_FREE(dst.value.data);
+                       LDB_FREE(dst.name);
+                       return dst;
+               }
+       } else {
+               dst.cf_value.data = NULL;
+               dst.cf_name = NULL;
+       }
 
-       return ret;
+       return dst;
 }
 
-/*
-  casefold a dn. We need to casefold the attribute names, and canonicalize 
-  attribute values of case insensitive attributes.
-*/
-struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn)
+struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
 {
-       struct ldb_dn *cedn;
-       int i, ret;
-
-       if (edn == NULL) return NULL;
+       struct ldb_dn *new_dn;
 
-       cedn = ldb_dn_new(mem_ctx);
-       if (!cedn) {
+       if (!dn || dn->invalid) {
                return NULL;
        }
 
-       cedn->comp_num = edn->comp_num;
-       cedn->components = talloc_array(cedn, struct ldb_dn_component, edn->comp_num);
-       if (!cedn->components) {
-               talloc_free(cedn);
+       new_dn = talloc_zero(mem_ctx, struct ldb_dn);
+       if ( !new_dn) {
                return NULL;
        }
 
-       for (i = 0; i < edn->comp_num; i++) {
-               struct ldb_dn_component dc;
-               const struct ldb_attrib_handler *h;
+       *new_dn = *dn;
 
-               memset(&dc, 0, sizeof(dc));
-               dc.name = ldb_attr_casefold(cedn->components, edn->components[i].name);
-               if (!dc.name) {
-                       talloc_free(cedn);
+       if (dn->valid_comp) {
+               int i;
+
+               new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
+               if ( ! new_dn->components) {
+                       talloc_free(new_dn);
                        return NULL;
                }
 
-               h = ldb_attrib_handler(ldb, dc.name);
-               ret = h->canonicalise_fn(ldb, cedn->components,
-                                        &(edn->components[i].value),
-                                        &(dc.value));
-               if (ret != 0) {
-                       talloc_free(cedn);
-                       return NULL;
+               for (i = 0; i < dn->comp_num; i++) {
+                       new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
+                       if ( ! new_dn->components[i].value.data) {
+                               talloc_free(new_dn);
+                               return NULL;
+                       }
                }
 
-               cedn->components[i] = dc;
+               if (dn->casefold) {
+                       new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
+                       if ( ! new_dn->casefold) {
+                               talloc_free(new_dn);
+                               return NULL;
+                       }
+               }
        }
 
-       return cedn;
+       if (dn->valid_lin) {
+               new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
+               if ( ! new_dn->linearized) {
+                       talloc_free(new_dn);
+                       return NULL;
+               }
+       }
+
+       return new_dn;
 }
 
-struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn)
+/* modify the given dn by adding a base.
+ *
+ * return true if successful and false if not
+ * if false is returned the dn may be marked invalid
+ */
+bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
 {
-       struct ldb_dn *edn, *cdn;
+       const char *s;
+       char *t;
 
-       if (dn == NULL) return NULL;
+       if ( !base || base->invalid || !dn || dn->invalid) {
+               return false;
+       }
 
-       edn = ldb_dn_explode(ldb, dn);
-       if (edn == NULL) return NULL;
+       if (dn->valid_comp) {
+               int i;
 
-       cdn = ldb_dn_casefold(ldb, mem_ctx, edn);
-       
-       talloc_free(edn);
-       return cdn;
-}
+               if ( ! ldb_dn_validate(base)) {
+                       return false;
+               }
 
-char *ldb_dn_linearize_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn)
-{
-       struct ldb_dn *cdn;
-       char *dn;
+               s = NULL;
+               if (dn->valid_case) {
+                       if ( ! (s = ldb_dn_get_casefold(base))) {
+                               return false;
+                       }
+               }
 
-       if (edn == NULL) return NULL;
+               dn->components = talloc_realloc(dn,
+                                               dn->components,
+                                               struct ldb_dn_component,
+                                               dn->comp_num + base->comp_num);
+               if ( ! dn->components) {
+                       dn->invalid = true;
+                       return false;
+               }
 
-       /* Special DNs */
-       if (ldb_dn_is_special(edn)) {
-               dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data);
-               return dn;
+               for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
+                       dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
+                       if (dn->components[dn->comp_num].value.data == NULL) {
+                               dn->invalid = true;
+                               return false;
+                       }
+               }
+
+               if (s) {
+                       t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
+                       LDB_FREE(dn->casefold);
+                       dn->casefold = t;
+               }
        }
 
-       cdn = ldb_dn_casefold(ldb, mem_ctx, edn);
-       if (cdn == NULL) return NULL;
+       if (dn->valid_lin) {
 
-       dn = ldb_dn_linearize(ldb, cdn);
-       if (dn == NULL) {
-               talloc_free(cdn);
-               return NULL;
+               s = ldb_dn_get_linearized(base);
+               if ( ! s) {
+                       return false;
+               }
+               
+               t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
+               if ( ! t) {
+                       dn->invalid = true;
+                       return false;
+               }
+               LDB_FREE(dn->linearized);
+               dn->linearized = t;
        }
 
-       talloc_free(cdn);
-       return dn;
+       return true;
 }
 
-static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
+/* modify the given dn by adding a base.
+ *
+ * return true if successful and false if not
+ * if false is returned the dn may be marked invalid
+ */
+bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
 {
-       struct ldb_dn_component dst;
-
-       memset(&dst, 0, sizeof(dst));
+       struct ldb_dn *base;
+       char *base_str;
+       va_list ap;
+       bool ret;
 
-       if (src == NULL) {
-               return dst;
+       if ( !dn || dn->invalid) {
+               return false;
        }
 
-       dst.value = ldb_val_dup(mem_ctx, &(src->value));
-       if (dst.value.data == NULL) {
-               return dst;
-       }
+       va_start(ap, base_fmt);
+       base_str = talloc_vasprintf(dn, base_fmt, ap);
+       va_end(ap);
 
-       dst.name = talloc_strdup(mem_ctx, src->name);
-       if (dst.name == NULL) {
-               talloc_free(dst.value.data);
-               dst.value.data = NULL;
+       if (base_str == NULL) {
+               return false;
        }
 
-       return dst;
-}
+       base = ldb_dn_new(base_str, dn->ldb, base_str);
 
-/* Copy a DN but replace the old with the new base DN. */
-struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base)
+       ret = ldb_dn_add_base(dn, base);
+
+       talloc_free(base_str);
+
+       return ret;
+}      
+
+/* modify the given dn by adding children elements.
+ *
+ * return true if successful and false if not
+ * if false is returned the dn may be marked invalid
+ */
+bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
 {
-       struct ldb_dn *new_dn;
-       int i, offset;
+       const char *s;
+       char *t;
 
-       /* Perhaps we don't need to rebase at all? */
-       if (!old_base || !new_base) {
-               return ldb_dn_copy(mem_ctx, old);
+       if ( !child || child->invalid || !dn || dn->invalid) {
+               return false;
        }
 
-       offset = old->comp_num - old_base->comp_num;
-       new_dn = ldb_dn_copy_partial(mem_ctx, new_base, offset + new_base->comp_num);
-       for (i = 0; i < offset; i++) {
-               new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &(old->components[i]));
-       }
+       if (dn->valid_comp) {
+               int n, i, j;
 
-       return new_dn;
-}
+               if ( ! ldb_dn_validate(child)) {
+                       return false;
+               }
 
-/* copy specified number of elements of a dn into a new one
-   element are copied from top level up to the unique rdn
-   num_el may be greater than dn->comp_num (see ldb_dn_make_child)
-*/
-struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el)
-{
-       struct ldb_dn *newdn;
-       int i, n, e;
+               s = NULL;
+               if (dn->valid_case) {
+                       if ( ! (s = ldb_dn_get_casefold(child))) {
+                               return false;
+                       }
+               }
+
+               n = dn->comp_num + child->comp_num;
 
-       if (dn == NULL) return NULL;
-       if (num_el <= 0) return NULL;
+               dn->components = talloc_realloc(dn,
+                                               dn->components,
+                                               struct ldb_dn_component,
+                                               n);
+               if ( ! dn->components) {
+                       dn->invalid = true;
+                       return false;
+               }
 
-       newdn = ldb_dn_new(mem_ctx);
-       LDB_DN_NULL_FAILED(newdn);
+               for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
+                       dn->components[j] = dn->components[i];
+               }
 
-       newdn->comp_num = num_el;
-       n = newdn->comp_num - 1;
-       newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
-       if (newdn->components == NULL) goto failed;
+               for (i = 0; i < child->comp_num; i++) { 
+                       dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
+                       if (dn->components[i].value.data == NULL) {
+                               dn->invalid = true;
+                               return false;
+                       }
+               }
 
-       if (dn->comp_num == 0) return newdn;
-       e = dn->comp_num - 1;
+               dn->comp_num = n;
 
-       for (i = 0; i < newdn->comp_num; i++) {
-               newdn->components[n - i] = ldb_dn_copy_component(newdn->components,
-                                                               &(dn->components[e - i]));
-               if ((e - i) == 0) {
-                       return newdn;
+               if (s) {
+                       t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
+                       LDB_FREE(dn->casefold);
+                       dn->casefold = t;
                }
        }
 
-       return newdn;
+       if (dn->valid_lin) {
 
-failed:
-       talloc_free(newdn);
-       return NULL;
-}
-
-struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn)
-{
-       if (dn == NULL) return NULL;
-       return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num);
-}
+               s = ldb_dn_get_linearized(child);
+               if ( ! s) {
+                       return false;
+               }
+               
+               t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
+               if ( ! t) {
+                       dn->invalid = true;
+                       return false;
+               }
+               LDB_FREE(dn->linearized);
+               dn->linearized = t;
+       }
 
-struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn)
-{
-       if (dn == NULL) return NULL;
-       return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num - 1);
+       return true;
 }
 
-struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr,
-                                               const char *val)
+/* modify the given dn by adding children elements.
+ *
+ * return true if successful and false if not
+ * if false is returned the dn may be marked invalid
+ */
+bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
 {
-       struct ldb_dn_component *dc;
+       struct ldb_dn *child;
+       char *child_str;
+       va_list ap;
+       bool ret;
 
-       if (attr == NULL || val == NULL) return NULL;
+       if ( !dn || dn->invalid) {
+               return false;
+       }
 
-       dc = talloc(mem_ctx, struct ldb_dn_component);
-       if (dc == NULL) return NULL;
+       va_start(ap, child_fmt);
+       child_str = talloc_vasprintf(dn, child_fmt, ap);
+       va_end(ap);
 
-       dc->name = talloc_strdup(dc, attr);
-       if (dc->name ==  NULL) {
-               talloc_free(dc);
-               return NULL;
+       if (child_str == NULL) {
+               return false;
        }
 
-       dc->value.data = (uint8_t *)talloc_strdup(dc, val);
-       if (dc->value.data ==  NULL) {
-               talloc_free(dc);
-               return NULL;
-       }
+       child = ldb_dn_new(child_str, dn->ldb, child_str);
+
+       ret = ldb_dn_add_child(dn, child);
 
-       dc->value.length = strlen(val);
+       talloc_free(child_str);
 
-       return dc;
+       return ret;
 }
 
-struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr,
-                                                const char * value,
-                                                const struct ldb_dn *base)
+bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
 {
-       struct ldb_dn *newdn;
-       if (! ldb_valid_attr_name(attr)) return NULL;
-       if (value == NULL || value == '\0') return NULL; 
-
-       if (base != NULL) {
-               newdn = ldb_dn_copy_partial(mem_ctx, base, base->comp_num + 1);
-               LDB_DN_NULL_FAILED(newdn);
-       } else {
-               newdn = ldb_dn_new(mem_ctx);
-               LDB_DN_NULL_FAILED(newdn);
-
-               newdn->comp_num = 1;
-               newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
+       if ( ! ldb_dn_validate(dn)) {
+               return false;
        }
 
-       newdn->components[0].name = talloc_strdup(newdn->components, attr);
-       LDB_DN_NULL_FAILED(newdn->components[0].name);
+       if (dn->comp_num < num) {
+               return false;
+       }
 
-       newdn->components[0].value.data = (uint8_t *)talloc_strdup(newdn->components, value);
-       LDB_DN_NULL_FAILED(newdn->components[0].value.data);
-       newdn->components[0].value.length = strlen((char *)newdn->components[0].value.data);
+       dn->comp_num -= num;
 
-       return newdn;
+       dn->valid_case = false;
 
-failed:
-       talloc_free(newdn);
-       return NULL;
+       if (dn->valid_lin) {    
+               dn->valid_lin = false;
+               LDB_FREE(dn->linearized);
+       }
 
+       return true;
 }
 
-struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2)
+bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
 {
-       int i;
-       struct ldb_dn *newdn;
+       int i, j;
 
-       if (dn2 == NULL && dn1 == NULL) {
-               return NULL;
+       if ( ! ldb_dn_validate(dn)) {
+               return false;
        }
 
-       if (dn2 == NULL) {
-               newdn = ldb_dn_new(mem_ctx);
-               LDB_DN_NULL_FAILED(newdn);
-
-               newdn->comp_num = dn1->comp_num;
-               newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
-       } else {
-               int comp_num = dn2->comp_num;
-               if (dn1 != NULL) comp_num += dn1->comp_num;
-               newdn = ldb_dn_copy_partial(mem_ctx, dn2, comp_num);
-               LDB_DN_NULL_FAILED(newdn);
+       if (dn->comp_num < num) {
+               return false;
        }
 
-       if (dn1 == NULL) {
-               return newdn;
+       for (i = 0, j = num; j < dn->comp_num; i++, j++) {
+               dn->components[i] = dn->components[j];
        }
 
-       for (i = 0; i < dn1->comp_num; i++) {
-               newdn->components[i] = ldb_dn_copy_component(newdn->components,
-                                                          &(dn1->components[i]));
-               if (newdn->components[i].value.data == NULL) {
-                       goto failed;
-               }
-       }
+       dn->comp_num -= num;
 
-       return newdn;
+       dn->valid_case = false;
 
-failed:
-       talloc_free(newdn);
-       return NULL;
+       if (dn->valid_lin) {    
+               dn->valid_lin = false;
+               LDB_FREE(dn->linearized);
+       }
+
+       return true;
 }
 
-struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...)
+struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
 {
-       struct ldb_dn *dn, *dn1;
-       char *child_str;
-       va_list ap;
-       
-       if (child_fmt == NULL) return NULL;
-
-       va_start(ap, child_fmt);
-       child_str = talloc_vasprintf(mem_ctx, child_fmt, ap);
-       va_end(ap);
-
-       if (child_str == NULL) return NULL;
+       struct ldb_dn *new_dn;
 
-       dn1 = ldb_dn_explode(mem_ctx, child_str);
-       dn = ldb_dn_compose(mem_ctx, dn1, base);
+       new_dn = ldb_dn_copy(mem_ctx, dn);
+       if ( !new_dn ) {
+               return NULL;
+       }
 
-       talloc_free(child_str);
-       talloc_free(dn1);
+       if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
+               talloc_free(new_dn);
+               return NULL;
+       }
 
-       return dn;
+       return new_dn;
 }
 
 /* Create a 'canonical name' string from a DN:
@@ -904,10 +1180,13 @@ struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, c
    There are two formats, the EX format has the last / replaced with a newline (\n).
 
 */
-static char *ldb_dn_canonical(void *mem_ctx, const struct ldb_dn *dn, int ex_format) {
+static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
        int i;
        char *cracked = NULL;
-
+       if ( ! ldb_dn_validate(dn)) {
+               return NULL;
+       }
        /* Walk backwards down the DN, grabbing 'dc' components at first */
        for (i = dn->comp_num - 1 ; i >= 0; i--) {
                if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
@@ -956,38 +1235,55 @@ static char *ldb_dn_canonical(void *mem_ctx, const struct ldb_dn *dn, int ex_for
 }
 
 /* Wrapper functions for the above, for the two different string formats */
-char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn) {
+char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
        return ldb_dn_canonical(mem_ctx, dn, 0);
 
 }
 
-char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn) {
+char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
        return ldb_dn_canonical(mem_ctx, dn, 1);
 }
 
-int ldb_dn_get_comp_num(const struct ldb_dn *dn)
+int ldb_dn_get_comp_num(struct ldb_dn *dn)
 {
+       if ( ! ldb_dn_validate(dn)) {
+               return -1;
+       }
        return dn->comp_num;
 }
 
-const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num)
+const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
 {
+       if ( ! ldb_dn_validate(dn)) {
+               return NULL;
+       }
        if (num >= dn->comp_num) return NULL;
        return dn->components[num].name;
 }
 
-const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num)
+const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
 {
+       if ( ! ldb_dn_validate(dn)) {
+               return NULL;
+       }
        if (num >= dn->comp_num) return NULL;
        return &dn->components[num].value;
 }
 
-const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn) {
+const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
+{
+       if ( ! ldb_dn_validate(dn)) {
+               return NULL;
+       }
        if (dn->comp_num == 0) return NULL;
        return dn->components[0].name;
 }
 
-const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn) {
+const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
+{
+       if ( ! ldb_dn_validate(dn)) {
+               return NULL;
+       }
        if (dn->comp_num == 0) return NULL;
        return &dn->components[0].value;
 }
@@ -997,6 +1293,10 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
        char *n;
        struct ldb_val v;
 
+       if ( ! ldb_dn_validate(dn)) {
+               return LDB_ERR_OTHER;
+       }
+
        if (num >= dn->comp_num) {
                return LDB_ERR_OTHER;
        }
@@ -1017,5 +1317,39 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
        dn->components[num].name = n;
        dn->components[num].value = v;
 
+       if (dn->valid_case) dn->valid_case = false;
+       if (dn->casefold) LDB_FREE(dn->casefold);
+
        return LDB_SUCCESS;
 }
+
+bool ldb_dn_is_valid(struct ldb_dn *dn)
+{
+       if ( ! dn) return false;
+       return ! dn->invalid;
+}
+
+bool ldb_dn_is_special(struct ldb_dn *dn)
+{
+       if ( ! dn || dn->invalid) return false;
+       return dn->special;
+}
+
+bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
+{
+       if ( ! dn || dn->invalid) return false;
+       return ! strcmp(dn->linearized, check);
+}
+
+bool ldb_dn_is_null(struct ldb_dn *dn)
+{
+       if ( ! dn || dn->invalid) return false;
+       if (dn->special) return false;
+       if (dn->valid_comp) {
+               if (dn->comp_num == 0) return true;
+               return false;
+       } else {
+               if (dn->linearized[0] == '\0') return true;
+       }
+       return false;
+}
index 135ce9eecd908c3fc13dcc866541c9b8fd26a329..50e9f5e5904d2aa03bffe7b4b35c6928587e6ae9 100644 (file)
@@ -566,9 +566,9 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                goto failed;
        }
 
-       msg->dn = ldb_dn_explode(msg, (char *)value.data);
+       msg->dn = ldb_dn_new(msg, ldb, (char *)value.data);
 
-       if (msg->dn == NULL) {
+       if ( ! ldb_dn_validate(msg->dn)) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", 
                                  value.data);
                goto failed;
index 0cd220ad60706d9d6baf855d1afdc3087ec7b7e6..524214992b671c8889506d32d7f0b6ffca38e649 100644 (file)
@@ -40,8 +40,8 @@
   check if the scope matches in a search result
 */
 static int ldb_match_scope(struct ldb_context *ldb,
-                          const struct ldb_dn *base,
-                          const struct ldb_dn *dn,
+                          struct ldb_dn *base,
+                          struct ldb_dn *dn,
                           enum ldb_scope scope)
 {
        int ret = 0;
@@ -52,14 +52,14 @@ static int ldb_match_scope(struct ldb_context *ldb,
 
        switch (scope) {
        case LDB_SCOPE_BASE:
-               if (ldb_dn_compare(ldb, base, dn) == 0) {
+               if (ldb_dn_compare(base, dn) == 0) {
                        ret = 1;
                }
                break;
 
        case LDB_SCOPE_ONELEVEL:
                if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
-                       if (ldb_dn_compare_base(ldb, base, dn) == 0) {
+                       if (ldb_dn_compare_base(base, dn) == 0) {
                                ret = 1;
                        }
                }
@@ -67,7 +67,7 @@ static int ldb_match_scope(struct ldb_context *ldb,
                
        case LDB_SCOPE_SUBTREE:
        default:
-               if (ldb_dn_compare_base(ldb, base, dn) == 0) {
+               if (ldb_dn_compare_base(base, dn) == 0) {
                        ret = 1;
                }
                break;
@@ -149,13 +149,12 @@ static int ldb_match_equality(struct ldb_context *ldb,
        int ret;
 
        if (ldb_attr_dn(tree->u.equality.attr) == 0) {
-               valuedn = ldb_dn_explode_casefold(ldb, ldb,
-                                                 (char *)tree->u.equality.value.data);
+               valuedn = ldb_dn_new(ldb, ldb, (char *)tree->u.equality.value.data);
                if (valuedn == NULL) {
                        return 0;
                }
 
-               ret = ldb_dn_compare(ldb, msg->dn, valuedn);
+               ret = ldb_dn_compare(msg->dn, valuedn);
 
                talloc_free(valuedn);
 
@@ -420,7 +419,7 @@ static int ldb_match_message(struct ldb_context *ldb,
 int ldb_match_msg(struct ldb_context *ldb,
                  const struct ldb_message *msg,
                  const struct ldb_parse_tree *tree,
-                 const struct ldb_dn *base,
+                 struct ldb_dn *base,
                  enum ldb_scope scope)
 {
        if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
index a6997b324a19acb228dd3a3bad28b24ecd11088b..28a619ddebd650b2b398124c8cf7b66ab98923af 100644 (file)
@@ -327,7 +327,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
                struct ldb_result *res = NULL;
                struct ldb_dn *mods_dn;
 
-               mods_dn = ldb_dn_explode(mem_ctx, "@MODULES");
+               mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES");
                if (mods_dn == NULL) {
                        talloc_free(mem_ctx);
                        return -1;
index 65d1ecacb7a98ee502a5e94ccd99587371af9bfd..2768786b83bc71eada817b1bc768c0d2a883bda5 100644 (file)
@@ -126,6 +126,7 @@ int ldb_msg_add_empty(      struct ldb_message *msg,
 {
        struct ldb_message_element *els;
 
+       /* FIXME: we should probably leave this to the schema module to check */
        if (! ldb_valid_attr_name(attr_name)) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -411,17 +412,24 @@ const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg,
        return (const char *)v->data;
 }
 
-struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx,
+struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
+                                      void *mem_ctx,
                                       const struct ldb_message *msg,
                                       const char *attr_name)
 {
+       struct ldb_dn *res_dn;
        const struct ldb_val *v;
 
        v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
                return NULL;
        }
-       return ldb_dn_explode(mem_ctx, (const char *)v->data);
+       res_dn = ldb_dn_new(mem_ctx, ldb, (const char *)v->data);
+       if ( ! ldb_dn_validate(res_dn)) {
+               talloc_free(res_dn);
+               return NULL;
+       }
+       return res_dn;
 }
 
 /*
index 17a2ec75569bb06dc98eb83edbcb66f95a5429ef..46894cd3c004d924ecce55bcaa591a049fc5a76d 100644 (file)
@@ -698,7 +698,7 @@ struct ldb_handle {
 };
 
 struct ldb_search {
-       const struct ldb_dn *base;
+       struct ldb_dn *base;
        enum ldb_scope scope;
        const struct ldb_parse_tree *tree;
        const char * const *attrs;
@@ -714,12 +714,12 @@ struct  ldb_modify {
 };
 
 struct ldb_delete {
-       const struct ldb_dn *dn;
+       struct ldb_dn *dn;
 };
 
 struct ldb_rename {
-       const struct ldb_dn *olddn;
-       const struct ldb_dn *newdn;
+       struct ldb_dn *olddn;
+       struct ldb_dn *newdn;
 };
 
 struct ldb_register_control {
@@ -727,7 +727,7 @@ struct ldb_register_control {
 };
 
 struct ldb_register_partition {
-       const struct ldb_dn *dn;
+       struct ldb_dn *dn;
 };
 
 struct ldb_sequence_number {
@@ -825,7 +825,7 @@ int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, co
   return an automatic baseDN from the defaultNamingContext of the rootDSE
   This value have been set in an opaque pointer at connection time
 */
-const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
+struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
 
 
 /**
@@ -868,7 +868,7 @@ int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct l
 int ldb_build_search_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *base,
+                       struct ldb_dn *base,
                        enum ldb_scope scope,
                        const char *expression,
                        const char * const *attrs,
@@ -937,7 +937,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
 int ldb_build_del_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *dn,
+                       struct ldb_dn *dn,
                        struct ldb_control **controls,
                        void *context,
                        ldb_request_callback_t callback);
@@ -960,8 +960,8 @@ int ldb_build_del_req(struct ldb_request **ret_req,
 int ldb_build_rename_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
                        void *mem_ctx,
-                       const struct ldb_dn *olddn,
-                       const struct ldb_dn *newdn,
+                       struct ldb_dn *olddn,
+                       struct ldb_dn *newdn,
                        struct ldb_control **controls,
                        void *context,
                        ldb_request_callback_t callback);
@@ -984,7 +984,7 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
   \note use talloc_free() to free the ldb_result returned
 */
 int ldb_search(struct ldb_context *ldb, 
-              const struct ldb_dn *base,
+              struct ldb_dn *base,
               enum ldb_scope scope,
               const char *expression,
               const char * const *attrs, struct ldb_result **res);
@@ -993,7 +993,7 @@ int ldb_search(struct ldb_context *ldb,
   like ldb_search() but takes a parse tree
 */
 int ldb_search_bytree(struct ldb_context *ldb, 
-                     const struct ldb_dn *base,
+                     struct ldb_dn *base,
                      enum ldb_scope scope,
                      struct ldb_parse_tree *tree,
                      const char * const *attrs, struct ldb_result **res);
@@ -1043,7 +1043,7 @@ int ldb_modify(struct ldb_context *ldb,
   \return result code (LDB_SUCCESS if the record was renamed as
   requested, otherwise a failure code)
 */
-int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn);
+int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn);
 
 /**
   Delete a record from the database
@@ -1057,7 +1057,7 @@ int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct
   \return result code (LDB_SUCCESS if the record was deleted,
   otherwise a failure code)
 */
-int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn);
+int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn);
 
 /**
   start a transaction
@@ -1269,38 +1269,41 @@ int ldb_attrib_add_handlers(struct ldb_context *ldb,
 
 /* The following definitions come from lib/ldb/common/ldb_dn.c  */
 
-int ldb_dn_is_special(const struct ldb_dn *dn);
-int ldb_dn_check_special(const struct ldb_dn *dn, const char *check);
+struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *dn);
+struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...);
+bool ldb_dn_validate(struct ldb_dn *dn);
+
 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value);
-struct ldb_dn *ldb_dn_new(void *mem_ctx);
-struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn);
-struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn);
-char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn);
-char *ldb_dn_linearize_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn);
-int ldb_dn_compare_base(struct ldb_context *ldb, const struct ldb_dn *base, const struct ldb_dn *dn);
-int ldb_dn_compare(struct ldb_context *ldb, const struct ldb_dn *edn0, const struct ldb_dn *edn1);
-struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn);
-struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn);
-struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el);
-struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn);
-struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base);
-struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn);
-struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr,
-                                                              const char *val);
-struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr,
-                                                const char * value,
-                                                const struct ldb_dn *base);
-struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2);
-struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...) PRINTF_ATTRIBUTE(3,4);
-char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn);
-char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn);
-int ldb_dn_get_comp_num(const struct ldb_dn *dn);
-const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num);
-const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num);
-const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn);
-const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn);
+char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *dn);
+const char *ldb_dn_get_linearized(struct ldb_dn *dn);
+const char *ldb_dn_get_casefold(struct ldb_dn *dn);
+
+int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn);
+int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1);
+
+bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base);
+bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...);
+bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child);
+bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...);
+bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num);
+bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num);
+
+struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn);
+struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn);
+int ldb_dn_get_comp_num(struct ldb_dn *dn);
+const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num);
+const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num);
+const char *ldb_dn_get_rdn_name(struct ldb_dn *dn);
+const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn);
 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val);
 
+bool ldb_dn_is_valid(struct ldb_dn *dn);
+bool ldb_dn_is_special(struct ldb_dn *dn);
+bool ldb_dn_check_special(struct ldb_dn *dn, const char *check);
+bool ldb_dn_is_null(struct ldb_dn *dn);
 
 
 /* useful functions for ldb_message structure manipulation */
@@ -1422,9 +1425,10 @@ const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg,
                                        const char *attr_name,
                                        const char *default_value);
 
-struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx,
+struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
+                                      void *mem_ctx,
                                       const struct ldb_message *msg,
-                                       const char *attr_name);
+                                      const char *attr_name);
 
 void ldb_msg_sort_elements(struct ldb_message *msg);
 
index f4049188ad3bbb5a9be8b201478a1023f7e8bb32..d597f30232c0e5471b89f4b191651b3b55e4dd4f 100644 (file)
@@ -180,7 +180,7 @@ int ldb_sqlite3_init(void);
 int ldb_match_msg(struct ldb_context *ldb,
                  const struct ldb_message *msg,
                  const struct ldb_parse_tree *tree,
-                 const struct ldb_dn *base,
+                 struct ldb_dn *base,
                  enum ldb_scope scope);
 
 void ldb_remove_attrib_handler(struct ldb_context *ldb, const char *attrib);
index 51ae031cf93f384f4be0e067bc6558d74a5a0504..a4abd4d1512d5d149b2b512838035f2957987687 100644 (file)
@@ -273,8 +273,8 @@ static void ildb_callback(struct ldap_request *req)
 
                                search = &(msg->r.SearchResultEntry);
                
-                               ares->message->dn = ldb_dn_explode_or_special(ares->message, search->dn);
-                               if (ares->message->dn == NULL) {
+                               ares->message->dn = ldb_dn_new(ares->message, ac->module->ldb, search->dn);
+                               if ( ! ldb_dn_validate(ares->message->dn)) {
                                        handle->status = LDB_ERR_OPERATIONS_ERROR;
                                        return;
                                }
index cdc1a500f80bb5f3c625a6ba81461d905ef56fa9..ee2d818935d3477838549afc46b2d68cc0772ad4 100644 (file)
@@ -527,8 +527,8 @@ static int lldb_parse_result(struct ldb_handle *handle, LDAPMessage *result)
                                ret = LDB_ERR_OPERATIONS_ERROR;
                                goto error;
                        }
-                       ares->message->dn = ldb_dn_explode_or_special(ares->message, dn);
-                       if (ares->message->dn == NULL) {
+                       ares->message->dn = ldb_dn_new(ares->message, ac->module->ldb, dn);
+                       if ( ! ldb_dn_validate(ares->message->dn)) {
                                ret = LDB_ERR_OPERATIONS_ERROR;
                                goto error;
                        }
index 4f9b0f6370f38cac96cee17e59abdf4cf8ae7cc0..7671b0d954f69bfb8d09e2c5408ddb25cb6a8612 100644 (file)
@@ -369,9 +369,8 @@ static char *parsetree_to_sql(struct ldb_module *module,
 
                } else if (strcasecmp(t->u.equality.attr, "dn") == 0) {
                        /* DN query is a special ldb case */
-                       char *cdn = ldb_dn_linearize_casefold(module->ldb,
-                                                             mem_ctx,
-                                                             ldb_dn_explode(module->ldb,
+                       char *cdn = ldb_dn_casefold(mem_ctx,
+                                                       ldb_dn_new(mem_ctx, module->ldb,
                                                              (const char *)value.data));
 
                        return lsqlite3_tprintf(mem_ctx,
@@ -754,7 +753,7 @@ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char
        msg = ac->ares->message;
 
        if (msg->dn == NULL) {
-               msg->dn = ldb_dn_explode(msg, cols[1]);
+               msg->dn = ldb_dn_new(msg, ac->module->ldb, cols[1]);
                if (msg->dn == NULL)
                        return SQLITE_ABORT;
        }
@@ -811,7 +810,7 @@ static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char
        return eid;
 }
 
-static long long lsqlite3_get_eid(struct ldb_module *module, const struct ldb_dn *dn)
+static long long lsqlite3_get_eid(struct ldb_module *module, struct ldb_dn *dn)
 {
        TALLOC_CTX *local_ctx;
        struct lsqlite3_private *lsqlite3 = module->private_data;
@@ -1044,7 +1043,7 @@ static int lsql_add(struct ldb_module *module, struct ldb_request *req)
        if (ldb_dn_is_special(msg->dn)) {
                struct ldb_dn *c;
 
-               c = ldb_dn_explode(lsql_ac, "@SUBCLASSES");
+               c = ldb_dn_new(lsql_ac, module->ldb, "@SUBCLASSES");
                if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
 #warning "insert subclasses into object class tree"
                        ret = LDB_ERR_UNWILLING_TO_PERFORM;
@@ -1052,7 +1051,7 @@ static int lsql_add(struct ldb_module *module, struct ldb_request *req)
                }
 
 /*
-               c = ldb_dn_explode(local_ctx, "@INDEXLIST");
+               c = ldb_dn_new(local_ctx, module->ldb, "@INDEXLIST");
                if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
 #warning "should we handle indexes somehow ?"
                        ret = LDB_ERR_UNWILLING_TO_PERFORM;
@@ -1182,7 +1181,7 @@ static int lsql_modify(struct ldb_module *module, struct ldb_request *req)
        if (ldb_dn_is_special(msg->dn)) {
                struct ldb_dn *c;
 
-               c = ldb_dn_explode(lsql_ac, "@SUBCLASSES");
+               c = ldb_dn_new(lsql_ac, module->ldb, "@SUBCLASSES");
                if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
 #warning "modify subclasses into object class tree"
                        ret = LDB_ERR_UNWILLING_TO_PERFORM;
index 467f1ac34df346f7aa0c3f30af62ee9eb177eec3..756c19810696d5b72ceb85348c086f27fc6e01db 100644 (file)
@@ -112,7 +112,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
        struct ldb_dn *dn;
        int i;
 
-       dn = ldb_dn_explode(module->ldb, LTDB_ATTRIBUTES);
+       dn = ldb_dn_new(module, module->ldb, LTDB_ATTRIBUTES);
        if (dn == NULL) goto failed;
 
        if (ltdb_search_dn1(module, dn, msg) == -1) {
@@ -180,7 +180,7 @@ static int ltdb_subclasses_load(struct ldb_module *module)
        struct ldb_dn *dn;
        int i, j;
 
-       dn = ldb_dn_explode(module->ldb, LTDB_SUBCLASSES);
+       dn = ldb_dn_new(module, module->ldb, LTDB_SUBCLASSES);
        if (dn == NULL) goto failed;
 
        if (ltdb_search_dn1(module, dn, msg) == -1) {
@@ -253,7 +253,7 @@ static int ltdb_baseinfo_init(struct ldb_module *module)
 
        msg->num_elements = 1;
        msg->elements = &el;
-       msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO);
+       msg->dn = ldb_dn_new(msg, module->ldb, LTDB_BASEINFO);
        if (!msg->dn) {
                goto failed;
        }
@@ -338,7 +338,7 @@ int ltdb_cache_load(struct ldb_module *module)
        baseinfo = talloc(ltdb->cache, struct ldb_message);
        if (baseinfo == NULL) goto failed;
 
-       baseinfo_dn = ldb_dn_explode(module->ldb, LTDB_BASEINFO);
+       baseinfo_dn = ldb_dn_new(module, module->ldb, LTDB_BASEINFO);
        if (baseinfo_dn == NULL) goto failed;
 
        if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) == -1) {
@@ -383,7 +383,7 @@ int ltdb_cache_load(struct ldb_module *module)
                goto failed;
        }
            
-       indexlist_dn = ldb_dn_explode(module->ldb, LTDB_INDEXLIST);
+       indexlist_dn = ldb_dn_new(module, module->ldb, LTDB_INDEXLIST);
        if (indexlist_dn == NULL) goto failed;
 
        if (ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist) == -1) {
@@ -439,7 +439,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
 
        msg->num_elements = ARRAY_SIZE(el);
        msg->elements = el;
-       msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO);
+       msg->dn = ldb_dn_new(msg, module->ldb, LTDB_BASEINFO);
        if (msg->dn == NULL) {
                talloc_free(msg);
                errno = ENOMEM;
index 0c9d1f33a1bfda545fdd1627b831c84eb7b10cb2..874d047186592133b2bca8d2efac7e794b2f6fee 100644 (file)
@@ -147,7 +147,7 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb,
        talloc_free(attr_folded);
 
 done:
-       ret = ldb_dn_explode(ldb, dn);
+       ret = ldb_dn_new(ldb, ldb, dn);
        talloc_free(dn);
        return ret;
 }
@@ -662,7 +662,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
                }
 
 
-               dn = ldb_dn_explode(ares->message, dn_list->dn[i]);
+               dn = ldb_dn_new(ares->message, ac->module->ldb, dn_list->dn[i]);
                if (dn == NULL) {
                        talloc_free(ares);
                        return LDB_ERR_OPERATIONS_ERROR;
index c6edf663ae18719aa43bdc7b807db949b099ff34..258c54356cdb63470a0d5ed3a32d6badfec4eb40 100644 (file)
@@ -196,7 +196,7 @@ int ltdb_unpack_data(struct ldb_module *module,
                        errno = EIO;
                        goto failed;
                }
-               message->dn = ldb_dn_explode(message, (char *)p);
+               message->dn = ldb_dn_new(message, ldb, (char *)p);
                if (message->dn == NULL) {
                        errno = ENOMEM;
                        goto failed;
index 884eccd36227eb23b51000b0db7cc9e9fb7eabaa..3f04994ce45ada1f72437cc6e0223fb69e332429 100644 (file)
@@ -209,7 +209,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
 
   return 1 on success, 0 on record-not-found and -1 on error
 */
-int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg)
+int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg)
 {
        struct ltdb_private *ltdb = module->private_data;
        int ret;
@@ -394,7 +394,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
        }
 
        if (!ares->message->dn) {
-               ares->message->dn = ldb_dn_explode(ares->message, (char *)key.dptr + 3);
+               ares->message->dn = ldb_dn_new(ares->message, ac->module->ldb, (char *)key.dptr + 3);
                if (ares->message->dn == NULL) {
                        handle->status = LDB_ERR_OPERATIONS_ERROR;
                        handle->state = LDB_ASYNC_DONE;
@@ -464,7 +464,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
        struct ldb_reply *ares;
        int ret;
 
-       if ((req->op.search.base == NULL || ldb_dn_get_comp_num(req->op.search.base) == 0) &&
+       if ((( ! ldb_dn_is_valid(req->op.search.base)) || ldb_dn_is_null(req->op.search.base)) &&
            (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL))
                return LDB_ERR_OPERATIONS_ERROR;
 
index 3f9db3909734d119ce9595f56cbc44c0d49a23a2..d950ab9cf02a2f4648582a1cbbe78373f5d868aa 100644 (file)
@@ -118,7 +118,7 @@ struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module
   note that the key for a record can depend on whether the 
   dn refers to a case sensitive index record or not
 */
-struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
+struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
 {
        struct ldb_context *ldb = module->ldb;
        TDB_DATA key;
@@ -137,15 +137,13 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
             the rest
        */
 
-       dn_folded = ldb_dn_linearize_casefold(ldb, ldb, dn);
+       dn_folded = ldb_dn_get_casefold(dn);
        if (!dn_folded) {
                goto failed;
        }
 
        key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
 
-       talloc_free(dn_folded);
-
        if (!key_str) {
                goto failed;
        }
@@ -194,7 +192,7 @@ int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *m
   we've made a modification to a dn - possibly reindex and 
   update sequence number
 */
-static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
+static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
 {
        int ret = 0;
 
@@ -330,7 +328,7 @@ done:
   delete a record from the database, not updating indexes (used for deleting
   index records)
 */
-int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
+int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
 {
        struct ltdb_private *ltdb =
                talloc_get_type(module->private_data, struct ltdb_private);
@@ -352,7 +350,7 @@ int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
        return ret;
 }
 
-static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn)
+static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
 {
        struct ldb_message *msg;
        int ret;
@@ -936,7 +934,7 @@ static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *r
 {
        TALLOC_CTX *tmp_ctx = talloc_new(req);
        struct ldb_message *msg = NULL;
-       struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO);
+       struct ldb_dn *dn = ldb_dn_new(tmp_ctx, module->ldb, LTDB_BASEINFO);
        int tret;
 
        if (tmp_ctx == NULL) {
index 42f3dc242122eb2309f9f4887e428c406e577271..6b556153add12698b6e915b9893cc22c8ec3685a 100644 (file)
@@ -46,7 +46,7 @@ struct ltdb_context {
 
        /* search stuff */
        const struct ldb_parse_tree *tree;
-       const struct ldb_dn *base;
+       struct ldb_dn *base;
        enum ldb_scope scope;
        const char * const *attrs;
 
@@ -101,7 +101,7 @@ int ltdb_unpack_data(struct ldb_module *module,
 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 struct ldb_dn *dn, struct ldb_message *msg);
+int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg);
 int ltdb_add_attr_results(struct ldb_module *module,
                          TALLOC_CTX *mem_ctx, 
                          struct ldb_message *msg,
@@ -114,9 +114,9 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req);
 /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c  */
 struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
                                    struct ldb_request *req);
-struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn);
+struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn);
 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);
-int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn);
+int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn);
 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg);
 
 int ltdb_index_del_value(struct ldb_module *module, const char *dn, 
index 2fed6aac50a8a79190cb4f662128d482ef46c40c..7d10a31b3426801dd33fc5beeb7d157490c03974 100644 (file)
@@ -313,8 +313,8 @@ static int asq_requests(struct ldb_handle *handle) {
                if (ac->reqs[i] == NULL)
                        return LDB_ERR_OPERATIONS_ERROR;
                ac->reqs[i]->operation = LDB_SEARCH;
-               ac->reqs[i]->op.search.base = ldb_dn_explode(ac->reqs[i], (const char *)el->values[i].data);
-               if (ac->reqs[i]->op.search.base == NULL) {
+               ac->reqs[i]->op.search.base = ldb_dn_new(ac->reqs[i], ac->module->ldb, (const char *)el->values[i].data);
+               if ( ! ldb_dn_validate(ac->reqs[i]->op.search.base)) {
                        ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX;
                        return asq_terminate(handle);
                }
index bbd7b9603dececbb7a37ae2d4888135066dcad7d..05a0459b4acc9df1a2bd404855a10b555f8f8e78 100644 (file)
@@ -182,15 +182,61 @@ BOOL map_check_local_db(struct ldb_module *module)
 }
 
 /* Copy a DN with the base DN of the local partition. */
-static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn)
+static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn)
 {
-       return ldb_dn_copy_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn);
+       struct ldb_dn *new_dn;
+
+       new_dn = ldb_dn_copy(mem_ctx, dn);
+       if ( ! ldb_dn_validate(new_dn)) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       /* may be we don't need to rebase at all */
+       if ( ! data->remote_base_dn || ! data->local_base_dn) {
+               return new_dn;
+       }
+
+       if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       return new_dn;
 }
 
 /* Copy a DN with the base DN of the remote partition. */
-static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn)
+static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn)
 {
-       return ldb_dn_copy_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn);
+       struct ldb_dn *new_dn;
+
+       new_dn = ldb_dn_copy(mem_ctx, dn);
+       if ( ! ldb_dn_validate(new_dn)) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       /* may be we don't need to rebase at all */
+       if ( ! data->remote_base_dn || ! data->local_base_dn) {
+               return new_dn;
+       }
+
+       if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) {
+               talloc_free(new_dn);
+               return NULL;
+       }
+
+       return new_dn;
 }
 
 /* Run a request and make sure it targets the remote partition. */
@@ -443,7 +489,7 @@ struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx,
  * =========== */
 
 /* Check whether a DN is below the local baseDN. */
-BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn)
+BOOL ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn)
 {
        const struct ldb_map_context *data = map_get_context(module);
 
@@ -451,11 +497,11 @@ BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn)
                return True;
        }
 
-       return ldb_dn_compare_base(module->ldb, data->local_base_dn, dn) == 0;
+       return ldb_dn_compare_base(data->local_base_dn, dn) == 0;
 }
 
 /* Map a DN into the remote partition. */
-struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn)
+struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn)
 {
        const struct ldb_map_context *data = map_get_context(module);
        struct ldb_dn *newdn;
@@ -527,7 +573,7 @@ failed:
 }
 
 /* Map a DN into the local partition. */
-struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn)
+struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn)
 {
        const struct ldb_map_context *data = map_get_context(module);
        struct ldb_dn *newdn;
@@ -600,7 +646,7 @@ failed:
 
 /* Map a DN and its base into the local partition. */
 /* TODO: This should not be required with GUIDs. */
-struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn)
+struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn)
 {
        const struct ldb_map_context *data = map_get_context(module);
        struct ldb_dn *dn1, *dn2;
@@ -622,7 +668,13 @@ static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_
        struct ldb_dn *dn, *newdn;
        struct ldb_val newval;
 
-       dn = ldb_dn_explode(mem_ctx, (char *)val->data);
+       dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data);
+       if (! ldb_dn_validate(dn)) {
+               newval.length = 0;
+               newval.data = NULL;
+               talloc_free(dn);
+               return newval;
+       }
        newdn = ldb_dn_map_local(module, mem_ctx, dn);
        talloc_free(dn);
 
@@ -642,7 +694,13 @@ static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem
        struct ldb_dn *dn, *newdn;
        struct ldb_val newval;
 
-       dn = ldb_dn_explode(mem_ctx, (char *)val->data);
+       dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data);
+       if (! ldb_dn_validate(dn)) {
+               newval.length = 0;
+               newval.data = NULL;
+               talloc_free(dn);
+               return newval;
+       }
        newdn = ldb_dn_map_remote(module, mem_ctx, dn);
        talloc_free(dn);
 
@@ -856,7 +914,7 @@ static int map_search_self_callback(struct ldb_context *ldb, void *context, stru
 }
 
 /* Build a request to search a record by its DN. */
-struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback)
+struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback)
 {
        struct ldb_request *req;
 
@@ -890,7 +948,7 @@ struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb
 }
 
 /* Build a request to search the local record by its DN. */
-struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb_dn *dn)
+struct ldb_request *map_search_self_req(struct map_context *ac, struct ldb_dn *dn)
 {
        /* attrs[] is returned from this function in
         * ac->search_req->op.search.attrs, so it must be static, as
@@ -913,7 +971,7 @@ struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb
 }
 
 /* Build a request to update the 'IS_MAPPED' attribute */
-struct ldb_request *map_build_fixup_req(struct map_context *ac, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
+struct ldb_request *map_build_fixup_req(struct map_context *ac, struct ldb_dn *olddn, struct ldb_dn *newdn)
 {
        struct ldb_request *req;
        struct ldb_message *msg;
@@ -1193,8 +1251,8 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
                return LDB_SUCCESS;
        }
 
-       dn = ldb_dn_string_compose(data, NULL, "%s=%s", MAP_DN_NAME, name);
-       if (dn == NULL) {
+       dn = ldb_dn_new_fmt(data, module->ldb, "%s=%s", MAP_DN_NAME, name);
+       if ( ! ldb_dn_validate(dn)) {
                ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
                          "Failed to construct '%s' DN!\n", MAP_DN_NAME);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -1219,8 +1277,8 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
        }
 
        msg = res->msgs[0];
-       data->local_base_dn = ldb_msg_find_attr_as_dn(data, msg, MAP_DN_FROM);
-       data->remote_base_dn = ldb_msg_find_attr_as_dn(data, msg, MAP_DN_TO);
+       data->local_base_dn = ldb_msg_find_attr_as_dn(module->ldb, data, msg, MAP_DN_FROM);
+       data->remote_base_dn = ldb_msg_find_attr_as_dn(module->ldb, data, msg, MAP_DN_TO);
        talloc_free(res);
 
        return LDB_SUCCESS;
index c5c455bcb259a77d7e2888bd7bc2e4083bf0d949..e8de2e3698df5bd2024046dad859d57658014ce4 100644 (file)
@@ -135,8 +135,8 @@ struct ldb_map_context {
        const char * const *wildcard_attributes;
 
        /* struct ldb_context *mapped_ldb; */
-       const struct ldb_dn *local_base_dn;
-       const struct ldb_dn *remote_base_dn;
+       struct ldb_dn *local_base_dn;
+       struct ldb_dn *remote_base_dn;
 };
 
 /* Global private data */
index 8a08d0a5b6ff64d00be3db138ea91c1c7500b988..1f4fecee8b300ecf9c3ab4a54d7beb4ed6c68b4d 100644 (file)
@@ -33,7 +33,7 @@ struct map_context {
 
        struct ldb_module *module;
 
-       const struct ldb_dn *local_dn;
+       struct ldb_dn *local_dn;
        const struct ldb_parse_tree *local_tree;
        const char * const *local_attrs;
        const char * const *remote_attrs;
@@ -70,7 +70,7 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque
 
 BOOL map_check_local_db(struct ldb_module *module);
 BOOL map_attr_check_remote(const struct ldb_map_context *data, const char *attr);
-BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn);
+BOOL ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn);
 
 const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name);
 const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name);
@@ -82,13 +82,13 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attr
 struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val);
 struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val);
 
-struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn);
-struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn);
-struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn);
+struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn);
+struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn);
+struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn);
 
-struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback);
-struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb_dn *dn);
-struct ldb_request *map_build_fixup_req(struct map_context *ac, const struct ldb_dn *olddn, const struct ldb_dn *newdn);
+struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback);
+struct ldb_request *map_search_self_req(struct map_context *ac, struct ldb_dn *dn);
+struct ldb_request *map_build_fixup_req(struct map_context *ac, struct ldb_dn *olddn, struct ldb_dn *newdn);
 
 int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map);
 
index c7d163307decf0ca7fa9b7393693e0c653f902b9..02d85e4c23066190ebd339ffe7abebf05c8a7f38 100644 (file)
@@ -424,7 +424,7 @@ static int ps_init(struct ldb_module *module)
        }
 
        req->operation = LDB_SEARCH;
-       req->op.search.base = ldb_dn_new(req);
+       req->op.search.base = ldb_dn_new(req, module->ldb, NULL);
        req->op.search.scope = LDB_SCOPE_BASE;
 
        req->op.search.tree = ldb_parse_tree(req, "objectClass=*");
index 614f6e170fe1a01f14c19139fa136acaa23cecb2..4577cea524135f881ea62a09f8124404120ac452 100644 (file)
@@ -62,8 +62,8 @@ NSS_STATUS _ldb_nss_init(void)
                goto failed;
        }
 
-       _ldb_nss_ctx->base = ldb_dn_explode(_ldb_nss_ctx, _LDB_NSS_BASEDN);
-       if (_ldb_nss_ctx->base == NULL) {
+       _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN);
+       if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) {
                goto failed;
        }
 
index c780a21e8119ee80b22c19787c168cffc01bf029..1ed68033e09ec376fe809c5aa2e7052ddcd3b050 100644 (file)
@@ -46,7 +46,7 @@ struct _ldb_nss_context {
        pid_t pid;
 
        struct ldb_context *ldb;
-       const struct ldb_dn *base;
+       struct ldb_dn *base;
 
        int pw_cur;
        struct ldb_result *pw_res;
index 8abfb872382d4ff94987b861b4436e955e17d9e9..d017306176bc0b6a8c82259c1601380c2df8ec1d 100644 (file)
@@ -300,8 +300,8 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c
        struct ldb_dn *dn1 = NULL;
        char *oc1, *oc2;
 
-       dn1 = ldb_dn_explode(mem_ctx, (char *)in->data);
-       if (dn1 == NULL) {
+       dn1 = ldb_dn_new(mem_ctx, ldb, (char *)in->data);
+       if ( ! ldb_dn_validate(dn1)) {
                oc1 = talloc_strndup(mem_ctx, (char *)in->data, in->length);
        } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
                const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
@@ -325,8 +325,8 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx
        struct ldb_dn *dn1 = NULL, *dn2 = NULL;
        const char *oc1, *oc2;
 
-       dn1 = ldb_dn_explode(mem_ctx, (char *)v1->data);
-       if (dn1 == NULL) {
+       dn1 = ldb_dn_new(mem_ctx, ldb, (char *)v1->data);
+       if ( ! ldb_dn_validate(dn1)) {
                oc1 = talloc_strndup(mem_ctx, (char *)v1->data, v1->length);
        } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
                const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
@@ -335,8 +335,8 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx
                oc1 = NULL;
        }
 
-       dn2 = ldb_dn_explode(mem_ctx, (char *)v2->data);
-       if (dn2 == NULL) {
+       dn2 = ldb_dn_new(mem_ctx, ldb, (char *)v2->data);
+       if ( ! ldb_dn_validate(dn2)) {
                oc2 = talloc_strndup(mem_ctx, (char *)v2->data, v2->length);
        } else if (ldb_dn_get_comp_num(dn2) >= 2 && strcasecmp(ldb_dn_get_rdn_name(dn2), "cn") == 0) {
                const struct ldb_val *val = ldb_dn_get_rdn_val(dn2);
index b9d224e0af0babbff5b3065988931268c952d52f..14cfb5f97935aff0a5e7fc33fff799f9ab52d574 100755 (executable)
@@ -49,6 +49,6 @@ else
     ret=$?
 fi
 
-$LDBDIR/tests/kill_slapd.sh
+#$LDBDIR/tests/kill_slapd.sh
 
 exit $ret
index 62c6e01c2e277e5cf1824bf320473fbae02e36e0..49c4fa1fd6713008f786440978b0889e34ad5f16 100644 (file)
@@ -200,7 +200,7 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
 {
        const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
        struct ldb_dn *schemadn;
-       struct ldb_dn *basedn = ldb_dn_explode(mem_ctx, "");
+       struct ldb_dn *basedn = ldb_dn_new(mem_ctx, ldb, NULL);
        struct ldb_result *rootdse_res;
        int ldb_ret;
        if (!basedn) {
@@ -222,7 +222,7 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
        }
        
        /* Locate schema */
-       schemadn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
+       schemadn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
        if (!schemadn) {
                return NULL;
        }
index 94f1da9903743f37a45e05db86a2242dc391a14a..b4da806b51198337aa9b9da319a43ef36e19228c 100644 (file)
@@ -36,7 +36,7 @@
 #include "ldb/include/includes.h"
 #include "ldb/tools/cmdline.h"
 
-static int ldb_delete_recursive(struct ldb_context *ldb, const struct ldb_dn *dn)
+static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn)
 {
        int ret, i, total=0;
        const char *attrs[] = { NULL };
@@ -91,10 +91,10 @@ int main(int argc, const char **argv)
        }
 
        for (i=0;i<options->argc;i++) {
-               const struct ldb_dn *dn;
+               struct ldb_dn *dn;
 
-               dn = ldb_dn_explode(ldb, options->argv[i]);
-               if (dn == NULL) {
+               dn = ldb_dn_new(ldb, ldb, options->argv[i]);
+               if ( ! ldb_dn_validate(dn)) {
                        printf("Invalid DN format\n");
                        exit(1);
                }
index 17ade152b780fed372235570321846aad3efd2a5..429febb75b04775fe90fda7337afbe4852440fcd 100644 (file)
@@ -91,11 +91,11 @@ static int modify_record(struct ldb_context *ldb,
 static struct ldb_message *msg_find(struct ldb_context *ldb,
                                    struct ldb_message **msgs,
                                    int count,
-                                   const struct ldb_dn *dn)
+                                   struct ldb_dn *dn)
 {
        int i;
        for (i=0;i<count;i++) {
-               if (ldb_dn_compare(ldb, dn, msgs[i]->dn) == 0) {
+               if (ldb_dn_compare(dn, msgs[i]->dn) == 0) {
                        return msgs[i];
                }
        }
@@ -300,8 +300,8 @@ int main(int argc, const char **argv)
        }
 
        if (options->basedn != NULL) {
-               basedn = ldb_dn_explode(ldb, options->basedn);
-               if (basedn == NULL) {
+               basedn = ldb_dn_new(ldb, ldb, options->basedn);
+               if ( ! ldb_dn_validate(basedn)) {
                        printf("Invalid Base DN format\n");
                        exit(1);
                }
index 9c0870721d487fb6e85aece70c58ba5ab1e8385c..d7e1347fea7d5b0b8d48e0564908af31b60bfb71 100644 (file)
@@ -56,7 +56,7 @@ int main(int argc, const char **argv)
        struct ldb_context *ldb;
        int ret;
        struct ldb_cmdline *options;
-       const struct ldb_dn *dn1, *dn2;
+       struct ldb_dn *dn1, *dn2;
 
        ldb_global_init();
 
@@ -68,8 +68,17 @@ int main(int argc, const char **argv)
                usage();
        }
 
-       dn1 = ldb_dn_explode(ldb, options->argv[0]);
-       dn2 = ldb_dn_explode(ldb, options->argv[1]);
+       dn1 = ldb_dn_new(ldb, ldb, options->argv[0]);
+       dn2 = ldb_dn_new(ldb, ldb, options->argv[1]);
+
+       if ( ! ldb_dn_validate(dn1)) {
+               printf("Invalid DN1: %s\n", options->argv[0]);
+               return -1;
+       }
+       if ( ! ldb_dn_validate(dn2)) {
+               printf("Invalid DN2: %s\n", options->argv[1]);
+               return -1;
+       }
 
        ret = ldb_rename(ldb, dn1, dn2);
        if (ret == 0) {
index 837dfc9088ce4de7f0d823cf19c34b875893c03c..7bf9d64fc21705e67b732a1220f8c4206fae3a23 100644 (file)
@@ -54,8 +54,7 @@ static int do_compare_msg(struct ldb_message **el1,
                          struct ldb_message **el2,
                          void *opaque)
 {
-       struct ldb_context *ldb = talloc_get_type(opaque, struct ldb_context);
-       return ldb_dn_compare(ldb, (*el1)->dn, (*el2)->dn);
+       return ldb_dn_compare((*el1)->dn, (*el2)->dn);
 }
 
 struct search_context {
@@ -185,7 +184,7 @@ static int search_callback(struct ldb_context *ldb, void *context, struct ldb_re
 }
 
 static int do_search(struct ldb_context *ldb,
-                    const struct ldb_dn *basedn,
+                    struct ldb_dn *basedn,
                     struct ldb_cmdline *options,
                     const char *expression,
                     const char * const *attrs)
@@ -298,8 +297,8 @@ int main(int argc, const char **argv)
        }
 
        if (options->basedn != NULL) {
-               basedn = ldb_dn_explode(ldb, options->basedn);
-               if (basedn == NULL) {
+               basedn = ldb_dn_new(ldb, ldb, options->basedn);
+               if ( ! ldb_dn_validate(basedn)) {
                        fprintf(stderr, "Invalid Base DN format\n");
                        exit(1);
                }
index 6cc8dfe19b2c57dc091c825680e1de8912aaa2e8..70b2b0148a574e957851b2949ab5ed00e496f424 100644 (file)
@@ -52,7 +52,7 @@ static double _end_timer(void)
 }
 
 static void add_records(struct ldb_context *ldb,
-                       const struct ldb_dn *basedn,
+                       struct ldb_dn *basedn,
                        int count)
 {
        struct ldb_message msg;
@@ -72,7 +72,8 @@ static void add_records(struct ldb_context *ldb,
 
                name = talloc_asprintf(tmp_ctx, "Test%d", i);
 
-               msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn);
+               msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+               ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
                msg.num_elements = 6;
                msg.elements = el;
 
@@ -140,7 +141,7 @@ static void add_records(struct ldb_context *ldb,
 }
 
 static void modify_records(struct ldb_context *ldb,
-                          const struct ldb_dn *basedn,
+                          struct ldb_dn *basedn,
                           int count)
 {
        struct ldb_message msg;
@@ -153,7 +154,8 @@ static void modify_records(struct ldb_context *ldb,
                TALLOC_CTX *tmp_ctx = talloc_new(ldb);
                
                name = talloc_asprintf(tmp_ctx, "Test%d", i);
-               msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn);
+               msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+               ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
 
                msg.num_elements = 3;
                msg.elements = el;
@@ -192,7 +194,7 @@ static void modify_records(struct ldb_context *ldb,
 
 
 static void delete_records(struct ldb_context *ldb,
-                          const struct ldb_dn *basedn,
+                          struct ldb_dn *basedn,
                           int count)
 {
        int i;
@@ -200,13 +202,14 @@ static void delete_records(struct ldb_context *ldb,
        for (i=0;i<count;i++) {
                struct ldb_dn *dn;
                char *name = talloc_asprintf(ldb, "Test%d", i);
-               dn = ldb_dn_build_child(name, "cn", name, basedn);
+               dn = ldb_dn_copy(name, basedn);
+               ldb_dn_add_child_fmt(dn, "cn=%s", name);
 
                printf("Deleting uid Test%d\r", i);
                fflush(stdout);
 
                if (ldb_delete(ldb, dn) != 0) {
-                       printf("Delete of %s failed - %s\n", ldb_dn_linearize(ldb, dn), ldb_errstring(ldb));
+                       printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
                        exit(1);
                }
                talloc_free(name);
@@ -252,7 +255,11 @@ static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
 {
        struct ldb_dn *basedn;
 
-       basedn = ldb_dn_explode(ldb, options->basedn);
+       basedn = ldb_dn_new(ldb, ldb, options->basedn);
+       if ( ! ldb_dn_validate(basedn)) {
+               printf("Invalid base DN\n");
+               exit(1);
+       }
 
        printf("Adding %d records\n", nrecords);
        add_records(ldb, basedn, nrecords);
@@ -305,7 +312,7 @@ static void start_test_index(struct ldb_context **ldb)
 
        printf("Starting index test\n");
 
-       indexlist = ldb_dn_explode(NULL, "@INDEXLIST");
+       indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
 
        ldb_delete(*ldb, indexlist);
 
@@ -319,10 +326,11 @@ static void start_test_index(struct ldb_context **ldb)
                exit(1);
        }
 
-       basedn = ldb_dn_explode(NULL, options->basedn);
+       basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
 
        memset(msg, 0, sizeof(*msg));
-       msg->dn = ldb_dn_build_child(msg, "cn", "test", basedn);
+       msg->dn = ldb_dn_copy(msg, basedn);
+       ldb_dn_add_child_fmt(msg->dn, "cn=test");
        ldb_msg_add_string(msg, "cn", strdup("test"));
        ldb_msg_add_string(msg, "sn", strdup("test"));
        ldb_msg_add_string(msg, "uid", strdup("test"));
@@ -339,13 +347,15 @@ static void start_test_index(struct ldb_context **ldb)
        }
 
        (*ldb) = ldb_init(options);
-       
+
        ret = ldb_connect(*ldb, options->url, flags, NULL);
        if (ret != 0) {
                printf("failed to connect to %s\n", options->url);
                exit(1);
        }
 
+       basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
+
        ret = ldb_search(*ldb, basedn, LDB_SCOPE_SUBTREE, "uid=test", NULL, &res);
        if (ret != LDB_SUCCESS) { 
                printf("Search with (uid=test) filter failed!\n");
@@ -356,6 +366,8 @@ static void start_test_index(struct ldb_context **ldb)
                exit(1);
        }
 
+       indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
+
        if (ldb_delete(*ldb, msg->dn) != 0 ||
            ldb_delete(*ldb, indexlist) != 0) {
                printf("cleanup failed - %s\n", ldb_errstring(*ldb));
index a9e157e32331c28a4d1c7032ccaa7cbee0ab403a..7863f5dcb77982c9a7db6b23b5b16bc6ec86d35d 100644 (file)
@@ -388,9 +388,8 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry)
                        MSG_ADD_STRING("cn", token->value);
                        MSG_ADD_STRING("name", token->value);
                        MSG_ADD_STRING("lDAPDisplayName", token->value);
-                       msg->dn = ldb_dn_string_compose(msg, basedn,
-                                                       "CN=%s,CN=Schema,CN=Configuration",
-                                                       token->value);
+                       msg->dn = ldb_dn_copy(msg, basedn);
+                       ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Schema,CN=Configuration", token->value);
                        break;
 
                case SCHEMA_SUP:
@@ -575,8 +574,8 @@ static void usage(void)
                perror("Base DN not specified");
                exit(1);
        } else {
-               basedn = ldb_dn_explode(ctx, options->basedn);
-               if (basedn == NULL) {
+               basedn = ldb_dn_new(ctx, ldb_ctx, options->basedn);
+               if ( ! ldb_dn_validate(basedn)) {
                        perror("Malformed Base DN");
                        exit(1);
                }
index b9bfe8a230641b569d38a2b53b5af208295189be..5f9481fa67e2e86a55683a085fe7880bc113741a 100644 (file)
@@ -27,7 +27,7 @@
 
 struct ldb_key_data 
 {
-       const struct ldb_dn *dn;
+       struct ldb_dn *dn;
        struct ldb_message **subkeys, **values;
        int subkey_count, value_count;
 };
@@ -115,15 +115,24 @@ static int reg_close_ldb_key(struct registry_key *key)
 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry_key *from, const char *path, const char *add)
 {
        TALLOC_CTX *local_ctx;
-       struct ldb_dn *ret = ldb_dn_new(mem_ctx);
+       struct ldb_dn *ret;
        char *mypath = talloc_strdup(mem_ctx, path);
        char *begin;
        struct ldb_key_data *kd = talloc_get_type(from->backend_data, struct ldb_key_data);
+       struct ldb_context *ldb = talloc_get_type(from->hive->backend_data, struct ldb_context);
 
        local_ctx = talloc_new(mem_ctx);
 
-       if (add) 
-               ret = ldb_dn_compose(local_ctx, ret, ldb_dn_explode(mem_ctx, add));
+       if (add) {
+               ret = ldb_dn_new(mem_ctx, ldb, add);
+       } else {
+               ret = ldb_dn_new(mem_ctx, ldb, NULL);
+       }
+       if ( ! ldb_dn_validate(ret)) {
+               talloc_free(ret);
+               talloc_free(local_ctx);
+               return NULL;
+       }
 
        while(mypath) {
                char *keyname;
@@ -134,10 +143,7 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry
                else keyname = mypath;
 
                if(strlen(keyname)) {
-                       struct ldb_dn *base;
-
-                       base = ldb_dn_build_child(local_ctx, "key", keyname, NULL);
-                       ret = ldb_dn_compose(local_ctx, ret, base);
+                       ldb_dn_add_base_fmt(ret, "key=%s", keyname);
                }
 
                if(begin) {
@@ -147,7 +153,7 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry
                }
        }
 
-       ret = ldb_dn_compose(mem_ctx, ret, kd->dn);
+       ldb_dn_add_base(ret, kd->dn);
 
        talloc_free(local_ctx);
 
@@ -277,7 +283,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k)
        talloc_set_destructor (hive, ldb_free_hive);
        (*k)->name = talloc_strdup(*k, "");
        (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data);
-       kd->dn = ldb_dn_explode(*k, "hive=NONE");
+       kd->dn = ldb_dn_new(*k, wrap, "hive=NONE");
        
 
        return WERR_OK;
@@ -316,7 +322,10 @@ static WERROR ldb_del_key (const struct registry_key *key, const char *child)
        struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context);
        int ret;
        struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data);
-       struct ldb_dn *childdn = ldb_dn_build_child(ctx, "key", child, kd->dn);
+       struct ldb_dn *childdn;
+
+       childdn = ldb_dn_copy(ctx, kd->dn);
+       ldb_dn_add_child_fmt(childdn, "key=%s", child);
 
        ret = ldb_delete(ctx, childdn);
 
@@ -335,7 +344,10 @@ static WERROR ldb_del_value (const struct registry_key *key, const char *child)
        int ret;
        struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context);
        struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data);
-       struct ldb_dn *childdn = ldb_dn_build_child(ctx, "value", child, kd->dn);
+       struct ldb_dn *childdn;
+
+       childdn = ldb_dn_copy(ctx, kd->dn);
+       ldb_dn_add_child_fmt(childdn, "value=%s", child);
 
        ret = ldb_delete(ctx, childdn);
 
@@ -359,7 +371,8 @@ static WERROR ldb_set_value (const struct registry_key *parent, const char *name
 
        msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data);
 
-       msg->dn = ldb_dn_build_child(msg, "value", name, kd->dn);
+       msg->dn = ldb_dn_copy(msg, kd->dn);
+       ldb_dn_add_child_fmt(msg->dn, "value=%s", name);
 
        ret = ldb_add(ctx, msg);
        if (ret < 0) {
index 01872eb7fce44df5dc1bb118f1ddffc5e69d3717..e68b0d623524a8fa9caee8a63b7c6b274ff12286 100644 (file)
@@ -62,7 +62,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        struct GUID drsuapi_bind_guid;
 
        struct ldb_context *remote_ldb;
-       const struct ldb_dn *account_dn;
+       struct ldb_dn *account_dn;
        const char *account_dn_str;
        const char *remote_ldb_url;
        struct ldb_result *res;
@@ -219,8 +219,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        /* Store the DN of our machine account. */
        account_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name;
 
-       account_dn = ldb_dn_explode(tmp_ctx, account_dn_str);
-       if (!account_dn) {
+       account_dn = ldb_dn_new(tmp_ctx, remote_ldb, account_dn_str);
+       if (! ldb_dn_validate(account_dn)) {
                r->out.error_string = talloc_asprintf(r, "Invalid account dn: %s",
                                                      account_dn_str);
                talloc_free(tmp_ctx);
@@ -855,7 +855,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
        struct libnet_JoinDomain *r2;
        int ret, rtn;
        struct ldb_context *ldb;
-       const struct ldb_dn *base_dn;
+       struct ldb_dn *base_dn;
        struct ldb_message **msgs, *msg;
        const char *sct;
        const char * const attrs[] = {
@@ -961,15 +961,15 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       base_dn = ldb_dn_explode(tmp_mem, "cn=Primary Domains");
+       base_dn = ldb_dn_new(tmp_mem, ldb, "cn=Primary Domains");
        if (!base_dn) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
                return NT_STATUS_NO_MEMORY;
        }
 
-       msg->dn = ldb_dn_build_child(tmp_mem, "flatname", r2->out.domain_name, base_dn);
-       if (!msg->dn) {
+       msg->dn = ldb_dn_copy(tmp_mem, base_dn);
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r2->out.domain_name)) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
                return NT_STATUS_NO_MEMORY;
index a57e2735e7118e0fd2fb8599f84f785627461b3e..3c34aca94428b67d00cc5312788b8331be6c0fb8 100644 (file)
@@ -89,9 +89,9 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
        }
 
        /* add core elements to the ldb_message for the alias */
-       msg->dn = ldb_dn_build_child(mem_ctx, "CN", sidstr, basedn);
-       if (msg->dn == NULL)
-               return NT_STATUS_NO_MEMORY;
+       msg->dn = basedn;
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
+               return NT_STATUS_UNSUCCESSFUL;
        
        samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
                             "objectClass",
@@ -128,7 +128,7 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
        }
 
        if (database == SAM_DATABASE_DOMAIN) {
-               const struct ldb_dn *partitions_basedn;
+               struct ldb_dn *partitions_basedn;
                const char *domain_attrs[] =  {"nETBIOSName", "nCName", NULL};
                struct ldb_message **msgs_domain;
                int ret_domain;
@@ -149,7 +149,7 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_SUCH_DOMAIN;                
                }
 
-               state->base_dn[database] = samdb_result_dn(state, msgs_domain[0], "nCName", NULL);
+               state->base_dn[database] = samdb_result_dn(state->sam_ldb, state, msgs_domain[0], "nCName", NULL);
 
                if (state->dom_sid[database]) {
                        /* Update the domain sid with the incoming
@@ -181,7 +181,10 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
                   fetching here */
                const char *dnstring = samdb_search_string(state->sam_ldb, mem_ctx, NULL,
                                                           "distinguishedName", "objectClass=builtinDomain");
-               state->base_dn[database] = ldb_dn_explode(state, dnstring);
+               state->base_dn[database] = ldb_dn_new(state, state->sam_ldb, dnstring);
+               if ( ! ldb_dn_validate(state->base_dn[database])) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
        } else {
                /* PRIVs DB */
                return NT_STATUS_INVALID_PARAMETER;
@@ -418,8 +421,8 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
                if (!msg->dn) {
-                       msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                                       "CN=%s, CN=%s", cn_name, container);
+                       msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+                       ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
                        if (!msg->dn) {
                                return NT_STATUS_NO_MEMORY;             
                        }
@@ -565,8 +568,8 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
        if (add) {
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
-               msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                               "CN=%s, CN=%s", cn_name, container);
+               msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+               ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
                if (!msg->dn) {
                        return NT_STATUS_NO_MEMORY;             
                }
@@ -779,8 +782,8 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
        if (add) {
                samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, 
                                     "objectClass", obj_class);
-               msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
-                                               "CN=%s, CN=%s", cn_name, container);
+               msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+               ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
                if (!msg->dn) {
                        return NT_STATUS_NO_MEMORY;             
                }
index ec4bb1329003eb6057d76c00bbc486d707f5f876..0c42bf1c73fdeda96b7691d7dd7f7b59d9a09230 100644 (file)
@@ -186,8 +186,8 @@ NTSTATUS libnet_JoinSite(struct ldb_context *remote_ldb,
                return NT_STATUS_NO_MEMORY;
        }
 
-       server_dn = ldb_dn_explode(tmp_ctx, server_dn_str);
-       if (server_dn == NULL) {
+       server_dn = ldb_dn_new(tmp_ctx, remote_ldb, server_dn_str);
+       if ( ! ldb_dn_validate(server_dn)) {
                libnet_r->out.error_string = talloc_asprintf(libnet_r,
                                        "Invalid server dn: %s",
                                        server_dn_str);
index 3b67a7f5c91101168223b0a9a588a6c791ea1057..3984d1f933c22251b303bc56bed7eddcc49a0d81 100644 (file)
@@ -45,7 +45,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        const char *ref_attrs[] = {"nETBIOSName", NULL};
        struct ldb_message **ref_res;
        struct ldb_context *samctx;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
        int ret;
 
        /* only answer getdc requests on the PDC or LOGON names */
@@ -112,7 +112,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
        int ret;
        const char **services = lp_server_services();
        const char *my_ip = reply_iface->ip_address; 
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
        if (!my_ip) {
                DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
                return;
@@ -142,7 +142,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
 
        /* try and find the domain */
        ret = gendb_search_dn(samctx, samctx, 
-                             samdb_result_dn(samctx, ref_res[0], "ncName", NULL), 
+                             samdb_result_dn(samctx, samctx, ref_res[0], "ncName", NULL), 
                              &dom_res, dom_attrs);
        if (ret != 1) {
                DEBUG(2,("Unable to find domain from reference '%s' in sam\n",
index bc518233abb60f67327a36b97eaf3600bc77b0a5..7b0a0756c6908589e99efc8ec5e60d4fc561cc93 100644 (file)
@@ -41,7 +41,7 @@ uint64_t winsdb_get_maxVersion(struct winsdb_handle *h)
        TALLOC_CTX *tmp_ctx = talloc_new(ldb);
        uint64_t maxVersion = 0;
 
-       dn = ldb_dn_explode(tmp_ctx, "CN=VERSION");
+       dn = ldb_dn_new(tmp_ctx, ldb, "CN=VERSION");
        if (!dn) goto failed;
 
        /* find the record in the WINS database */
@@ -78,7 +78,7 @@ uint64_t winsdb_set_maxVersion(struct winsdb_handle *h, uint64_t newMaxVersion)
        trans = ldb_transaction_start(wins_db);
        if (trans != LDB_SUCCESS) goto failed;
 
-       dn = ldb_dn_explode(tmp_ctx, "CN=VERSION");
+       dn = ldb_dn_new(tmp_ctx, wins_db, "CN=VERSION");
        if (!dn) goto failed;
 
        /* find the record in the WINS database */
@@ -139,7 +139,7 @@ uint64_t winsdb_get_seqnumber(struct winsdb_handle *h)
        TALLOC_CTX *tmp_ctx = talloc_new(ldb);
        uint64_t seqnumber = 0;
 
-       dn = ldb_dn_explode(tmp_ctx, "@BASEINFO");
+       dn = ldb_dn_new(tmp_ctx, ldb, "@BASEINFO");
        if (!dn) goto failed;
 
        /* find the record in the WINS database */
@@ -161,16 +161,16 @@ failed:
 /*
   return a DN for a nbt_name
 */
-static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct nbt_name *name)
+static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct nbt_name *name)
 {
        struct ldb_dn *dn;
 
-       dn = ldb_dn_string_compose(mem_ctx, NULL, "type=0x%02X", name->type);
-       if (dn && name->name && *name->name) {
-               dn = ldb_dn_string_compose(mem_ctx, dn, "name=%s", name->name);
+       dn = ldb_dn_new_fmt(mem_ctx, ldb, "type=0x%02X", name->type);
+       if (ldb_dn_is_valid(dn) && name->name && *name->name) {
+               ldb_dn_add_child_fmt(dn, "name=%s", name->name);
        }
-       if (dn && name->scope && *name->scope) {
-               dn = ldb_dn_string_compose(mem_ctx, dn, "scope=%s", name->scope);
+       if (ldb_dn_is_valid(dn) && name->scope && *name->scope) {
+               ldb_dn_add_child_fmt(dn, "scope=%s", name->scope);
        }
        return dn;
 }
@@ -589,7 +589,7 @@ NTSTATUS winsdb_lookup(struct winsdb_handle *h,
        time_t now = time(NULL);
 
        /* find the record in the WINS database */
-       ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, name), LDB_SCOPE_BASE, 
+       ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, wins_db, name), LDB_SCOPE_BASE, 
                         NULL, NULL, &res);
 
        talloc_steal(tmp_ctx, res);
@@ -783,7 +783,7 @@ struct ldb_message *winsdb_message(struct ldb_context *ldb,
                goto failed;
        }
 
-       msg->dn = winsdb_dn(msg, rec->name);
+       msg->dn = winsdb_dn(msg, ldb, rec->name);
        if (msg->dn == NULL) goto failed;
        ret |= ldb_msg_add_fmt(msg, "type", "0x%02X", rec->name->type);
        if (rec->name->name && *rec->name->name) {
@@ -918,14 +918,14 @@ uint8_t winsdb_delete(struct winsdb_handle *h, struct winsdb_record *rec)
 {
        struct ldb_context *wins_db = h->ldb;
        TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
-       const struct ldb_dn *dn;
+       struct ldb_dn *dn;
        int trans;
        int ret;
 
        trans = ldb_transaction_start(wins_db);
        if (trans != LDB_SUCCESS) goto failed;
 
-       dn = winsdb_dn(tmp_ctx, rec->name);
+       dn = winsdb_dn(tmp_ctx, wins_db, rec->name);
        if (dn == NULL) goto failed;
 
        ret = ldb_delete(wins_db, dn);
@@ -959,7 +959,7 @@ static BOOL winsdb_check_or_add_module_list(struct winsdb_handle *h)
        if (trans != LDB_SUCCESS) goto failed;
 
        /* check if we have a special @MODULES record already */
-       dn = ldb_dn_explode(tmp_ctx, "@MODULES");
+       dn = ldb_dn_new(tmp_ctx, h->ldb, "@MODULES");
        if (!dn) goto failed;
 
        /* find the record in the WINS database */
index 136dae352aa86c0e85f4644781467b3f344aa6d9..d504a53a836d1ee2b2b7a6d6ce0e351013992cfa 100644 (file)
@@ -49,14 +49,14 @@ static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx)
 
 static int sptr_db_search(struct ldb_context *ldb,
                          TALLOC_CTX *mem_ctx,
-                         const struct ldb_dn *basedn,
+                         struct ldb_dn *basedn,
                          struct ldb_message ***res,
                          const char * const *attrs,
                          const char *format, ...) PRINTF_ATTRIBUTE(6,7);
 
 static int sptr_db_search(struct ldb_context *ldb,
                          TALLOC_CTX *mem_ctx,
-                         const struct ldb_dn *basedn,
+                         struct ldb_dn *basedn,
                          struct ldb_message ***res,
                          const char * const *attrs,
                          const char *format, ...)
@@ -227,7 +227,7 @@ static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALL
        union spoolss_FormInfo *info;
 
        count = sptr_db_search(sptr_db, mem_ctx,
-                               ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+                               ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
                                &msgs, NULL, "(&(objectClass=form))");
 
        if (count == 0) return WERR_OK;
@@ -282,7 +282,7 @@ static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC
                        return WERR_FOOBAR;
                }
                count = sptr_db_search(sptr_db, mem_ctx,
-                                      ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+                                      ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
                                       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
                                       r->in.info.info1->form_name);
 
@@ -298,9 +298,7 @@ static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC
                W_ERROR_HAVE_NO_MEMORY(msg);
 
                /* add core elements to the ldb_message for the Form */
-               msg->dn = ldb_dn_build_child(msg,
-                                            "form-name", r->in.info.info1->form_name,
-                                            ldb_dn_explode(msg, "CN=Forms,CN=PrintServer"));
+               msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
                SET_STRING(sptr_db, msg, "objectClass", "form");
 
                SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
@@ -349,7 +347,7 @@ static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC
                }
 
                count = sptr_db_search(sptr_db, mem_ctx,
-                                      ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+                                      ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
                                       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
                                       r->in.info.info1->form_name);
 
@@ -412,7 +410,7 @@ static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TAL
        }
 
        count = sptr_db_search(sptr_db, mem_ctx,
-                              ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+                              ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
                               &msgs, attrs, "(&(form-name=%s)(objectclass=form))",
                               r->in.form_name);
 
@@ -704,7 +702,7 @@ static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CT
 {
        struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context);
        struct ldb_message **msgs;
-       const struct ldb_dn *base_dn;
+       struct ldb_dn *base_dn;
        int count;
        union spoolss_FormInfo *info;
 
@@ -714,7 +712,7 @@ static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CT
         * }
         */
 
-       base_dn = ldb_dn_string_compose(mem_ctx, NULL, "CN=Forms, CN=%s, CN=Printers", printer->object_name);
+       base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name);
        W_ERROR_HAVE_NO_MEMORY(base_dn);
 
        count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL,
index 876be607f1f1d1e2790227b63106417cb3d47918..a7eb9607de341a4bd0e77a4ce9027b818d41c80a 100644 (file)
@@ -141,7 +141,7 @@ struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx,
        }
 
        ldb_ret = gendb_search(ldb, ldb,
-                              ldb_dn_explode(mem_ctx, SECRETS_PRIMARY_DOMAIN_DN), 
+                              ldb_dn_new(mem_ctx, ldb, SECRETS_PRIMARY_DOMAIN_DN), 
                               &msgs, attrs,
                               SECRETS_PRIMARY_DOMAIN_FILTER, domain);
 
index 62b529e6cf36b9664fa00694d15976c411f4cbcf..8db3a02f1c03d79d9acfe4dcb22492975538fa7f 100644 (file)
@@ -171,7 +171,7 @@ static NTSTATUS sldb_list_all(TALLOC_CTX *mem_ctx,
 
        ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
 
-       ret = ldb_search(ldb, ldb_dn_explode(tmp_ctx, "CN=SHARES"), LDB_SCOPE_SUBTREE, "(name=*)", NULL, &res);
+       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, "CN=SHARES"), LDB_SCOPE_SUBTREE, "(name=*)", NULL, &res);
        talloc_steal(tmp_ctx, res);
        if (ret != LDB_SUCCESS) {
                talloc_free(tmp_ctx);
@@ -227,7 +227,7 @@ static NTSTATUS sldb_get_config(TALLOC_CTX *mem_ctx,
                talloc_free(tmp_ctx);
                return NT_STATUS_NO_MEMORY;
        }
-       ret = ldb_search(ldb, ldb_dn_explode(tmp_ctx, "CN=SHARES"), LDB_SCOPE_SUBTREE, filter, NULL, &res);
+       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, "CN=SHARES"), LDB_SCOPE_SUBTREE, filter, NULL, &res);
        talloc_steal(tmp_ctx, res);
        if (ret != LDB_SUCCESS || res->count != 1) {
                talloc_free(tmp_ctx);
@@ -324,7 +324,7 @@ NTSTATUS sldb_create(struct share_context *ctx, const char *name, struct share_i
        }
 
        /* TODO: escape info->name */
-       msg->dn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", name);
+       msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
        if (!msg->dn) {
                DEBUG(0,("ERROR: Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
@@ -454,7 +454,7 @@ NTSTATUS sldb_set(struct share_context *ctx, const char *name, struct share_info
        }
 
        /* TODO: escape name */
-       msg->dn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", name);
+       msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
        if (!msg->dn) {
                DEBUG(0,("ERROR: Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
@@ -493,7 +493,7 @@ NTSTATUS sldb_set(struct share_context *ctx, const char *name, struct share_info
                olddn = msg->dn;
 
                /* TODO: escape newname */
-               newdn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", newname);
+               newdn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", newname);
                if (!newdn) {
                        DEBUG(0,("ERROR: Out of memory!\n"));
                        ret = NT_STATUS_NO_MEMORY;
@@ -549,7 +549,7 @@ NTSTATUS sldb_remove(struct share_context *ctx, const char *name)
 
        ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
 
-       dn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", name);
+       dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
        if (!dn) {
                DEBUG(0,("ERROR: Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
index e101195d9cd748a4d8e43afbc880cee439efd0ba..b7a5b2d24265b3afd962c9a3eb8b05ecf3913bf8 100644 (file)
@@ -280,8 +280,8 @@ static WERROR drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALL
                                return WERR_NOMEM;
                        }
 
-                       msg->dn = ldb_dn_explode(msg, req->object_dn);
-                       if (msg->dn == NULL) {
+                       msg->dn = ldb_dn_new(msg, b_state->sam_ctx, req->object_dn);
+                       if ( ! ldb_dn_validate(msg->dn)) {
                                r->out.res.res1.status = WERR_OK;
                                return WERR_OK;
                        }
index 6dce61506d40b8bf22655eaee77963b242dd8a11..af67835d03ad41d6aedfec756731862f4682fdd9 100644 (file)
@@ -52,9 +52,9 @@ struct lsa_policy_state {
        struct ldb_context *sam_ldb;
        struct sidmap_context *sidmap;
        uint32_t access_mask;
-       const struct ldb_dn *domain_dn;
-       const struct ldb_dn *builtin_dn;
-       const struct ldb_dn *system_dn;
+       struct ldb_dn *domain_dn;
+       struct ldb_dn *builtin_dn;
+       struct ldb_dn *system_dn;
        const char *domain_name;
        const char *domain_dns;
        struct dom_sid *domain_sid;
@@ -91,7 +91,7 @@ struct lsa_secret_state {
 struct lsa_trusted_domain_state {
        struct lsa_policy_state *policy;
        uint32_t access_mask;
-       const struct ldb_dn *trusted_domain_dn;
+       struct ldb_dn *trusted_domain_dn;
 };
 
 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
@@ -271,7 +271,7 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                                     struct lsa_policy_state **_state)
 {
        struct lsa_policy_state *state;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
        struct ldb_result *dom_res;
        const char *dom_attrs[] = {
                "objectSid", 
@@ -833,10 +833,8 @@ static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALL
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        
-       msg->dn = ldb_dn_build_child(mem_ctx, "cn",
-                                    r->in.info->name.string, 
-                                    policy_state->system_dn);
-       if (!msg->dn) {
+       msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "sn=%s", r->in.info->name.string)) {
                return NT_STATUS_NO_MEMORY;
        }
        
@@ -2218,8 +2216,8 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
-               msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
-               if (!name2 || !msg->dn) {
+               msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
+               if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
                        return NT_STATUS_NO_MEMORY;
                }
                
@@ -2236,7 +2234,7 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
                /* search for the secret record */
                ret = gendb_search(secret_state->sam_ldb, mem_ctx,
-                                  ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
+                                  ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
                                   &msgs, attrs,
                                   "(&(cn=%s)(objectclass=secret))", 
                                   ldb_binary_encode_string(mem_ctx, name));
@@ -2250,7 +2248,7 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
-               msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
+               msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
                samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
        } 
 
@@ -2361,7 +2359,7 @@ static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 
                /* search for the secret record */
                ret = gendb_search(secret_state->sam_ldb, mem_ctx,
-                                  ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
+                                  ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
                                   &msgs, attrs,
                                   "(&(cn=%s)(objectclass=secret))", 
                                   ldb_binary_encode_string(mem_ctx, name));
index bd8b289ae5ba5794ae39fa21d78f334aeff0f549..9b43d1c70f9f65b4cf48adb4aa3d5c9830c25675 100644 (file)
@@ -874,7 +874,7 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL
        struct netr_DomainInfo1 *info1;
        int ret, ret1, ret2, i;
        NTSTATUS status;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        const char *local_domain;
 
@@ -1130,7 +1130,7 @@ static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
        struct ldb_message **dom_res, **ref_res;
        const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
        const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        ZERO_STRUCT(r->out);
 
index b03c3789e773138e7fb87c0f55d5e556d40f29cc..3e8650eb55c1226e35f56da49aa51abb7ba3d8c0 100644 (file)
@@ -225,7 +225,7 @@ static NTSTATUS samr_LookupDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX
        struct ldb_message **dom_msgs;
        struct ldb_message **ref_msgs;
        int ret;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        r->out.sid = NULL;
 
@@ -253,7 +253,7 @@ static NTSTATUS samr_LookupDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX
                }
                
                ret = gendb_search_dn(c_state->sam_ctx, mem_ctx, 
-                                     samdb_result_dn(mem_ctx,
+                                     samdb_result_dn(c_state->sam_ctx, mem_ctx,
                                                      ref_msgs[0], "ncName", NULL), 
                                      &dom_msgs, dom_attrs);
        }
@@ -291,7 +291,7 @@ static NTSTATUS samr_EnumDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX
        const char * const ref_attrs[] = { "nETBIOSName", NULL};
        struct ldb_message **dom_msgs;
        struct ldb_message **ref_msgs;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        *r->out.resume_handle = 0;
        r->out.sam = NULL;
@@ -371,7 +371,7 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        struct ldb_message **dom_msgs;
        struct ldb_message **ref_msgs;
        int ret;
-       const struct ldb_dn *partitions_basedn;
+       struct ldb_dn *partitions_basedn;
 
        ZERO_STRUCTP(r->out.domain_handle);
 
@@ -934,8 +934,8 @@ static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLO
        }
 
        /* add core elements to the ldb_message for the user */
-       msg->dn = ldb_dn_string_compose(mem_ctx, d_state->domain_dn,
-                                       "CN=%s,CN=Users", groupname);
+       msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn);
+       ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
        if (!msg->dn) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1197,11 +1197,12 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
        }
 
        /* add core elements to the ldb_message for the user */
-       msg->dn = ldb_dn_build_child(mem_ctx, "CN", cn_name, ldb_dn_build_child(mem_ctx, "CN", container, d_state->domain_dn));
-       if (!msg->dn) {
+       msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn);
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container)) {
                ldb_transaction_cancel(d_state->sam_ctx);
-               return NT_STATUS_NO_MEMORY;             
+               return NT_STATUS_FOOBAR;
        }
+
        samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name);
        samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class);
        
@@ -1215,13 +1216,13 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
        case  LDB_ERR_ENTRY_ALREADY_EXISTS:
                ldb_transaction_cancel(d_state->sam_ctx);
                DEBUG(0,("Failed to create user record %s: %s\n",
-                        ldb_dn_linearize(mem_ctx, msg->dn),
+                        ldb_dn_get_linearized(msg->dn),
                         ldb_errstring(d_state->sam_ctx)));
                return NT_STATUS_USER_EXISTS;
        default:
                ldb_transaction_cancel(d_state->sam_ctx);
                DEBUG(0,("Failed to create user record %s: %s\n",
-                        ldb_dn_linearize(mem_ctx, msg->dn),
+                        ldb_dn_get_linearized(msg->dn),
                         ldb_errstring(d_state->sam_ctx)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -1464,8 +1465,8 @@ static NTSTATUS samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_C
        }
 
        /* add core elements to the ldb_message for the alias */
-       msg->dn = ldb_dn_string_compose(mem_ctx, d_state->domain_dn,
-                                       "CN=%s, CN=Users", alias_name);
+       msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn);
+       ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
        if (!msg->dn) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -2288,7 +2289,7 @@ static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC
                        struct ldb_message **res2;
                        const char * const attrs2[2] = { "objectSid", NULL };
                        ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
-                                          ldb_dn_explode(mem_ctx, (const char *)el->values[i].data),
+                                          ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data),
                                           &res2, attrs2);
                        if (ret != 1)
                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -2682,7 +2683,7 @@ static NTSTATUS samr_GetMembersInAlias(struct dcesrv_call_state *dce_call, TALLO
                        struct ldb_message **msgs2;
                        const char * const attrs2[2] = { "objectSid", NULL };
                        ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
-                                          ldb_dn_explode(mem_ctx, (const char *)el->values[i].data),
+                                          ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data),
                                           &msgs2, attrs2);
                        if (ret != 1)
                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -3782,7 +3783,7 @@ static NTSTATUS samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state *dce
                        return NT_STATUS_NO_MEMORY;
                }
 
-               mod->dn = samdb_result_dn(mod, res[i], "distinguishedName", NULL);
+               mod->dn = samdb_result_dn(d_state->sam_ctx, mod, res[i], "distinguishedName", NULL);
                if (mod->dn == NULL) {
                        talloc_free(mod);
                        continue;
index 8e53fa7a100bcebfc3dbf2618345f504a936f82b..bebc60e0e7f03920cff9482a83f05d6ee4c4e6b4 100644 (file)
@@ -49,7 +49,7 @@ struct samr_domain_state {
        uint32_t access_mask;
        struct dom_sid *domain_sid;
        const char *domain_name;
-       const struct ldb_dn *domain_dn;
+       struct ldb_dn *domain_dn;
 };
 
 /*
@@ -61,5 +61,5 @@ struct samr_account_state {
        uint32_t access_mask;
        struct dom_sid *account_sid;
        const char *account_name;
-       const struct ldb_dn *account_dn;
+       struct ldb_dn *account_dn;
 };
index a62e7689808fd041f3e7d958a300d37912e516fc..3d15a2973500317448b02894e77f4b9797bbc4a2 100644 (file)
@@ -187,7 +187,7 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_
        uint32_t new_pass_len;
        struct samr_CryptPassword *pwbuf = r->in.password;
        struct ldb_context *sam_ctx;
-       const struct ldb_dn *user_dn;
+       struct ldb_dn *user_dn;
        int ret;
        struct ldb_message **res, *mod;
        const char * const attrs[] = { "objectSid", "lmPwdHash", NULL };
@@ -320,7 +320,7 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
        char new_pass[512];
        uint32_t new_pass_len;
        struct ldb_context *sam_ctx = NULL;
-       const struct ldb_dn *user_dn;
+       struct ldb_dn *user_dn;
        int ret;
        struct ldb_message **res, *mod;
        const char * const attrs[] = { "ntPwdHash", "lmPwdHash", NULL };
@@ -510,7 +510,7 @@ NTSTATUS samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
 */
 NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
                           void *sam_ctx,
-                          const struct ldb_dn *account_dn, const struct ldb_dn *domain_dn,
+                          struct ldb_dn *account_dn, struct ldb_dn *domain_dn,
                           TALLOC_CTX *mem_ctx,
                           struct ldb_message *msg, 
                           struct samr_CryptPassword *pwbuf)
@@ -552,7 +552,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
 */
 NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
                              struct ldb_context *sam_ctx,
-                             const struct ldb_dn *account_dn, const struct ldb_dn *domain_dn,
+                             struct ldb_dn *account_dn, struct ldb_dn *domain_dn,
                              TALLOC_CTX *mem_ctx,
                              struct ldb_message *msg, 
                              struct samr_CryptPasswordEx *pwbuf)
index 0af9738b60c62e17c97598f584cb36c6062b661b..3c368bba4f26a6ef081764d6491326ced8037a38 100644 (file)
@@ -83,8 +83,8 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
                /* a null basedn is valid */
        }
        if (base != NULL) {
-               basedn = ldb_dn_explode(tmp_ctx, base);
-               if (basedn == NULL) {
+               basedn = ldb_dn_new(tmp_ctx, ldb, base);
+               if ( ! ldb_dn_validate(basedn)) {
                        ejsSetErrorMsg(eid, "ldb.search malformed base dn");
                        goto failed;
                }
@@ -187,8 +187,8 @@ static int ejs_ldbDelete(MprVarHandle eid, int argc, struct MprVar **argv)
                return -1;
        }
 
-       dn = ldb_dn_explode(ldb, mprToString(argv[0]));
-       if (dn == NULL) {
+       dn = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
+       if ( ! ldb_dn_validate(dn)) {
                ejsSetErrorMsg(eid, "ldb.delete malformed dn");
                return -1;
        }
@@ -222,9 +222,9 @@ static int ejs_ldbRename(MprVarHandle eid, int argc, struct MprVar **argv)
                return -1;
        }
 
-       dn1 = ldb_dn_explode(ldb, mprToString(argv[0]));
-       dn2 = ldb_dn_explode(ldb, mprToString(argv[1]));
-       if (dn1 == NULL || dn2 == NULL) {
+       dn1 = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
+       dn2 = ldb_dn_new(ldb, ldb, mprToString(argv[1]));
+       if ( ! ldb_dn_validate(dn1) ||  ! ldb_dn_validate(dn2)) {
                ejsSetErrorMsg(eid, "ldb.rename invalid or malformed arguments");
                return -1;
        }
index 05f978719135fe1cc8fcbe736ba7218bd63780de..fb2037f75e192b8064f4b69299427c2b30bd0936 100644 (file)
@@ -167,12 +167,12 @@ done:
   use the convenient ldif dump routines in ldb to print out cldap
   search results
 */
-static struct ldb_message *ldap_msg_to_ldb(TALLOC_CTX *mem_ctx, struct ldap_SearchResEntry *res)
+static struct ldb_message *ldap_msg_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldap_SearchResEntry *res)
 {
        struct ldb_message *msg;
 
        msg = ldb_msg_new(mem_ctx);
-       msg->dn = ldb_dn_explode_or_special(msg, res->dn);
+       msg->dn = ldb_dn_new(msg, ldb, res->dn);
        msg->num_elements = res->num_attributes;
        msg->elements = talloc_steal(msg, res->attributes);
        return msg;
@@ -194,7 +194,7 @@ static void cldap_dump_results(struct cldap_search *search)
        ldb = ldb_init(NULL);
 
        ZERO_STRUCT(ldif);
-       ldif.msg = ldap_msg_to_ldb(ldb, search->out.response);
+       ldif.msg = ldap_msg_to_ldb(ldb, ldb, search->out.response);
 
        ldb_ldif_write_file(ldb, stdout, &ldif);
 
index bc8f1e38cef8446f2c534082d7063cbd5924f7dc..2ab0c5e1166794eb6485ec4530e150beff9b39e3 100644 (file)
@@ -119,7 +119,7 @@ static BOOL test_search_rootDSE(struct ldb_context *ldb, struct test_rootDSE *ro
 
        d_printf("Testing RootDSE Search\n");
 
-       ret = ldb_search(ldb, ldb_dn_new(ldb), LDB_SCOPE_BASE, 
+       ret = ldb_search(ldb, ldb_dn_new(ldb, ldb, NULL), LDB_SCOPE_BASE, 
                         NULL, NULL, &r);
        if (ret != LDB_SUCCESS) {
                return False;
@@ -226,7 +226,7 @@ static BOOL test_create_schema_type(struct ldb_context *ldb, struct test_rootDSE
        ctrl[1] = NULL;
 
        req->operation = LDB_SEARCH;
-       req->op.search.base = ldb_dn_explode(req, root->schemadn);
+       req->op.search.base = ldb_dn_new(req, ldb, root->schemadn);
        req->op.search.scope = LDB_SCOPE_SUBTREE;
        req->op.search.tree = ldb_parse_tree(req, filter);
        if (req->op.search.tree == NULL) return -1;
index 555f02588c87cfc75bc9a2fc824176d695d0409f..2d521394ce84bab5d2c5cc3831f5842df15bb244 100644 (file)
@@ -133,8 +133,7 @@ static BOOL ldb_add_record(struct ldb_context *ldb, unsigned rid)
                return False;
        }
 
-       msg->dn = ldb_dn_string_compose(msg, NULL, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", 
-                                       rid);
+       msg->dn = ldb_dn_new_fmt(msg, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", rid);
        if (msg->dn == NULL) {
                return False;
        }
@@ -206,25 +205,20 @@ static BOOL test_ldb_speed(struct torture_context *torture, const void *_data)
                char *expr;
 
                i = random() % torture_entries;
-               dn = ldb_dn_string_compose(tmp_ctx, NULL, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", 
-                                       i);
-               if (ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res) != LDB_SUCCESS ||
-                   res->count != 1) {
-                       torture_fail(torture, talloc_asprintf(torture,
-                                                                                                 "Failed to find SID %d\n", i));
+               dn = ldb_dn_new_fmt(tmp_ctx, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", i);
+               if (ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res) != LDB_SUCCESS || res->count != 1) {
+                       torture_fail(torture, talloc_asprintf(torture, "Failed to find SID %d\n", i));
                }
                talloc_free(res);
                talloc_free(dn);
                expr = talloc_asprintf(tmp_ctx, "(UID=%u)", i);
-               if (ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res) != LDB_SUCCESS ||
-                   res->count != 1) {
-                       torture_fail(torture, talloc_asprintf(torture, 
-                                                                                                 "Failed to find UID %d\n", i));
+               if (ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res) != LDB_SUCCESS || res->count != 1) {
+                       torture_fail(torture, talloc_asprintf(torture, "Failed to find UID %d\n", i));
                }
                talloc_free(res);
                talloc_free(expr);
        }
-       
+
        if (talloc_total_blocks(torture) > 100) {
                torture_fail(torture, "memory leak in ldb search\n");
                goto failed;
index e6ff33d58dcbbf09a309be295c775444c4abbf09..adf14461c0dc731bce824b88e1ee88fd6e313e28 100644 (file)
@@ -211,6 +211,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        const char *dns_domain;
        const char *nt4_domain;
        const char *FQDN_1779_name;
+       struct ldb_context *ldb;
        struct ldb_dn *FQDN_1779_dn;
        struct ldb_dn *realm_dn;
        const char *realm_dn_str;
@@ -318,9 +319,11 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        if (!ret) {
                return ret;
        }
+
+       ldb = ldb_init(mem_ctx);
        
        realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
-       realm_dn =  ldb_dn_explode(mem_ctx, realm_dn_str);
+       realm_dn =  ldb_dn_new(mem_ctx, ldb, realm_dn_str);
        realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
 
        if (strcmp(realm_canonical, 
@@ -399,7 +402,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
 
-       FQDN_1779_dn = ldb_dn_explode(mem_ctx, FQDN_1779_name);
+       FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
 
        canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
        canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
index d325f10cee27d696ac841fe731c120503bf6136b..c9507287e8bd24c511639253bc16b903ef4011bc 100644 (file)
@@ -424,8 +424,8 @@ NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_JoinDomain
        }
 
        /* Remove CN=Servers,... entry from the AD. */ 
-       server_dn = ldb_dn_explode(tmp_ctx, libnet_r->out.server_dn_str);
-       if (!server_dn) {
+       server_dn = ldb_dn_new(tmp_ctx, ldb_ctx, libnet_r->out.server_dn_str);
+       if (! ldb_dn_validate(server_dn)) {
                libnet_r->out.error_string = NULL;
                talloc_free(tmp_ctx);
                return NT_STATUS_NO_MEMORY;
index 55ab76c2289b63dd13c68e1af4eb31dbb6700ca9..bc24ae1abdb62de241fbe9ca2b60ca4b46a39acf 100644 (file)
@@ -47,7 +47,7 @@ static uint64_t wins_config_db_get_seqnumber(struct ldb_context *ldb)
        TALLOC_CTX *tmp_ctx = talloc_new(ldb);
        uint64_t seqnumber = 0;
 
-       dn = ldb_dn_explode(tmp_ctx, "@BASEINFO");
+       dn = ldb_dn_new(tmp_ctx, ldb, "@BASEINFO");
        if (!dn) goto failed;
 
        /* find the record in the WINS database */
@@ -141,7 +141,7 @@ NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service)
        service->config.seqnumber = new_seqnumber;
 
        /* find the record in the WINS database */
-       ret = ldb_search(service->config.ldb, ldb_dn_explode(tmp_ctx, "CN=PARTNERS"), LDB_SCOPE_SUBTREE,
+       ret = ldb_search(service->config.ldb, ldb_dn_new(tmp_ctx, service->config.ldb, "CN=PARTNERS"), LDB_SCOPE_SUBTREE,
                         "(objectClass=wreplPartner)", NULL, &res);
        if (ret != LDB_SUCCESS) goto failed;
        talloc_steal(tmp_ctx, res);