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
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/>.
*/
/*
struct ldb_dn *dn;
unsigned int num_elements;
struct ldb_message_element *elements;
- void *private_data; /* private to the backend */
};
enum ldb_changetype {
*/
#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
*/
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
*/
#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"
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;
};
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 {
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;
};
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;
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 {
};
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;
};
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;
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
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)
\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
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,
\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
\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
\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
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);
\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
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
\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.
\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
\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
*/
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
\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);
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);
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);
/**
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
/**
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
*/
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