Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-python
[samba.git] / source4 / lib / ldb / include / ldb.h
index 0438b88bbb6fee3ba62542bfb9f06f65ff415b46..2e54920c17eaa7f25ea1906bc26af47cf1a21e7a 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/>.
 */
 
 /*
@@ -204,7 +203,7 @@ struct ldb_debug_ops {
 */
 struct ldb_utf8_fns {
        void *context;
-       char *(*casefold)(void *context, void *mem_ctx, const char *s);
+       char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s);
 };
 
 /**
@@ -232,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
 */
@@ -276,8 +280,8 @@ struct ldb_parse_tree {
        } u;
 };
 
-struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s);
-char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree);
+struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s);
+char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree);
 
 /**
    Encode a binary blob
@@ -293,7 +297,7 @@ char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree);
 
    \sa <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>.
 */
-char *ldb_binary_encode(void *ctx, struct ldb_val val);
+char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val);
 
 /**
    Encode a string
@@ -309,13 +313,13 @@ char *ldb_binary_encode(void *ctx, struct ldb_val val);
 
    \sa <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>.
 */
-char *ldb_binary_encode_string(void *mem_ctx, const char *string);
+char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string);
 
 /*
   functions for controlling attribute handling
 */
-typedef int (*ldb_attr_handler_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, struct ldb_val *);
-typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, const struct ldb_val *);
+typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *);
+typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *);
 
 /*
   attribute handler structure
@@ -535,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"
 
@@ -560,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;
 };
 
@@ -651,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 {
@@ -674,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;
@@ -705,7 +705,7 @@ struct ldb_handle {
 struct ldb_search {
        struct ldb_dn *base;
        enum ldb_scope scope;
-       const struct ldb_parse_tree *tree;
+       struct ldb_parse_tree *tree;
        const char * const *attrs;
        struct ldb_result *res;
 };
@@ -714,7 +714,7 @@ struct ldb_add {
        const struct ldb_message *message;
 };
 
-struct  ldb_modify {
+struct ldb_modify {
        const struct ldb_message *message;
 };
 
@@ -735,12 +735,14 @@ struct ldb_register_partition {
        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;
 };
@@ -756,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;
@@ -778,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
@@ -799,7 +803,7 @@ int ldb_global_init(void);
   \return pointer to ldb_context that should be free'd (using talloc_free())
   at the end of the program.
 */
-struct ldb_context *ldb_init(void *mem_ctx);
+struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx);
 
 /**
    Connect to a database.
@@ -826,18 +830,35 @@ 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 rootDomainNamingContext of the rootDSE
+  This value have been set in an opaque pointer at connection time
+*/
+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)
@@ -858,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
@@ -872,7 +893,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,
+                       TALLOC_CTX *mem_ctx,
                        struct ldb_dn *base,
                        enum ldb_scope scope,
                        const char *expression,
@@ -886,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
@@ -897,7 +918,7 @@ int ldb_build_search_req(struct ldb_request **ret_req,
 
 int ldb_build_add_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
-                       void *mem_ctx,
+                       TALLOC_CTX *mem_ctx,
                        const struct ldb_message *message,
                        struct ldb_control **controls,
                        void *context,
@@ -908,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
@@ -919,7 +940,7 @@ int ldb_build_add_req(struct ldb_request **ret_req,
 
 int ldb_build_mod_req(struct ldb_request **ret_req,
                        struct ldb_context *ldb,
-                       void *mem_ctx,
+                       TALLOC_CTX *mem_ctx,
                        const struct ldb_message *message,
                        struct ldb_control **controls,
                        void *context,
@@ -930,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
@@ -941,7 +962,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,
+                       TALLOC_CTX *mem_ctx,
                        struct ldb_dn *dn,
                        struct ldb_control **controls,
                        void *context,
@@ -952,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
@@ -964,13 +985,34 @@ 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,
+                       TALLOC_CTX *mem_ctx,
                        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
 
@@ -1004,15 +1046,6 @@ int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                       enum ldb_scope scope, const char * const *attrs,
                       const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8);
 
-/*
-  like ldb_search() but takes a parse tree
-*/
-int ldb_search_bytree(struct ldb_context *ldb, 
-                     struct ldb_dn *base,
-                     enum ldb_scope scope,
-                     struct ldb_parse_tree *tree,
-                     const char * const *attrs, struct ldb_result **res);
-
 /**
   Add a record to the database.
 
@@ -1074,6 +1107,68 @@ int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *new
 */
 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,
+                          TALLOC_CTX *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
 */
@@ -1118,11 +1213,11 @@ void ldb_set_utf8_default(struct ldb_context *ldb);
    \note The default function is not yet UTF8 aware. Provide your own
          set of functions through ldb_set_utf8_fns()
 */
-char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s);
+char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s);
 
 /**
    Check the attribute name is valid according to rfc2251
-   \param s tthe string to check
+   \param s the string to check
 
    \return 1 if the name is ok
 */
@@ -1262,7 +1357,7 @@ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif
 
    \note The caller is responsible for freeing the result
 */
-char *ldb_base64_encode(void *mem_ctx, const char *buf, int len);
+char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len);
 
 /**
    Base64 decode a buffer
@@ -1280,15 +1375,15 @@ int ldb_base64_decode(char *s);
 
 /* The following definitions come from lib/ldb/common/ldb_dn.c  */
 
-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);
+struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn);
+struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *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);
+char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value);
 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);
+char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_alloc_casefold(TALLOC_CTX *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);
@@ -1300,10 +1395,10 @@ bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_
 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);
+struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+char *ldb_dn_canonical_ex_string(TALLOC_CTX *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);
@@ -1317,9 +1412,6 @@ 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
 
@@ -1337,7 +1429,7 @@ int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2);
   return 0 for match
 */
 #define ldb_attr_cmp(a, b) strcasecmp(a, b)
-char *ldb_attr_casefold(void *mem_ctx, const char *s);
+char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s);
 int ldb_attr_dn(const char *attr);
 
 /**
@@ -1347,7 +1439,7 @@ int ldb_attr_dn(const char *attr);
    to get the top level context, however the ldb context (from
    ldb_init()) may be a better choice
 */
-struct ldb_message *ldb_msg_new(void *mem_ctx);
+struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx);
 
 /**
    Find an element within an message
@@ -1441,15 +1533,15 @@ const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg,
                                        const char *default_value);
 
 struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
-                                      void *mem_ctx,
+                                      TALLOC_CTX *mem_ctx,
                                       const struct ldb_message *msg,
                                       const char *attr_name);
 
 void ldb_msg_sort_elements(struct ldb_message *msg);
 
-struct ldb_message *ldb_msg_copy_shallow(void *mem_ctx, 
+struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, 
                                         const struct ldb_message *msg);
-struct ldb_message *ldb_msg_copy(void *mem_ctx, 
+struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, 
                                 const struct ldb_message *msg);
 
 struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 
@@ -1491,7 +1583,7 @@ int ldb_msg_sanity_check(struct ldb_context *ldb,
 
    \return the duplicated ldb_val structure.
 */
-struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v);
+struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v);
 
 /**
   this allows the user to set a debug function for error reporting
@@ -1517,8 +1609,8 @@ 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 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);
+const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs);
+const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr);
 int ldb_attr_in_list(const char * const *attrs, const char *attr);
 
 
@@ -1533,22 +1625,22 @@ 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
 
    \return the formatted string, or NULL if the time structure could
    not be converted
 */
-char *ldb_timestring(void *mem_ctx, time_t t);
+char *ldb_timestring(TALLOC_CTX *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
 
@@ -1556,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(TALLOC_CTX *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, TALLOC_CTX *mem_ctx, const char **control_strings);
+
 #endif