s4-ldb: added an environment varibale LDB_WARN_UNINDEXED
[kai/samba.git] / source4 / lib / ldb / include / ldb.h
index b1ce3ef70b2a7073a65b6cad98bc59cc49566abd..1deed84550c8818f98bac75a143dd98e44812f5b 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
 
 */
 
@@ -83,6 +86,14 @@ struct ldb_val {
 #ifndef PRINTF_ATTRIBUTE
 #define PRINTF_ATTRIBUTE(a,b)
 #endif
+
+#ifndef _DEPRECATED_
+#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
+#endif
 /*! \endcond */
 
 /* opaque ldb_dn structures, see ldb_dn.c for internals */
@@ -91,13 +102,18 @@ 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.
 */
 #define LDB_FLAG_MOD_MASK  0x3
 
+/**
+  use this to extract the mod type from the operation
+ */
+#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK)
+
 /**
    Flag value used in ldap_modify() to indicate that attributes are
    being added.
@@ -122,6 +138,11 @@ struct ldb_dn;
 */
 #define LDB_FLAG_MOD_DELETE  3
 
+/**
+    flag bits on an element usable only by the internal implementation
+*/
+#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0
+
 /**
   OID for logic AND comaprison.
 
@@ -181,7 +202,7 @@ enum ldb_scope {LDB_SCOPE_DEFAULT=-1,
                LDB_SCOPE_SUBTREE=2};
 
 struct ldb_context;
-struct event_context;
+struct tevent_context;
 
 /* debugging uses one of the following levels */
 enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, 
@@ -237,6 +258,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
 */
@@ -282,7 +314,7 @@ struct ldb_parse_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);
+char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree);
 
 /**
    Encode a binary blob
@@ -321,12 +353,15 @@ char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string);
 */
 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 *);
+struct ldb_schema_attribute;
+typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation,
+                                  const struct ldb_schema_attribute *a,
+                                  const struct ldb_val *, const struct ldb_val *, bool *matched);
 
 /*
   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
@@ -339,6 +374,7 @@ struct ldb_schema_syntax {
        ldb_attr_handler_t ldif_write_fn;
        ldb_attr_handler_t canonicalise_fn;
        ldb_attr_comparison_t comparison_fn;
+       ldb_attr_operator_t operator_fn;
 };
 
 struct ldb_schema_attribute {
@@ -350,6 +386,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
 */
@@ -363,6 +409,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
 
@@ -390,6 +447,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
 
@@ -413,6 +479,45 @@ 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);
 
+/* Individual controls */
+
+/**
+  OID for getting and manipulating attributes from the ldb
+  without interception in the operational module.
+  It can be used to access attribute that used to be stored in the sam 
+  and that are now calculated.
+*/
+#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13"
+
+/**
+  OID for recalculate SD control. This control force the
+  dsdb code to recalculate the SD of the object as if the
+  object was just created.
+
+*/
+#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5"
+
+/**
+   REVEAL_INTERNALS is used to reveal internal attributes and DN
+   components which are not normally shown to the user
+*/
+#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6"
+
+/**
+   LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations
+   that are performed by the system, but with a user's credentials, e.g.
+   updating prefix map
+*/
+#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7"
+
+/**
+   LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is
+   mainly thought to be used for the provisioning.
+*/
+#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16"
+
+/* AD controls */
+
 /**
    OID for the paged results control. This control is included in the
    searchRequest and searchResultDone messages as part of the controls
@@ -451,6 +556,13 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 */
 #define LDB_CONTROL_NOTIFICATION_OID   "1.2.840.113556.1.4.528"
 
+/**
+   OID for performing subtree deletes
+
+   \sa <a href="http://msdn.microsoft.com/en-us/library/aa366991(v=VS.85).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_TREE_DELETE_OID    "1.2.840.113556.1.4.805"
+
 /**
    OID for getting deleted objects
 
@@ -458,6 +570,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
 
@@ -531,22 +657,75 @@ 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 <a href="http://msdn.microsoft.com/en-us/library/aa366982(v=VS.85).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_SERVER_LAZY_COMMIT   "1.2.840.113556.1.4.619"
+
 /**
-   OID for LDAP Extended Operation START_TLS.
+   Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23
 
-   This Extended operation is used to start a new TLS
-   channel on top of a clear text channel.
+   \sa <a href="">Microsoft documentation of this OID</a>
 */
-#define LDB_EXTENDED_START_TLS_OID     "1.3.6.1.4.1.1466.20037"
+#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341"
+
+/* Other standardised controls */
+
+/**
+   OID for the allowing client to request temporary relaxed
+   enforcement of constraints of the x.500 model.
+
+   Mainly used for the OpenLDAP backend.
+
+   \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"
+
+/* Extended operations */
 
 /**
+   OID for LDAP Extended Operation SEQUENCE_NUMBER
+
+   This extended operation is used to retrieve the extended sequence number.
 */
-#define LDB_EXTENDED_DYNAMIC_OID       "1.3.6.1.4.1.1466.101.119.1"
+#define LDB_EXTENDED_SEQUENCE_NUMBER   "1.3.6.1.4.1.7165.4.4.3"
 
 /**
+   OID for LDAP Extended Operation PASSWORD_CHANGE.
+
+   This Extended operation is used to allow user password changes by the user
+   itself.
+*/
+#define LDB_EXTENDED_PASSWORD_CHANGE_OID       "1.3.6.1.4.1.4203.1.11.1"
+
+
+/**
+   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.
+*/
+#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"
+
 struct ldb_sd_flags_control {
        /*
         * request the owner    0x00000001
@@ -589,8 +768,8 @@ struct ldb_extended_dn_control {
 };
 
 struct ldb_server_sort_control {
-       char *attributeName;
-       char *orderingRule;
+       const char *attributeName;
+       const char *orderingRule;
        int reverse;
 };
 
@@ -652,7 +831,6 @@ enum ldb_request_type {
        LDB_DELETE,
        LDB_RENAME,
        LDB_EXTENDED,
-       LDB_SEQUENCE_NUMBER,
        LDB_REQ_REGISTER_CONTROL,
        LDB_REQ_REGISTER_PARTITION
 };
@@ -679,21 +857,39 @@ struct ldb_extended {
        void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
 };
 
+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;
-       int error;
+       char *referral;
 };
 
 struct ldb_request;
@@ -732,18 +928,6 @@ 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 *);
 
 struct ldb_request {
@@ -757,7 +941,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;
@@ -783,9 +966,9 @@ int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeou
 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
@@ -807,7 +990,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.
@@ -900,6 +1083,7 @@ int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares)
 */
 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares);
 
+int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares);
 
 /**
   Helper function to build a search request
@@ -1053,6 +1237,18 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
 */
 int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data);
 
+/**
+  replace a ldb_control in a ldb_request
+
+  \param req the request struct where to add the control
+  \param oid the object identifier of the control as string
+  \param critical 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_replace_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
@@ -1062,6 +1258,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
 
@@ -1211,11 +1416,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
 */
@@ -1226,6 +1441,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
@@ -1388,6 +1609,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
 
@@ -1418,15 +1665,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(TALLOC_CTX *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_extended_filter(struct ldb_dn *dn, const char * const *accept);
+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);
-struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
+/** 
+  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(TALLOC_CTX *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);
@@ -1454,6 +1768,7 @@ 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);
+int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn);
 
 
 /**
@@ -1537,6 +1852,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_linearized_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);
 
@@ -1545,6 +1862,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.
@@ -1588,14 +1907,66 @@ struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx,
 struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, 
                                 const struct ldb_message *msg);
 
+/*
+ * ldb_msg_canonicalize() is now depreciated
+ * Please use ldb_msg_normalize() instead
+ *
+ * NOTE: Returned ldb_message object is allocated
+ * into *ldb's context. Callers are recommended
+ * to steal the returned object into a TALLOC_CTX
+ * with short lifetime.
+ */
 struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 
-                                        const struct ldb_message *msg);
+                                        const struct ldb_message *msg) _DEPRECATED_;
+
+int ldb_msg_normalize(struct ldb_context *ldb,
+                     TALLOC_CTX *mem_ctx,
+                     const struct ldb_message *msg,
+                     struct ldb_message **_msg_out);
 
 
+/*
+ * ldb_msg_diff() is now depreciated
+ * Please use ldb_msg_difference() instead
+ *
+ * NOTE: Returned ldb_message object is allocated
+ * into *ldb's context. Callers are recommended
+ * to steal the returned object into a TALLOC_CTX
+ * with short lifetime.
+ */
 struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, 
                                 struct ldb_message *msg1,
-                                struct ldb_message *msg2);
+                                struct ldb_message *msg2) _DEPRECATED_;
+
+/**
+ * return a ldb_message representing the differences between msg1 and msg2.
+ * If you then use this in a ldb_modify() call,
+ * it can be used to save edits to a message
+ *
+ * Result message is constructed as follows:
+ * - LDB_FLAG_MOD_ADD     - elements found only in msg2
+ * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have
+ *                         different value in msg1
+ *                          Value for msg2 element is used
+ * - LDB_FLAG_MOD_DELETE  - elements found only in msg2
+ *
+ * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR
+ */
+int ldb_msg_difference(struct ldb_context *ldb,
+                      TALLOC_CTX *mem_ctx,
+                      struct ldb_message *msg1,
+                      struct ldb_message *msg2,
+                      struct ldb_message **_msg_out);
+
+/**
+   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);
@@ -1658,14 +2029,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
@@ -1693,6 +2072,12 @@ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t);
 */
 time_t ldb_string_to_time(const char *s);
 
+/**
+  convert a LDAP GeneralizedTime string in ldb_val format to a
+  time_t.
+*/
+int ldb_val_to_time(const struct ldb_val *v, time_t *t);
+
 /**
    Convert a time structure to a string
 
@@ -1722,6 +2107,35 @@ 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);
 
+#ifndef discard_const
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+#endif
+
+/*
+  a wrapper around ldb_qsort() that ensures the comparison function is
+  type safe. This will produce a compilation warning if the types
+  don't match
+ */
+#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison)    \
+do { \
+       if (numel > 1) { \
+               ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \
+               comparison(&((base)[0]), &((base)[1]), opaque);         \
+       } \
+} while (0)
+
+/* allow ldb to also call TYPESAFE_QSORT() */
+#ifndef TYPESAFE_QSORT
+#define TYPESAFE_QSORT(base, numel, comparison) \
+do { \
+       if (numel > 1) { \
+               qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \
+               comparison(&((base)[0]), &((base)[1])); \
+       } \
+} while (0)
+#endif
+
+
 
 /**
    Convert an array of string represention of a control into an array of ldb_control structures 
@@ -1734,4 +2148,27 @@ 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(TALLOC_CTX *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);
+
+/* debugging functions for ldb requests */
+void ldb_req_set_location(struct ldb_request *req, const char *location);
+const char *ldb_req_location(struct ldb_request *req);
+
+/* set the location marker on a request handle - used for debugging */
+#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__)
+
 #endif