added new function "ldb_msg_add_dn"
[samba.git] / source4 / lib / ldb / include / ldb.h
index 937029f52ce3f53f2ec78274430a9d05416500d0..1d0b533a332974b496f3c2fe3d6271d067238b49 100644 (file)
 #define _LDB_H_ 1
 /*! \endcond */
 
+#include <stdbool.h>
+#include "talloc.h"
+#include "tevent.h"
+#include "ldb_errors.h"
+
 /*
   major restrictions as compared to normal LDAP:
 
-     - no async calls.
      - each record must have a unique key field
      - the key must be representable as a NULL terminated C string and may not 
        contain a comma or braces
 
   major restrictions as compared to tdb:
 
-     - no explicit locking calls
-     UPDATE: we have transactions now, better than locking --SSS.
+     - no explicit locking calls, but we have transactions when using ldb_tdb
 
 */
 
@@ -91,8 +94,8 @@ struct ldb_dn;
 
 /**
  There are a number of flags that are used with ldap_modify() in
- ldb_message_element.flags fields. The LDA_FLAGS_MOD_ADD,
- LDA_FLAGS_MOD_DELETE and LDA_FLAGS_MOD_REPLACE flags are used in
+ ldb_message_element.flags fields. The LDB_FLAGS_MOD_ADD,
+ LDB_FLAGS_MOD_DELETE and LDB_FLAGS_MOD_REPLACE flags are used in
  ldap_modify() calls to specify whether attributes are being added,
  deleted or modified respectively.
 */
@@ -181,6 +184,7 @@ enum ldb_scope {LDB_SCOPE_DEFAULT=-1,
                LDB_SCOPE_SUBTREE=2};
 
 struct ldb_context;
+struct tevent_context;
 
 /* debugging uses one of the following levels */
 enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, 
@@ -236,6 +240,17 @@ struct ldb_utf8_fns {
 */
 #define LDB_FLG_NOMMAP 8
 
+/**
+   Flag to tell ldif handlers not to force encoding of binary
+   structures in base64   
+*/
+#define LDB_FLG_SHOW_BINARY 16
+
+/**
+   Flags to enable ldb tracing
+*/
+#define LDB_FLG_ENABLE_TRACING 32
+
 /*
    structures for ldb_parse_tree handling code
 */
@@ -325,7 +340,6 @@ typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx,
   attribute handler structure
 
   attr                 -> The attribute name
-  flags                        -> LDB_ATTR_FLAG_*
   ldif_read_fn         -> convert from ldif to binary format
   ldif_write_fn                -> convert from binary to ldif format
   canonicalise_fn      -> canonicalise a value, for use by indexing and dn construction
@@ -349,6 +363,16 @@ struct ldb_schema_attribute {
 const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
                                                                const char *name);
 
+struct ldb_dn_extended_syntax {
+       const char *name;
+       ldb_attr_handler_t read_fn;
+       ldb_attr_handler_t write_clear_fn;
+       ldb_attr_handler_t write_hex_fn;
+};
+
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+                                                                   const char *name);
+
 /**
    The attribute is not returned by default
 */
@@ -362,6 +386,17 @@ const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_conte
 */
 #define LDB_ATTR_FLAG_FIXED        (1<<2) 
 
+/*
+  when this is set, attempts to create two records which have the same
+  value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS
+ */
+#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3)
+
+/*
+  when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION
+ */
+#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4)
+
 /**
   LDAP attribute syntax for a DN
 
@@ -389,6 +424,15 @@ const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_conte
 */
 #define LDB_SYNTAX_INTEGER              "1.3.6.1.4.1.1466.115.121.1.27"
 
+/**
+  LDAP attribute syntax for a boolean
+
+  This is the well-known LDAP attribute syntax for a boolean.
+
+  See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 
+*/
+#define LDB_SYNTAX_BOOLEAN              "1.3.6.1.4.1.1466.115.121.1.7"
+
 /**
   LDAP attribute syntax for an octet string
 
@@ -412,6 +456,14 @@ const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_conte
 /* sorting helpers */
 typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 
+/**
+   OID for the allowing client to request temporary relaxed 
+   enforcement of constraints of the x.500 model.
+
+   \sa <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>.
+*/
+#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
+
 /**
    OID for the paged results control. This control is included in the
    searchRequest and searchResultDone messages as part of the controls
@@ -457,6 +509,20 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 */
 #define LDB_CONTROL_SHOW_DELETED_OID   "1.2.840.113556.1.4.417"
 
+/**
+   OID for getting recycled objects
+
+   \sa <a href="http://msdn.microsoft.com/en-us/library/dd304621(PROT.13).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_SHOW_RECYCLED_OID         "1.2.840.113556.1.4.2064"
+
+/**
+   OID for getting deactivated linked attributes
+
+   \sa <a href="http://msdn.microsoft.com/en-us/library/dd302781(PROT.13).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065"
+
 /**
    OID for extended DN
 
@@ -530,21 +596,47 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 */
 #define LDB_CONTROL_PERMISSIVE_MODIFY_OID      "1.2.840.113556.1.4.1413"
 
+/** 
+    OID to allow the server to be more 'fast and loose' with the data being added.  
+
+    \sa 
+
+*/
+#define LDB_CONTROL_SERVER_LAZY_COMMIT   "1.2.840.113556.1.4.619"
+
+/**
+   OID for LDAP Extended Operation FAST_BIND
+
+   This Extended operations is used to perform a fast bind.
+*/
+#define LDB_EXTENDED_FAST_BIND_OID     "1.2.840.113556.1.4.1781"
+
 /**
    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.
+   This Extended operation is used to start a new TLS channel on top of a clear
+   text channel.
 */
 #define LDB_EXTENDED_START_TLS_OID     "1.3.6.1.4.1.1466.20037"
 
 /**
+   OID for LDAP Extended Operation DYNAMIC_REFRESH.
+
+   This Extended operation is used to create and maintain objects which exist
+   only a specific time, e.g. when a certain client or a certain person is
+   logged in. Data refreshes have to be periodically sent in a specific
+   interval. Otherwise the entry is going to be removed.
 */
 #define LDB_EXTENDED_DYNAMIC_OID       "1.3.6.1.4.1.1466.101.119.1"
 
-/**
+/*
+   OID for LDAP Extended Operation PASSWORD_CHANGE.
+
+   This Extended operation is used to allow user password changes by the user
+   itself.
 */
-#define LDB_EXTENDED_FAST_BIND_OID     "1.2.840.113556.1.4.1781"
+#define LDB_EXTENDED_PASSWORD_CHANGE_OID       "1.3.6.1.4.1.4203.1.11.1"
+
 
 struct ldb_sd_flags_control {
        /*
@@ -588,8 +680,8 @@ struct ldb_extended_dn_control {
 };
 
 struct ldb_server_sort_control {
-       char *attributeName;
-       char *orderingRule;
+       const char *attributeName;
+       const char *orderingRule;
        int reverse;
 };
 
@@ -651,7 +743,6 @@ enum ldb_request_type {
        LDB_DELETE,
        LDB_RENAME,
        LDB_EXTENDED,
-       LDB_SEQUENCE_NUMBER,
        LDB_REQ_REGISTER_CONTROL,
        LDB_REQ_REGISTER_PARTITION
 };
@@ -659,7 +750,6 @@ enum ldb_request_type {
 enum ldb_reply_type {
        LDB_REPLY_ENTRY,
        LDB_REPLY_REFERRAL,
-       LDB_REPLY_EXTENDED,
        LDB_REPLY_DONE
 };
 
@@ -679,28 +769,45 @@ struct ldb_extended {
        void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
 };
 
+#define LDB_EXTENDED_SEQUENCE_NUMBER   "1.3.6.1.4.1.7165.4.4.3"
+
+enum ldb_sequence_type {
+       LDB_SEQ_HIGHEST_SEQ,
+       LDB_SEQ_HIGHEST_TIMESTAMP,
+       LDB_SEQ_NEXT
+};
+
+#define LDB_SEQ_GLOBAL_SEQUENCE    0x01
+#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02
+
+struct ldb_seqnum_request {
+       enum ldb_sequence_type type;
+};
+
+struct ldb_seqnum_result {
+       uint64_t seq_num;
+       uint32_t flags;
+};
+
 struct ldb_result {
        unsigned int count;
        struct ldb_message **msgs;
-       char **refs;
        struct ldb_extended *extended;
        struct ldb_control **controls;
+       char **refs;
 };
 
 struct ldb_reply {
+       int error;
        enum ldb_reply_type type;
        struct ldb_message *message;
        struct ldb_extended *response;
-       char *referral;
        struct ldb_control **controls;
+       char *referral;
 };
 
-struct ldb_handle {
-       int status;
-       enum ldb_state state;
-       void *private_data;
-       struct ldb_module *module;
-};
+struct ldb_request;
+struct ldb_handle;
 
 struct ldb_search {
        struct ldb_dn *base;
@@ -735,19 +842,8 @@ 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 type;
-       uint64_t seq_num;
-       uint32_t flags;
-};
+typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *);
 
-typedef int (*ldb_request_callback_t)(struct ldb_context *, void *, struct ldb_reply *);
 struct ldb_request {
 
        enum ldb_request_type operation;
@@ -759,7 +855,6 @@ struct ldb_request {
                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;
        } op;
@@ -775,16 +870,19 @@ struct ldb_request {
 };
 
 int ldb_request(struct ldb_context *ldb, struct ldb_request *request);
+int ldb_request_done(struct ldb_request *req, int status);
+bool ldb_request_is_done(struct ldb_request *req);
 
+int ldb_modules_wait(struct ldb_handle *handle);
 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);
-struct event_context;
-void ldb_set_event_context(struct ldb_context *ldb, struct event_context *ev);
-struct event_context * ldb_get_event_context(struct ldb_context *ldb);
+struct tevent_context;
+void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev);
+struct tevent_context * ldb_get_event_context(struct ldb_context *ldb);
 
 /**
   Initialise ldbs' global information
@@ -806,7 +904,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(TALLOC_CTX *mem_ctx, struct event_context *ev_ctx);
+struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx);
 
 /**
    Connect to a database.
@@ -831,6 +929,19 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct event_context *ev_ctx);
    (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be
    created if it does not exist.
 */
+
+typedef void (*ldb_async_timeout_fn) (void *);
+typedef bool (*ldb_async_callback_fn) (void *);
+typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn);
+typedef int (*ldb_async_ctx_wait_op_fn)(void *);
+
+void ldb_async_ctx_set_private_data(struct ldb_context *ldb,
+                                       void *private_data);
+void ldb_async_ctx_set_add_op(struct ldb_context *ldb,
+                               ldb_async_ctx_add_op_fn add_op);
+void ldb_async_ctx_set_wait_op(struct ldb_context *ldb,
+                               ldb_async_ctx_wait_op_fn wait_op);
+
 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]);
 
 /*
@@ -860,13 +971,12 @@ struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
 /**
   The default async search callback function 
 
-  \param ldb the context associated with the database (from ldb_init())
-  \param context the callback context (struct ldb_result *)
+  \param req the request we are callback of
   \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
+  \note this function expects req->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.
@@ -875,7 +985,18 @@ struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
   request that can be freed as sson as the search request is finished)
 */
 
-int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares);
+int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares);
+
+/**
+  The default async extended operation callback function
+
+  \param req the request we are callback of
+  \param ares a single reply from the async core
+
+  \return result code (LDB_SUCCESS on success, or a failure code)
+*/
+int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares);
+
 
 /**
   Helper function to build a search request
@@ -889,7 +1010,8 @@ int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct l
   \param attrs the search attributes for the query (pass NULL if none required)
   \param controls an array of controls
   \param context the callback function context
-  \param callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -903,7 +1025,20 @@ int ldb_build_search_req(struct ldb_request **ret_req,
                        const char * const *attrs,
                        struct ldb_control **controls,
                        void *context,
-                       ldb_request_callback_t callback);
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
+
+int ldb_build_search_req_ex(struct ldb_request **ret_req,
+                       struct ldb_context *ldb,
+                       TALLOC_CTX *mem_ctx,
+                       struct ldb_dn *base,
+                       enum ldb_scope scope,
+                       struct ldb_parse_tree *tree,
+                       const char * const *attrs,
+                       struct ldb_control **controls,
+                       void *context,
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
 
 /**
   Helper function to build an add request
@@ -914,7 +1049,8 @@ int ldb_build_search_req(struct ldb_request **ret_req,
   \param message contains the entry to be added 
   \param controls an array of controls
   \param context the callback function context
-  \param callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -925,7 +1061,8 @@ int ldb_build_add_req(struct ldb_request **ret_req,
                        const struct ldb_message *message,
                        struct ldb_control **controls,
                        void *context,
-                       ldb_request_callback_t callback);
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
 
 /**
   Helper function to build a modify request
@@ -936,7 +1073,8 @@ int ldb_build_add_req(struct ldb_request **ret_req,
   \param message contains the entry to be modified
   \param controls an array of controls
   \param context the callback function context
-  \param callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -947,7 +1085,8 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
                        const struct ldb_message *message,
                        struct ldb_control **controls,
                        void *context,
-                       ldb_request_callback_t callback);
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
 
 /**
   Helper function to build a delete request
@@ -958,7 +1097,8 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
   \param dn the DN to be deleted
   \param controls an array of controls
   \param context the callback function context
-  \param callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -969,7 +1109,8 @@ int ldb_build_del_req(struct ldb_request **ret_req,
                        struct ldb_dn *dn,
                        struct ldb_control **controls,
                        void *context,
-                       ldb_request_callback_t callback);
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
 
 /**
   Helper function to build a rename request
@@ -981,7 +1122,8 @@ int ldb_build_del_req(struct ldb_request **ret_req,
   \param newdn the new DN
   \param controls an array of controls
   \param context the callback function context
-  \param callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -993,7 +1135,8 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
                        struct ldb_dn *newdn,
                        struct ldb_control **controls,
                        void *context,
-                       ldb_request_callback_t callback);
+                       ldb_request_callback_t callback,
+                       struct ldb_request *parent);
 
 /**
   Add a ldb_control to a ldb_request
@@ -1016,6 +1159,15 @@ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool criti
 */
 struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid);
 
+/**
+   check if a control with the specified "oid" exist and return it 
+  \param rep the reply 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_reply_get_control(struct ldb_reply *rep, const char *oid);
+
 /**
   Search the database
 
@@ -1023,31 +1175,21 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char
   records that match an LDAP-like search expression
 
   \param ldb the context associated with the database (from ldb_init())
+  \param mem_ctx the memory context to use for the request and the results
+  \param result the return result
   \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
   \param attrs the search attributes for the query (pass NULL if none required)
-  \param res the return result
+  \param exp_fmt the search expression to use for this query (printf like)
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 
   \note use talloc_free() to free the ldb_result returned
 */
-int ldb_search(struct ldb_context *ldb, 
-              struct ldb_dn *base,
-              enum ldb_scope scope,
-              const char *expression,
-              const char * const *attrs, struct ldb_result **res);
-
-/*
- * a useful search function where you can easily define the expression and
- * that takes a memory context where results are allocated
-*/
-
-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);
+int ldb_search(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.
@@ -1113,13 +1255,12 @@ 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 req the request we are callback of
   \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
+  \note this function expects req->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.
@@ -1127,7 +1268,9 @@ int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn);
   (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);
+
+int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares);
+
 
 /**
   Helper function to build a extended request
@@ -1140,7 +1283,8 @@ int ldb_extended_default_callback(struct ldb_context *ldb, void *context, struct
   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 callback the callback function to handle the async replies
+  \param the callback function to handle the async replies
+  \param the parent request if any
 
   \return result code (LDB_SUCCESS on success, or a failure code)
 */
@@ -1151,7 +1295,8 @@ int ldb_build_extended_req(struct ldb_request **ret_req,
                           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);
+                          ldb_request_callback_t callback,
+                          struct ldb_request *parent);
 
 /**
   call an extended operation
@@ -1172,11 +1317,21 @@ int ldb_extended(struct ldb_context *ldb,
                 void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
                 struct ldb_result **res);
 
+/**
+  Obtain current/next database sequence number
+*/
+int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num);
+
 /**
   start a transaction
 */
 int ldb_transaction_start(struct ldb_context *ldb);
 
+/**
+   first phase of two phase commit
+ */
+int ldb_transaction_prepare_commit(struct ldb_context *ldb);
+
 /**
   commit a transaction
 */
@@ -1187,6 +1342,12 @@ int ldb_transaction_commit(struct ldb_context *ldb);
 */
 int ldb_transaction_cancel(struct ldb_context *ldb);
 
+/*
+  cancel a transaction with no error if no transaction is pending
+  used when we fork() to clear any parent transactions
+*/
+int ldb_transaction_cancel_noerr(struct ldb_context *ldb);
+
 
 /**
   return extended error information from the last call
@@ -1349,6 +1510,32 @@ struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s);
 */
 int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg);
 
+/**
+   Write an LDIF message to a string
+
+   \param ldb the ldb context (from ldb_init())
+   \param mem_ctx the talloc context on which to attach the string)
+   \param msg the message to write out
+
+   \return the string containing the LDIF, or NULL on error
+
+   \sa ldb_ldif_read_string for the reader equivalent to this function.
+*/
+char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 
+                         const struct ldb_ldif *msg);
+
+
+/*
+   Produce a string form of an ldb message
+
+   convenient function to turn a ldb_message into a string. Useful for
+   debugging
+ */
+char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 
+                             enum ldb_changetype changetype,
+                             const struct ldb_message *msg);
+
+
 /**
    Base64 encode a buffer
 
@@ -1379,15 +1566,82 @@ int ldb_base64_decode(char *s);
 
 /* The following definitions come from lib/ldb/common/ldb_dn.c  */
 
+/**
+  Get the linear form of a DN (without any extended components)
+  
+  \param dn The DN to linearize
+*/
+
+const char *ldb_dn_get_linearized(struct ldb_dn *dn);
+
+/**
+  Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context 
+  
+  \param dn The DN to linearize
+  \param mem_ctx TALLOC context to return result on
+*/
+
+char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+
+/**
+  Get the linear form of a DN (with any extended components)
+  
+  \param mem_ctx TALLOC context to return result on
+  \param dn The DN to linearize
+  \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form)
+*/
+char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode);
+const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name);
+int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val);
+
+void ldb_dn_remove_extended_components(struct ldb_dn *dn);
+bool ldb_dn_has_extended(struct ldb_dn *dn);
+
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb, 
+                              unsigned flags,
+                              const struct ldb_dn_extended_syntax *syntax);
+
+/** 
+  Allocate a new DN from a string
+
+  \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+  \param dn The new DN 
+
+  \note The DN will not be parsed at this time.  Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
 struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn);
+/** 
+  Allocate a new DN from a printf style format string and arguments
+
+  \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+  \param new_fms The new DN as a format string (plus arguments)
+
+  \note The DN will not be parsed at this time.  Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
 struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4);
+/** 
+  Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun)
+
+  \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+  \param dn The new DN 
+
+  \note The DN will not be parsed at this time.  Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
+
+/**
+  Determine if this DN is syntactically valid 
+
+  \param dn The DN to validate
+*/
+
 bool ldb_dn_validate(struct ldb_dn *dn);
 
 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(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);
@@ -1498,6 +1752,8 @@ int ldb_msg_add_steal_string(struct ldb_message *msg,
                             const char *attr_name, char *str);
 int ldb_msg_add_string(struct ldb_message *msg, 
                       const char *attr_name, const char *str);
+int ldb_msg_add_dn(struct ldb_message *msg, const char *attr_name,
+                  struct ldb_dn *dn);
 int ldb_msg_add_fmt(struct ldb_message *msg, 
                    const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
 
@@ -1506,6 +1762,8 @@ int ldb_msg_add_fmt(struct ldb_message *msg,
 */
 int ldb_msg_element_compare(struct ldb_message_element *el1, 
                            struct ldb_message_element *el2);
+int ldb_msg_element_compare_name(struct ldb_message_element *el1, 
+                                struct ldb_message_element *el2);
 
 /**
    Find elements in a message.
@@ -1557,6 +1815,15 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
                                 struct ldb_message *msg1,
                                 struct ldb_message *msg2);
 
+/**
+   Tries to find a certain string attribute in a message
+
+   \param msg the message to check
+   \param name attribute name
+   \param value attribute value
+
+   \return 1 on match and 0 otherwise.
+*/
 int ldb_msg_check_string_attribute(const struct ldb_message *msg,
                                   const char *name,
                                   const char *value);
@@ -1619,14 +1886,22 @@ 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);
 
+int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace);
+int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace);
+void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr);
+void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el);
+
 
 void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, 
                                 const char *attr, 
                                 const char *replace);
 
-int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace);
-int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace);
-void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr);
+/*
+  shallow copy a tree - copying only the elements array so that the caller
+  can safely add new elements without changing the message
+*/
+struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx,
+                                                  const struct ldb_parse_tree *ot);
 
 /**
    Convert a time structure to a string
@@ -1695,4 +1970,20 @@ void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque
 */
 struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings);
 
+/**
+   return the ldb flags 
+*/
+unsigned int ldb_get_flags(struct ldb_context *ldb);
+
+/* set the ldb flags */
+void ldb_set_flags(struct ldb_context *ldb, unsigned flags);
+
+
+struct ldb_dn *ldb_dn_binary_from_ldb_val(void *mem_ctx,
+                                         struct ldb_context *ldb,
+                                         const struct ldb_val *strdn);
+
+int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val);
+int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val);
+
 #endif