r25624: Remove ipv4_addr hack. Only causes 4 extra includes of system/network.h becau...
[bbaumbach/samba-autobuild/.git] / source4 / lib / ldb / include / ldb.h
index 17a2ec75569bb06dc98eb83edbcb66f95a5429ef..301db4dadc0763c37056149117b5df6b1d5c7477 100644 (file)
@@ -12,7 +12,7 @@
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
+   version 3 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,8 +20,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
@@ -156,7 +155,6 @@ struct ldb_message {
        struct ldb_dn *dn;
        unsigned int num_elements;
        struct ldb_message_element *elements;
-       void *private_data; /* private to the backend */
 };
 
 enum ldb_changetype {
@@ -233,6 +231,11 @@ struct ldb_utf8_fns {
 */
 #define LDB_FLG_RECONNECT 4
 
+/**
+   Flag to tell backends not to use mmap
+*/
+#define LDB_FLG_NOMMAP 8
+
 /*
    structures for ldb_parse_tree handling code
 */
@@ -329,17 +332,23 @@ typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const
   comparison_fn                -> compare two values
 */
 
-struct ldb_attrib_handler {
-
-       const char *attr;
-       unsigned flags;
-
+struct ldb_schema_syntax {
+       const char *name;
        ldb_attr_handler_t ldif_read_fn;
        ldb_attr_handler_t ldif_write_fn;
        ldb_attr_handler_t canonicalise_fn;
        ldb_attr_comparison_t comparison_fn;
 };
 
+struct ldb_schema_attribute {
+       const char *name;
+       unsigned flags;
+       const struct ldb_schema_syntax *syntax;
+};
+
+const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
+                                                               const char *name);
+
 /**
    The attribute is not returned by default
 */
@@ -530,18 +539,10 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 #define LDB_EXTENDED_START_TLS_OID     "1.3.6.1.4.1.1466.20037"
 
 /**
-   OID for LDAP Extended Operation START_TLS.
-
-   This Extended operation is used to start a new TLS
-   channel on top of a clear text channel.
 */
 #define LDB_EXTENDED_DYNAMIC_OID       "1.3.6.1.4.1.1466.101.119.1"
 
 /**
-   OID for LDAP Extended Operation START_TLS.
-
-   This Extended operation is used to start a new TLS
-   channel on top of a clear text channel.
 */
 #define LDB_EXTENDED_FAST_BIND_OID     "1.2.840.113556.1.4.1781"
 
@@ -555,20 +556,24 @@ struct ldb_sd_flags_control {
        unsigned secinfo_flags;
 };
 
+/*
+ * DOMAIN_SCOPE                0x00000001
+ * this limits the search to one partition,
+ * and no referrals will be returned.
+ * (Note this doesn't limit the entries by there
+ *  objectSid belonging to a domain! Builtin and Foreign Sids
+ *  are still returned)
+ *
+ * PHANTOM_ROOT                0x00000002
+ * this search on the whole tree on a domain controller
+ * over multiple partitions without referrals.
+ * (This is the default behavior on the Global Catalog Port)
+ */
+
+#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001
+#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002
+
 struct ldb_search_options_control {
-       /*
-        * DOMAIN_SCOPE         0x00000001
-        * this limits the search to one partition,
-        * and no referrals will be returned.
-        * (Note this doesn't limit the entries by there
-        *  objectSid belonging to a domain! Builtin and Foreign Sids
-        *  are still returned)
-        *
-        * PHANTOM_ROOT         0x00000002
-        * this search on the whole tree on a domain controller
-        * over multiple partitions without referrals.
-        * (This is the default behavior on the Global Catalog Port)
-        */
        unsigned search_options;
 };
 
@@ -646,9 +651,9 @@ enum ldb_request_type {
        LDB_DELETE,
        LDB_RENAME,
        LDB_EXTENDED,
+       LDB_SEQUENCE_NUMBER,
        LDB_REQ_REGISTER_CONTROL,
-       LDB_REQ_REGISTER_PARTITION,
-       LDB_SEQUENCE_NUMBER
+       LDB_REQ_REGISTER_PARTITION
 };
 
 enum ldb_reply_type {
@@ -669,19 +674,19 @@ enum ldb_state {
        LDB_ASYNC_DONE
 };
 
+struct ldb_extended {
+       const char *oid;
+       void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
+};
+
 struct ldb_result {
        unsigned int count;
        struct ldb_message **msgs;
        char **refs;
+       struct ldb_extended *extended;
        struct ldb_control **controls;
 };
 
-struct ldb_extended {
-       const char *oid;
-       const char *value;
-       int value_len;
-};
-
 struct ldb_reply {
        enum ldb_reply_type type;
        struct ldb_message *message;
@@ -698,7 +703,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;
@@ -709,17 +714,17 @@ struct ldb_add {
        const struct ldb_message *message;
 };
 
-struct  ldb_modify {
+struct ldb_modify {
        const struct ldb_message *message;
 };
 
 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,15 +732,17 @@ struct ldb_register_control {
 };
 
 struct ldb_register_partition {
-       const struct ldb_dn *dn;
+       struct ldb_dn *dn;
+};
+
+enum ldb_sequence_type {
+       LDB_SEQ_HIGHEST_SEQ,
+       LDB_SEQ_HIGHEST_TIMESTAMP,
+       LDB_SEQ_NEXT
 };
 
 struct ldb_sequence_number {
-       enum ldb_sequence_type {
-               LDB_SEQ_HIGHEST_SEQ,
-               LDB_SEQ_HIGHEST_TIMESTAMP,
-               LDB_SEQ_NEXT
-       } type;
+       enum ldb_sequence_type type;
        uint64_t seq_num;
        uint32_t flags;
 };
@@ -751,9 +758,10 @@ struct ldb_request {
                struct ldb_modify mod;
                struct ldb_delete del;
                struct ldb_rename rename;
+               struct ldb_extended extended;
+               struct ldb_sequence_number seq_num;
                struct ldb_register_control reg_control;
                struct ldb_register_partition reg_partition;
-               struct ldb_sequence_number seq_num;
        } op;
 
        struct ldb_control **controls;
@@ -773,6 +781,7 @@ int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type);
 int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout);
 int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq);
 void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms);
+void ldb_set_modules_dir(struct ldb_context *ldb, const char *path);
 
 /**
   Initialise ldbs' global information
@@ -822,17 +831,34 @@ struct ldb_context *ldb_init(void *mem_ctx);
 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]);
 
 /*
-  return an automatic baseDN from the defaultNamingContext of the rootDSE
+  return an automatic basedn from the rootDomainNamingContext 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_root_basedn(struct ldb_context *ldb);
 
+/*
+  return an automatic basedn from the configurationNamingContext of the rootDSE
+  This value have been set in an opaque pointer at connection time
+*/
+struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb);
+
+/*
+  return an automatic basedn from the schemaNamingContext of the rootDSE
+  This value have been set in an opaque pointer at connection time
+*/
+struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb);
+
+/*
+  return an automatic baseDN from the defaultNamingContext of the rootDSE
+  This value have been set in an opaque pointer at connection time
+*/
+struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
 
 /**
-  The Default iasync search callback function 
+  The default async search callback function 
 
   \param ldb the context associated with the database (from ldb_init())
-  \param context the callback context
+  \param context the callback context (struct ldb_result *)
   \param ares a single reply from the async core
 
   \return result code (LDB_SUCCESS on success, or a failure code)
@@ -853,7 +879,7 @@ int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct l
 
   \param ret_req the request structure is returned here (talloced on mem_ctx)
   \param ldb the context associated with the database (from ldb_init())
-  \param mem_ctx a talloc emmory context (used as parent of ret_req)
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
   \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one)
   \param scope the search scope for the query
   \param expression the search expression to use for this query
@@ -868,7 +894,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,
@@ -881,7 +907,7 @@ int ldb_build_search_req(struct ldb_request **ret_req,
 
   \param ret_req the request structure is returned here (talloced on mem_ctx)
   \param ldb the context associated with the database (from ldb_init())
-  \param mem_ctx a talloc emmory context (used as parent of ret_req)
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
   \param message contains the entry to be added 
   \param controls an array of controls
   \param context the callback function context
@@ -903,7 +929,7 @@ int ldb_build_add_req(struct ldb_request **ret_req,
 
   \param ret_req the request structure is returned here (talloced on mem_ctx)
   \param ldb the context associated with the database (from ldb_init())
-  \param mem_ctx a talloc emmory context (used as parent of ret_req)
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
   \param message contains the entry to be modified
   \param controls an array of controls
   \param context the callback function context
@@ -925,7 +951,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
 
   \param ret_req the request structure is returned here (talloced on mem_ctx)
   \param ldb the context associated with the database (from ldb_init())
-  \param mem_ctx a talloc emmory context (used as parent of ret_req)
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
   \param dn the DN to be deleted
   \param controls an array of controls
   \param context the callback function context
@@ -937,7 +963,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);
@@ -947,7 +973,7 @@ int ldb_build_del_req(struct ldb_request **ret_req,
 
   \param ret_req the request structure is returned here (talloced on mem_ctx)
   \param ldb the context associated with the database (from ldb_init())
-  \param mem_ctx a talloc emmory context (used as parent of ret_req)
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
   \param olddn the old DN
   \param newdn the new DN
   \param controls an array of controls
@@ -960,12 +986,33 @@ 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);
 
+/**
+  Add a ldb_control to a ldb_request
+
+  \param req the request struct where to add the control
+  \param oid the object identifier of the control as string
+  \param ciritical whether the control should be critical or not
+  \param data a talloc pointer to the control specific data
+
+  \return result code (LDB_SUCCESS on success, or a failure code)
+*/
+int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data);
+
+/**
+   check if a control with the specified "oid" exist and return it 
+  \param req the request struct where to add the control
+  \param oid the object identifier of the control as string
+
+  \return the control, NULL if not found 
+*/
+struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid);
+
 /**
   Search the database
 
@@ -984,19 +1031,20 @@ 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);
 
 /*
-  like ldb_search() but takes a parse tree
+ * a useful search function where you can easily define the expression and
+ * that takes a memory context where results are allocated
 */
-int ldb_search_bytree(struct ldb_context *ldb, 
-                     const struct ldb_dn *base,
-                     enum ldb_scope scope,
-                     struct ldb_parse_tree *tree,
-                     const char * const *attrs, struct ldb_result **res);
+
+int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
+                      struct ldb_result **result, struct ldb_dn *base,
+                      enum ldb_scope scope, const char * const *attrs,
+                      const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8);
 
 /**
   Add a record to the database.
@@ -1043,7 +1091,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 +1105,69 @@ 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);
+
+/**
+  The default async extended operation callback function 
+
+  \param ldb the context associated with the database (from ldb_init())
+  \param context the callback context (struct ldb_result *)
+  \param ares a single reply from the async core
+
+  \return result code (LDB_SUCCESS on success, or a failure code)
+
+  \note this function expects the context to always be an struct ldb_result pointer
+  AND a talloc context, this function will steal on the context each message
+  from the ares reply passed on by the async core so that in the end all the
+  messages will be in the context (ldb_result)  memory tree.
+  Freeing the passed context (ldb_result tree) will free all the resources
+  (the request need to be freed separately and the result doe not depend on the
+  request that can be freed as sson as the search request is finished)
+*/
+int ldb_extended_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares);
+
+/**
+  Helper function to build a extended request
+
+  \param ret_req the request structure is returned here (talloced on mem_ctx)
+  \param ldb the context associated with the database (from ldb_init())
+  \param mem_ctx a talloc memory context (used as parent of ret_req)
+  \param oid the OID of the extended operation.
+  \param data a void pointer a the extended operation specific parameters,
+  it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it  
+  \param controls an array of controls
+  \param context the callback function context
+  \param the callback function to handle the async replies
+
+  \return result code (LDB_SUCCESS on success, or a failure code)
+*/
+int ldb_build_extended_req(struct ldb_request **ret_req,
+                          struct ldb_context *ldb,
+                          void *mem_ctx,
+                          const char *oid,
+                          void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
+                          struct ldb_control **controls,
+                          void *context,
+                          ldb_request_callback_t callback);
+
+/**
+  call an extended operation
+
+  This function deletes a record from the database.
+
+  \param ldb the context associated with the database (from ldb_init())
+  \param oid the OID of the extended operation.
+  \param data a void pointer a the extended operation specific parameters,
+  it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it  
+  \param res the result of the extended operation
+
+  \return result code (LDB_SUCCESS if the extended operation returned fine,
+  otherwise a failure code)
+*/
+int ldb_extended(struct ldb_context *ldb, 
+                const char *oid,
+                void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
+                struct ldb_result **res);
 
 /**
   start a transaction
@@ -1263,49 +1373,45 @@ char *ldb_base64_encode(void *mem_ctx, const char *buf, int len);
 */
 int ldb_base64_decode(char *s);
 
-int ldb_attrib_add_handlers(struct ldb_context *ldb, 
-                           const struct ldb_attrib_handler *handlers, 
-                           unsigned num_handlers);
-
 /* 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, ...) PRINTF_ATTRIBUTE(3,4);
+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);
+const char *ldb_dn_get_linearized(struct ldb_dn *dn);
+const char *ldb_dn_get_casefold(struct ldb_dn *dn);
+char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_alloc_casefold(void *mem_ctx, 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, ...) PRINTF_ATTRIBUTE(2,3);
+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, ...) PRINTF_ATTRIBUTE(2,3);
+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 */
-int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2);
-
 /**
    Compare two attributes
 
@@ -1317,8 +1423,12 @@ int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2);
 
    \return 0 if the attribute names are the same, or only differ in
    case; non-zero if there are any differences
+
+  attribute names are restricted by rfc2251 so using
+  strcasecmp and toupper here is ok.
+  return 0 for match
 */
-int ldb_attr_cmp(const char *attr1, const char *attr2);
+#define ldb_attr_cmp(a, b) strcasecmp(a, b)
 char *ldb_attr_casefold(void *mem_ctx, const char *s);
 int ldb_attr_dn(const char *attr);
 
@@ -1422,9 +1532,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);
 
@@ -1498,10 +1609,6 @@ int ldb_set_debug_stderr(struct ldb_context *ldb);
 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value);
 void *ldb_get_opaque(struct ldb_context *ldb, const char *name);
 
-const struct ldb_attrib_handler *ldb_attrib_handler(struct ldb_context *ldb,
-                                                   const char *attrib);
-
-
 const char **ldb_attr_list_copy(void *mem_ctx, const char * const *attrs);
 const char **ldb_attr_list_copy_add(void *mem_ctx, const char * const *attrs, const char *new_attr);
 int ldb_attr_in_list(const char * const *attrs, const char *attr);
@@ -1518,9 +1625,9 @@ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr);
 /**
    Convert a time structure to a string
 
-   This function converts a time_t structure to an LDAP formatted time
-   string.
-
+   This function converts a time_t structure to an LDAP formatted
+   GeneralizedTime string.
+               
    \param mem_ctx the memory context to allocate the return string in
    \param t the time structure to convert
 
@@ -1532,8 +1639,8 @@ char *ldb_timestring(void *mem_ctx, time_t t);
 /**
    Convert a string to a time structure
 
-   This function converts an LDAP formatted time string to a time_t
-   structure.
+   This function converts an LDAP formatted GeneralizedTime string
+   to a time_t structure.
 
    \param s the string to convert
 
@@ -1541,6 +1648,45 @@ char *ldb_timestring(void *mem_ctx, time_t t);
 */
 time_t ldb_string_to_time(const char *s);
 
+/**
+   Convert a time structure to a string
+
+   This function converts a time_t structure to an LDAP formatted
+   UTCTime string.
+               
+   \param mem_ctx the memory context to allocate the return string in
+   \param t the time structure to convert
+
+   \return the formatted string, or NULL if the time structure could
+   not be converted
+*/
+char *ldb_timestring_utc(void *mem_ctx, time_t t);
+
+/**
+   Convert a string to a time structure
+
+   This function converts an LDAP formatted UTCTime string
+   to a time_t structure.
+
+   \param s the string to convert
+
+   \return the time structure, or 0 if the string cannot be converted
+*/
+time_t ldb_string_utc_to_time(const char *s);
+
 
 void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp);
+
+
+/**
+   Convert an array of string represention of a control into an array of ldb_control structures 
+   
+   \param ldb LDB context
+   \param mem_ctx TALLOC context to return result on, and to allocate error_string on
+   \param control_strings Array of string-formatted controls
+
+   \return array of ldb_control elements
+*/
+struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings);
+
 #endif