diffstat for ldb-1.1.13 ldb-1.1.15 ABI/ldb-1.1.14.sigs | 262 +++++++++ ABI/ldb-1.1.15.sigs | 262 +++++++++ ABI/pyldb-util-1.1.14.sigs | 2 ABI/pyldb-util-1.1.15.sigs | 2 buildtools/wafadmin/Tools/python.py | 2 buildtools/wafadmin/Utils.py | 4 buildtools/wafsamba/nothreads.py | 6 buildtools/wafsamba/samba_abi.py | 34 - buildtools/wafsamba/samba_autoconf.py | 12 buildtools/wafsamba/samba_bundled.py | 6 buildtools/wafsamba/samba_deps.py | 8 buildtools/wafsamba/samba_dist.py | 4 buildtools/wafsamba/samba_headers.py | 1 buildtools/wafsamba/samba_install.py | 2 buildtools/wafsamba/samba_optimisation.py | 2 buildtools/wafsamba/samba_patterns.py | 2 buildtools/wafsamba/samba_pidl.py | 26 buildtools/wafsamba/samba_utils.py | 17 buildtools/wafsamba/samba_version.py | 2 buildtools/wafsamba/stale_files.py | 2 buildtools/wafsamba/symbols.py | 2 buildtools/wafsamba/tests/test_abi.py | 67 ++ buildtools/wafsamba/wafsamba.py | 19 buildtools/wafsamba/wscript | 15 common/ldb.c | 3 common/ldb_ldif.c | 2 common/ldb_pack.c | 287 ++++++++++ debian/changelog | 12 debian/control | 5 debian/libldb1.symbols | 21 debian/patches/01_exclude_symbols | 24 debian/patches/series | 1 debian/python-ldb.symbols | 12 include/ldb.h | 25 include/ldb_private.h | 11 ldb_tdb/ldb_index.c | 3 ldb_tdb/ldb_pack.c | 292 ---------- ldb_tdb/ldb_search.c | 7 ldb_tdb/ldb_tdb.c | 5 ldb_tdb/ldb_tdb.h | 11 lib/replace/README | 2 lib/replace/getpass.c | 218 -------- lib/replace/getpass.m4 | 24 lib/replace/libreplace.m4 | 58 +- lib/replace/poll.c | 4 lib/replace/replace-test.h | 4 lib/replace/replace-testsuite.h | 10 lib/replace/replace.c | 24 lib/replace/replace.h | 65 +- lib/replace/snprintf.c | 5 lib/replace/system/passwd.h | 11 lib/replace/system/wait.h | 4 lib/replace/test/main.c | 4 lib/replace/test/testsuite.c | 13 lib/replace/wscript | 87 ++- lib/replace/xattr.c | 15 lib/talloc/ABI/pytalloc-util-2.0.8.sigs | 6 lib/talloc/ABI/talloc-2.0.8.sigs | 63 ++ lib/talloc/man/talloc.3.xml | 813 ++++++++++++++++++++++++++++++ lib/talloc/talloc.3.xml | 801 ----------------------------- lib/talloc/talloc.c | 314 ++++++++++- lib/talloc/talloc.h | 19 lib/talloc/testsuite.c | 172 ++++++ lib/talloc/wscript | 4 lib/tdb/ABI/tdb-1.2.11.sigs | 67 ++ lib/tdb/common/dump.c | 10 lib/tdb/common/error.c | 2 lib/tdb/common/freelist.c | 26 lib/tdb/common/io.c | 50 + lib/tdb/common/lock.c | 82 +-- lib/tdb/common/open.c | 45 + lib/tdb/common/rescue.c | 349 ++++++++++++ lib/tdb/common/summary.c | 4 lib/tdb/common/tdb.c | 20 lib/tdb/common/tdb_private.h | 2 lib/tdb/common/transaction.c | 74 +- lib/tdb/common/traverse.c | 16 lib/tdb/include/tdb.h | 32 + lib/tdb/libtdb.m4 | 2 lib/tdb/man/tdbbackup.8.xml | 136 +++++ lib/tdb/man/tdbdump.8.xml | 92 +++ lib/tdb/man/tdbrestore.8.xml | 66 ++ lib/tdb/man/tdbtool.8.xml | 235 ++++++++ lib/tdb/manpages/tdbbackup.8.xml | 136 ----- lib/tdb/manpages/tdbdump.8.xml | 61 -- lib/tdb/manpages/tdbrestore.8.xml | 66 -- lib/tdb/manpages/tdbtool.8.xml | 235 -------- lib/tdb/pytdb.c | 17 lib/tdb/test/run-rescue-find_entry.c | 50 + lib/tdb/test/run-rescue.c | 126 ++++ lib/tdb/tools/tdbdump.c | 62 ++ lib/tdb/tools/tdbtorture.c | 4 lib/tdb/wscript | 18 lib/tevent/tevent_liboop.c | 2 lib/tevent/tevent_signal.c | 29 + man/ldb.3.xml | 3 man/ldbadd.1.xml | 5 man/ldbdel.1.xml | 5 man/ldbedit.1.xml | 5 man/ldbmodify.1.xml | 5 man/ldbrename.1.xml | 5 man/ldbsearch.1.xml | 5 tools/ldbdump.c | 230 ++++++++ wscript | 10 104 files changed, 4295 insertions(+), 2316 deletions(-) diff -Nru ldb-1.1.13/ABI/ldb-1.1.14.sigs ldb-1.1.15/ABI/ldb-1.1.14.sigs --- ldb-1.1.13/ABI/ldb-1.1.14.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/ABI/ldb-1.1.14.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff -Nru ldb-1.1.13/ABI/ldb-1.1.15.sigs ldb-1.1.15/ABI/ldb-1.1.15.sigs --- ldb-1.1.13/ABI/ldb-1.1.15.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/ABI/ldb-1.1.15.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff -Nru ldb-1.1.13/ABI/pyldb-util-1.1.14.sigs ldb-1.1.15/ABI/pyldb-util-1.1.14.sigs --- ldb-1.1.13/ABI/pyldb-util-1.1.14.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/ABI/pyldb-util-1.1.14.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff -Nru ldb-1.1.13/ABI/pyldb-util-1.1.15.sigs ldb-1.1.15/ABI/pyldb-util-1.1.15.sigs --- ldb-1.1.13/ABI/pyldb-util-1.1.15.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/ABI/pyldb-util-1.1.15.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff -Nru ldb-1.1.13/buildtools/wafadmin/Tools/python.py ldb-1.1.15/buildtools/wafadmin/Tools/python.py --- ldb-1.1.13/buildtools/wafadmin/Tools/python.py 2012-08-06 08:57:44.000000000 +0000 +++ ldb-1.1.15/buildtools/wafadmin/Tools/python.py 2013-01-27 11:51:43.000000000 +0000 @@ -259,7 +259,7 @@ includes = [] if python_config: - for incstr in Utils.cmd_output("%s %s --includes" % (python, python_config)).strip().split(): + for incstr in Utils.cmd_output("%s --includes" % (python_config,)).strip().split(): # strip the -I or /I if (incstr.startswith('-I') or incstr.startswith('/I')): diff -Nru ldb-1.1.13/buildtools/wafadmin/Utils.py ldb-1.1.15/buildtools/wafadmin/Utils.py --- ldb-1.1.13/buildtools/wafadmin/Utils.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafadmin/Utils.py 2013-01-27 11:51:43.000000000 +0000 @@ -15,7 +15,7 @@ import stat def h_file(filename): - st = os.stat(filename) + st = os.lstat(filename) if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file') m = Utils.md5() m.update(str(st.st_mtime)) @@ -419,7 +419,7 @@ def check_dir(dir): """If a folder doesn't exists, create it.""" try: - os.stat(dir) + os.lstat(dir) except OSError: try: os.makedirs(dir) diff -Nru ldb-1.1.13/buildtools/wafsamba/nothreads.py ldb-1.1.15/buildtools/wafsamba/nothreads.py --- ldb-1.1.13/buildtools/wafsamba/nothreads.py 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/nothreads.py 2013-01-27 11:51:43.000000000 +0000 @@ -132,8 +132,10 @@ self.frozen = [] elif not self.count: (jobs, tmp) = self.manager.get_next_set() - if jobs != None: self.maxjobs = jobs - if tmp: self.outstanding += tmp + if jobs is not None: + self.maxjobs = jobs + if tmp: + self.outstanding += tmp break def get_out(self): diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_abi.py ldb-1.1.15/buildtools/wafsamba/samba_abi.py --- ldb-1.1.13/buildtools/wafsamba/samba_abi.py 2012-09-07 14:47:16.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_abi.py 2013-01-27 11:51:43.000000000 +0000 @@ -152,22 +152,23 @@ symmap[symname] = version f.close() -def abi_write_vscript(vscript, libname, current_version, versions, symmap, abi_match): - '''write a vscript file for a library in --version-script format - - :param vscript: Path to the vscript file + +def abi_write_vscript(f, libname, current_version, versions, symmap, abi_match): + """Write a vscript file for a library in --version-script format. + + :param f: File-like object to write to :param libname: Name of the library, uppercased :param current_version: Current version :param versions: Versions to consider :param symmap: Dictionary mapping symbols -> version - :param abi_match: List of symbols considered to be public in the current version - ''' + :param abi_match: List of symbols considered to be public in the current + version + """ invmap = {} for s in symmap: invmap.setdefault(symmap[s], []).append(s) - f = open(vscript, mode='w') last_key = "" versions = sorted(versions, key=version_key) for k in versions: @@ -175,8 +176,8 @@ if symver == current_version: break f.write("%s {\n" % symver) - if k in invmap: - f.write("\tglobal: \n") + if k in sorted(invmap.keys()): + f.write("\tglobal:\n") for s in invmap.get(k, []): f.write("\t\t%s;\n" % s); f.write("}%s;\n\n" % last_key) @@ -190,14 +191,13 @@ f.write("\t\t%s;\n" % x) else: f.write("\t\t*;\n") - if len(local_abi) > 0: + if abi_match != ["*"]: f.write("\tlocal:\n") for x in local_abi: f.write("\t\t%s;\n" % x[1:]) - elif abi_match != ["*"]: - f.write("\tlocal: *;\n") + if len(global_abi) > 0: + f.write("\t\t*;\n") f.write("};\n") - f.close() def abi_build_vscript(task): @@ -213,8 +213,12 @@ version = basename[len(task.env.LIBNAME)+1:-len(".sigs")] versions.append(version) abi_process_file(fname, version, symmap) - abi_write_vscript(tgt, task.env.LIBNAME, task.env.VERSION, versions, symmap, - task.env.ABI_MATCH) + f = open(tgt, mode='w') + try: + abi_write_vscript(f, task.env.LIBNAME, task.env.VERSION, versions, + symmap, task.env.ABI_MATCH) + finally: + f.close() def ABI_VSCRIPT(bld, libname, abi_directory, version, vscript, abi_match=None): diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_autoconf.py ldb-1.1.15/buildtools/wafsamba/samba_autoconf.py --- ldb-1.1.13/buildtools/wafsamba/samba_autoconf.py 2012-08-28 09:36:26.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_autoconf.py 2013-01-27 11:51:43.000000000 +0000 @@ -62,9 +62,9 @@ conf.check_message_1 = conf.saved_check_message_1 conf.check_message_2 = conf.saved_check_message_2 p = conf.check_message_2 - if result == True: - p('ok ') - elif result == False: + if result is True: + p('ok') + elif not result: p('not found', 'YELLOW') else: p(result) @@ -241,7 +241,7 @@ conf.COMPOUND_START('Checking for %s' % f) - if link is None or link == True: + if link is None or link: ret = CHECK_CODE(conf, # this is based on the autoconf strategy ''' @@ -284,7 +284,7 @@ headers=headers, msg='Checking for macro %s' % f) - if not ret and (link is None or link == False): + if not ret and (link is None or not link): ret = CHECK_VARIABLE(conf, f, define=define, headers=headers, @@ -470,7 +470,7 @@ if option not in conf.env: return False v = conf.env[option] - if v == None: + if v is None: return False if v == []: return False diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_bundled.py ldb-1.1.15/buildtools/wafsamba/samba_bundled.py --- ldb-1.1.13/buildtools/wafsamba/samba_bundled.py 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_bundled.py 2013-01-27 11:51:43.000000000 +0000 @@ -30,8 +30,6 @@ def BUILTIN_LIBRARY(bld, name): '''return True if a library should be builtin instead of being built as a shared lib''' - if bld.env.DISABLE_SHARED: - return True return target_in_list(name, bld.env.BUILTIN_LIBRARIES, False) Build.BuildContext.BUILTIN_LIBRARY = BUILTIN_LIBRARY @@ -78,7 +76,7 @@ @conf def LIB_MUST_BE_BUNDLED(conf, libname): - return ('ALL' in conf.env.BUNDLED_LIBS or + return ('ALL' in conf.env.BUNDLED_LIBS or libname in conf.env.BUNDLED_LIBS) @conf @@ -249,8 +247,6 @@ def NONSHARED_BINARY(bld, name): '''return True if a binary should be built without non-system shared libs''' - if bld.env.DISABLE_SHARED: - return True return target_in_list(name, bld.env.NONSHARED_BINARIES, False) Build.BuildContext.NONSHARED_BINARY = NONSHARED_BINARY diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_deps.py ldb-1.1.15/buildtools/wafsamba/samba_deps.py --- ldb-1.1.13/buildtools/wafsamba/samba_deps.py 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_deps.py 2013-01-27 11:51:43.000000000 +0000 @@ -136,7 +136,7 @@ includes = [] # maybe add local includes - if getattr(self, 'local_include', True) == True and getattr(self, 'local_include_first', True): + if getattr(self, 'local_include', True) and getattr(self, 'local_include_first', True): includes.append('.') includes.extend(self.samba_includes_extended) @@ -153,7 +153,7 @@ t = bld.name_to_obj(d, bld.env) bld.ASSERT(t is not None, "Unable to find dependency %s for %s" % (d, self.sname)) inclist = getattr(t, 'samba_includes_extended', [])[:] - if getattr(t, 'local_include', True) == True: + if getattr(t, 'local_include', True): inclist.append('.') if inclist == []: continue @@ -169,7 +169,7 @@ relpath = os_path_relpath(inc, mypath) includes.append(relpath) - if getattr(self, 'local_include', True) == True and not getattr(self, 'local_include_first', True): + if getattr(self, 'local_include', True) and not getattr(self, 'local_include_first', True): includes.append('.') # now transform the includes list to be relative to the top directory @@ -306,7 +306,7 @@ debug('deps: checking for orphaned targets') for t in tgt_list: - if getattr(t, 'samba_used', False) == True: + if getattr(t, 'samba_used', False): continue type = target_dict[t.sname] if not type in ['BINARY', 'LIBRARY', 'MODULE', 'ET', 'PYTHON']: diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_dist.py ldb-1.1.15/buildtools/wafsamba/samba_dist.py --- ldb-1.1.13/buildtools/wafsamba/samba_dist.py 2012-09-12 21:53:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_dist.py 2013-01-27 11:51:43.000000000 +0000 @@ -98,10 +98,10 @@ return Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env).split() -def dist(appname='',version=''): +def dist(appname='', version=''): def add_files_to_tarball(tar, srcdir, srcsubdir, dstdir, dstsubdir, blacklist, files): - if blacklist == None: + if blacklist is None: blacklist = [] for f in files: abspath = os.path.join(srcdir, f) diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_headers.py ldb-1.1.15/buildtools/wafsamba/samba_headers.py --- ldb-1.1.13/buildtools/wafsamba/samba_headers.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_headers.py 2013-01-27 11:51:43.000000000 +0000 @@ -119,7 +119,6 @@ h_name = h inst_name = os.path.basename(h) bld.INSTALL_FILES('${INCLUDEDIR}', h_name, destname=inst_name) - def PUBLIC_HEADERS(bld, public_headers, header_path=None, public_headers_install=True): diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_install.py ldb-1.1.15/buildtools/wafsamba/samba_install.py --- ldb-1.1.13/buildtools/wafsamba/samba_install.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_install.py 2013-01-27 11:51:43.000000000 +0000 @@ -103,6 +103,8 @@ if getattr(self, 'samba_realname', None): install_name = self.samba_realname install_link = None + if getattr(self, 'soname', ''): + install_link = self.soname if getattr(self, 'samba_type', None) == 'PYTHON': inst_name = bld.make_libname(t.target, nolibprefix=True, python=True) else: diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_optimisation.py ldb-1.1.15/buildtools/wafsamba/samba_optimisation.py --- ldb-1.1.13/buildtools/wafsamba/samba_optimisation.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_optimisation.py 2013-01-27 11:51:43.000000000 +0000 @@ -31,7 +31,7 @@ for path in self.to_list(self.includes): if not path in lst: - if preproc.go_absolute or path[0] != '/': #os.path.isabs(path): + if preproc.go_absolute or path[0] != '/': # os.path.isabs(path): lst.append(path) else: self.env.prepend_value('CPPPATH', path) diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_patterns.py ldb-1.1.15/buildtools/wafsamba/samba_patterns.py --- ldb-1.1.13/buildtools/wafsamba/samba_patterns.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_patterns.py 2013-01-27 11:51:43.000000000 +0000 @@ -21,7 +21,7 @@ def SAMBA_MKVERSION(bld, target): '''generate the version.h header for Samba''' - t = bld.SAMBA_GENERATOR('VERSION', + t = bld.SAMBA_GENERATOR('VERSION', rule=write_version_header, source= 'VERSION', target=target, diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_pidl.py ldb-1.1.15/buildtools/wafsamba/samba_pidl.py --- ldb-1.1.13/buildtools/wafsamba/samba_pidl.py 2012-04-11 12:36:11.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_pidl.py 2013-01-27 11:51:43.000000000 +0000 @@ -7,7 +7,6 @@ def SAMBA_PIDL(bld, pname, source, options='', output_dir='.', - symlink=False, generate_tables=True): '''Build a IDL file using pidl. This will produce up to 13 output files depending on the options used''' @@ -91,27 +90,7 @@ t.env.PIDL = os.path.join(bld.srcnode.abspath(), 'pidl/pidl') t.env.OPTIONS = TO_LIST(options) - - # this rather convoluted set of path calculations is to cope with the possibility - # that gen_ndr is a symlink into the source tree. By doing this for the source3 - # gen_ndr directory we end up generating identical output in gen_ndr for the old - # build system and the new one. That makes keeping things in sync much easier. - # eventually we should drop the gen_ndr files in git, but in the meanwhile this works - - found_dir = bld.path.find_dir(output_dir) - if not 'abspath' in dir(found_dir): - Logs.error('Unable to find pidl output directory %s' % - os.path.normpath(os.path.join(bld.curdir, output_dir))) - sys.exit(1) - - outdir = bld.path.find_dir(output_dir).abspath(t.env) - - if symlink and not os.path.lexists(outdir): - link_source = os.path.normpath(os.path.join(bld.curdir,output_dir)) - os.symlink(link_source, outdir) - - real_outputdir = os.path.realpath(outdir) - t.env.OUTPUTDIR = os_path_relpath(real_outputdir, os.path.dirname(bld.env.BUILD_DIRECTORY)) + t.env.OUTPUTDIR = bld.bldnode.name + '/' + bld.path.find_dir(output_dir).bldpath(t.env) if generate_tables and table_header_idx is not None: pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') @@ -124,11 +103,10 @@ def SAMBA_PIDL_LIST(bld, name, source, options='', output_dir='.', - symlink=False, generate_tables=True): '''A wrapper for building a set of IDL files''' for p in TO_LIST(source): - bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, symlink=symlink, generate_tables=generate_tables) + bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_utils.py ldb-1.1.15/buildtools/wafsamba/samba_utils.py --- ldb-1.1.13/buildtools/wafsamba/samba_utils.py 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_utils.py 2013-01-27 11:51:43.000000000 +0000 @@ -256,7 +256,7 @@ @feature('*') @before('exec_rule', 'apply_core', 'collect') def force_previous_groups(self): - if getattr(self.bld, 'enforced_group_ordering', False) == True: + if getattr(self.bld, 'enforced_group_ordering', False): return self.bld.enforced_group_ordering = True @@ -274,7 +274,7 @@ debug('group: Forcing up to group %s for target %s', group_name(g), self.name or self.target) break - if stop != None: + if stop is not None: break if stop is None: return @@ -388,9 +388,16 @@ # make sure we have md5. some systems don't have it try: from hashlib import md5 + # Even if hashlib.md5 exists, it may be unusable. + # Try to use MD5 function. In FIPS mode this will cause an exception + # and we'll get to the replacement code + foo = md5.md5('abcd') except: try: import md5 + # repeat the same check here, mere success of import is not enough. + # Try to use MD5 function. In FIPS mode this will cause an exception + foo = md5.md5('abcd') except: import Constants Constants.SIG_NIL = hash('abcd') @@ -502,15 +509,15 @@ if v == 'j': jobs_set = True elif v == 'k': - Options.options.keep = True + Options.options.keep = True elif opt == '-j': jobs_set = True elif opt == '-k': - Options.options.keep = True + Options.options.keep = True if not jobs_set: # default to one job Options.options.jobs = 1 - + Build.BuildContext.CHECK_MAKEFLAGS = CHECK_MAKEFLAGS option_groups = {} diff -Nru ldb-1.1.13/buildtools/wafsamba/samba_version.py ldb-1.1.15/buildtools/wafsamba/samba_version.py --- ldb-1.1.13/buildtools/wafsamba/samba_version.py 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/samba_version.py 2013-01-27 11:51:43.000000000 +0000 @@ -132,7 +132,7 @@ def __init__(self, version_dict, path, env=None, is_install=True): '''Determine the version number of samba -See VERSION for the format. Entries on that file are +See VERSION for the format. Entries on that file are also accepted as dictionary entries here ''' diff -Nru ldb-1.1.13/buildtools/wafsamba/stale_files.py ldb-1.1.15/buildtools/wafsamba/stale_files.py --- ldb-1.1.13/buildtools/wafsamba/stale_files.py 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/stale_files.py 2013-01-27 11:51:43.000000000 +0000 @@ -47,7 +47,7 @@ # paranoia if bin_base[-4:] != '/bin': raise Utils.WafError("Invalid bin base: %s" % bin_base) - + # obtain the expected list of files expected = [] for i in range(len(bld.task_manager.groups)): diff -Nru ldb-1.1.13/buildtools/wafsamba/symbols.py ldb-1.1.15/buildtools/wafsamba/symbols.py --- ldb-1.1.13/buildtools/wafsamba/symbols.py 2012-08-28 09:36:26.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/symbols.py 2013-01-27 11:51:43.000000000 +0000 @@ -569,7 +569,7 @@ def report_duplicate(bld, binname, sym, libs, fail_on_error): '''report duplicated symbols''' - if sym in ['_init', '_fini']: + if sym in ['_init', '_fini', '_edata', '_end', '__bss_start']: return libnames = [] for lib in libs: diff -Nru ldb-1.1.13/buildtools/wafsamba/tests/test_abi.py ldb-1.1.15/buildtools/wafsamba/tests/test_abi.py --- ldb-1.1.13/buildtools/wafsamba/tests/test_abi.py 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/tests/test_abi.py 2013-01-27 11:51:43.000000000 +0000 @@ -17,9 +17,12 @@ from wafsamba.tests import TestCase from wafsamba.samba_abi import ( + abi_write_vscript, normalise_signature, ) +from cStringIO import StringIO + class NormaliseSignatureTests(TestCase): @@ -51,3 +54,67 @@ 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2}')) + +class WriteVscriptTests(TestCase): + + def test_one(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "old": "1.0", + "new": "1.0"}, ["*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\t*; +}; +""") + + def test_simple(self): + # No restrictions. + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", ["0.1"], { + "old": "0.1", + "new": "1.0"}, ["*"]) + self.assertEquals(f.getvalue(), """\ +MYLIB_0.1 { +\tglobal: +\t\told; +}; + +1.0 { +\tglobal: +\t\t*; +}; +""") + + def test_exclude(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "exc_old": "0.1", + "old": "0.1", + "new": "1.0"}, ["!exc_*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\t*; +\tlocal: +\t\texc_*; +}; +""") + + def test_excludes_and_includes(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "pub_foo": "1.0", + "exc_bar": "1.0", + "other": "1.0" + }, ["pub_*", "!exc_*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\tpub_*; +\tlocal: +\t\texc_*; +\t\t*; +}; +""") diff -Nru ldb-1.1.13/buildtools/wafsamba/wafsamba.py ldb-1.1.15/buildtools/wafsamba/wafsamba.py --- ldb-1.1.13/buildtools/wafsamba/wafsamba.py 2012-10-02 08:20:23.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/wafsamba.py 2013-01-27 11:51:43.000000000 +0000 @@ -285,9 +285,9 @@ if pc_files is not None and not private_library: bld.PKG_CONFIG_FILES(pc_files, vnum=vnum) - if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and + if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']): - bld.MANPAGES(manpages) + bld.MANPAGES(manpages, install) Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY @@ -383,7 +383,7 @@ ) if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']: - bld.MANPAGES(manpages) + bld.MANPAGES(manpages, install) Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY @@ -670,7 +670,7 @@ bld.SET_BUILD_GROUP('build_source') for s in TO_LIST(source): iname = s - if installname != None: + if installname is not None: iname = installname target = os.path.join(installdir, iname) tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target)) @@ -771,7 +771,7 @@ Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS -def MANPAGES(bld, manpages): +def MANPAGES(bld, manpages, install): '''build and install manual pages''' bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' for m in manpages.split(): @@ -782,21 +782,24 @@ group='final', rule='${XSLTPROC} --xinclude -o ${TGT} --nonet ${MAN_XSL} ${SRC}' ) - bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) + if install: + bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) Build.BuildContext.MANPAGES = MANPAGES def SAMBAMANPAGES(bld, manpages): '''build and install manual pages''' bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl' bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl' - bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file://' + bld.srcnode.abspath() + '/bin/default/docs-xml/build/catalog.xml' + bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.srcnode.abspath() + '/bin/default/docs-xml/build/catalog.xml' + for m in manpages.split(): source = m + '.xml' bld.SAMBA_GENERATOR(m, source=source, target=m, group='final', - rule='''export XML_CATALOG_FILES="${SAMBA_CATALOGS}" + rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}" + export XML_CATALOG_FILES ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC} ${XSLTPROC} --nonet -o ${TGT} ${SAMBA_MAN_XSL} ${TGT}.xml''' ) diff -Nru ldb-1.1.13/buildtools/wafsamba/wscript ldb-1.1.15/buildtools/wafsamba/wscript --- ldb-1.1.13/buildtools/wafsamba/wscript 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/buildtools/wafsamba/wscript 2013-01-27 11:51:43.000000000 +0000 @@ -50,9 +50,6 @@ help=("list of minimum system library versions (LIBNAME1:version,LIBNAME2:version)"), action="store", dest='MINIMUM_LIBRARY_VERSION', default='') - gr.add_option('--disable-shared', - help=("Disable all use of shared libraries"), - action="store_true", dest='disable_shared', default=False) gr.add_option('--disable-rpath', help=("Disable use of rpath for build binaries"), action="store_true", dest='disable_rpath_build', default=False) @@ -248,7 +245,6 @@ conf.env.BUNDLED_LIBS = Options.options.BUNDLED_LIBS.split(',') conf.env.PRIVATE_LIBS = Options.options.PRIVATE_LIBS.split(',') conf.env.BUILTIN_LIBRARIES = Options.options.BUILTIN_LIBRARIES.split(',') - conf.env.DISABLE_SHARED = Options.options.disable_shared conf.env.NONSHARED_BINARIES = Options.options.NONSHARED_BINARIES.split(',') conf.env.PRIVATE_EXTENSION = Options.options.PRIVATE_EXTENSION @@ -297,12 +293,8 @@ headers='stdio.h', msg='Checking simple C program') - # see if we can build shared libs - if not conf.CHECK_LIBRARY_SUPPORT(): - conf.env.DISABLE_SHARED = True - # check for rpath - if not conf.env.DISABLE_SHARED and conf.CHECK_LIBRARY_SUPPORT(rpath=True): + if conf.CHECK_LIBRARY_SUPPORT(rpath=True): support_rpath = True conf.env.RPATH_ON_BUILD = not Options.options.disable_rpath_build conf.env.RPATH_ON_INSTALL = (conf.env.RPATH_ON_BUILD and @@ -322,8 +314,7 @@ # the user can of course always override it. conf.env.PRIVATELIBDIR = conf.env.LIBDIR - if (not conf.env.DISABLE_SHARED and - not Options.options.disable_symbol_versions and + if (not Options.options.disable_symbol_versions and conf.CHECK_LIBRARY_SUPPORT(rpath=support_rpath, version_script=True, msg='-Wl,--version-script support')): @@ -331,7 +322,7 @@ else: conf.env.HAVE_LD_VERSION_SCRIPT = False - if sys.platform == "aix5": + if sys.platform == "aix5" or sys.platform == "aix6": conf.DEFINE('_ALL_SOURCE', 1, add_to_cflags=True) # Might not be needed if ALL_SOURCE is defined # conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) diff -Nru ldb-1.1.13/common/ldb.c ldb-1.1.15/common/ldb.c --- ldb-1.1.13/common/ldb.c 2012-09-03 09:48:09.000000000 +0000 +++ ldb-1.1.15/common/ldb.c 2013-01-27 11:51:43.000000000 +0000 @@ -408,6 +408,7 @@ status = module->ops->prepare_commit(module); if (status != LDB_SUCCESS) { + ldb->transaction_active--; /* if a module fails the prepare then we need to call the end transaction for everyone */ FIRST_OP(ldb, del_transaction); @@ -1980,7 +1981,7 @@ /** - return true is a request is untrusted + * return true if a request is untrusted */ bool ldb_req_is_untrusted(struct ldb_request *req) { diff -Nru ldb-1.1.13/common/ldb_ldif.c ldb-1.1.15/common/ldb_ldif.c --- ldb-1.1.13/common/ldb_ldif.c 2012-09-03 09:48:09.000000000 +0000 +++ ldb-1.1.15/common/ldb_ldif.c 2013-01-27 11:51:43.000000000 +0000 @@ -333,7 +333,7 @@ if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) { /* Deliberatly skip printing this password */ - ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE", + ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n", msg->elements[i].name); CHECK_RET; continue; diff -Nru ldb-1.1.13/common/ldb_pack.c ldb-1.1.15/common/ldb_pack.c --- ldb-1.1.13/common/ldb_pack.c 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/common/ldb_pack.c 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,287 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + 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 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + 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, see . +*/ + +/* + * Name: ldb + * + * Component: ldb pack/unpack + * + * Description: pack/unpack routines for ldb messages as key/value blobs + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* change this if the data format ever changes */ +#define LDB_PACKING_FORMAT 0x26011967 + +/* old packing formats */ +#define LDB_PACKING_FORMAT_NODN 0x26011966 + +/* use a portable integer format */ +static void put_uint32(uint8_t *p, int ofs, unsigned int val) +{ + p += ofs; + p[0] = val&0xFF; + p[1] = (val>>8) & 0xFF; + p[2] = (val>>16) & 0xFF; + p[3] = (val>>24) & 0xFF; +} + +static unsigned int pull_uint32(uint8_t *p, int ofs) +{ + p += ofs; + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + +static int attribute_storable_values(const struct ldb_message_element *el) +{ + if (el->num_values == 0) return 0; + + if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; + + return el->num_values; +} + +/* + pack a ldb message into a linear buffer in a ldb_val + + note that this routine avoids saving elements with zero values, + as these are equivalent to having no element + + caller frees the data buffer after use +*/ +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data) +{ + unsigned int i, j, real_elements=0; + size_t size; + const char *dn; + uint8_t *p; + size_t len; + + dn = ldb_dn_get_linearized(message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + /* work out how big it needs to be */ + size = 8; + + size += 1 + strlen(dn); + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + size += 1 + strlen(message->elements[i].name) + 4; + for (j=0;jelements[i].num_values;j++) { + size += 4 + message->elements[i].values[j].length + 1; + } + } + + /* allocate it */ + data->data = talloc_array(ldb, uint8_t, size); + if (!data->data) { + errno = ENOMEM; + return -1; + } + data->length = size; + + p = data->data; + put_uint32(p, 0, LDB_PACKING_FORMAT); + put_uint32(p, 4, real_elements); + p += 8; + + /* the dn needs to be packed so we can be case preserving + while hashing on a case folded dn */ + len = strlen(dn); + memcpy(p, dn, len+1); + p += len + 1; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + len = strlen(message->elements[i].name); + memcpy(p, message->elements[i].name, len+1); + p += len + 1; + put_uint32(p, 0, message->elements[i].num_values); + p += 4; + for (j=0;jelements[i].num_values;j++) { + put_uint32(p, 0, message->elements[i].values[j].length); + memcpy(p+4, message->elements[i].values[j].data, + message->elements[i].values[j].length); + p[4+message->elements[i].values[j].length] = 0; + p += 4 + message->elements[i].values[j].length + 1; + } + } + + return 0; +} + +/* + unpack a ldb message from a linear buffer in ldb_val + + Free with ldb_unpack_data_free() +*/ +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message) +{ + uint8_t *p; + unsigned int remaining; + unsigned int i, j; + unsigned format; + size_t len; + + message->elements = NULL; + + p = data->data; + if (data->length < 8) { + errno = EIO; + goto failed; + } + + format = pull_uint32(p, 0); + message->num_elements = pull_uint32(p, 4); + p += 8; + + remaining = data->length - 8; + + switch (format) { + case LDB_PACKING_FORMAT_NODN: + message->dn = NULL; + break; + + case LDB_PACKING_FORMAT: + len = strnlen((char *)p, remaining); + if (len == remaining) { + errno = EIO; + goto failed; + } + message->dn = ldb_dn_new(message, ldb, (char *)p); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + break; + + default: + errno = EIO; + goto failed; + } + + if (message->num_elements == 0) { + return 0; + } + + if (message->num_elements > remaining / 6) { + errno = EIO; + goto failed; + } + + message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + memset(message->elements, 0, + message->num_elements * sizeof(struct ldb_message_element)); + + for (i=0;inum_elements;i++) { + if (remaining < 10) { + errno = EIO; + goto failed; + } + len = strnlen((char *)p, remaining-6); + if (len == remaining-6) { + errno = EIO; + goto failed; + } + if (len == 0) { + errno = EIO; + goto failed; + } + message->elements[i].flags = 0; + message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); + if (message->elements[i].name == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + message->elements[i].num_values = pull_uint32(p, 0); + message->elements[i].values = NULL; + if (message->elements[i].num_values != 0) { + message->elements[i].values = talloc_array(message->elements, + struct ldb_val, + message->elements[i].num_values); + if (!message->elements[i].values) { + errno = ENOMEM; + goto failed; + } + } + p += 4; + remaining -= 4; + for (j=0;jelements[i].num_values;j++) { + len = pull_uint32(p, 0); + if (len > remaining-5) { + errno = EIO; + goto failed; + } + + message->elements[i].values[j].length = len; + message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + if (message->elements[i].values[j].data == NULL) { + errno = ENOMEM; + goto failed; + } + memcpy(message->elements[i].values[j].data, p+4, len); + message->elements[i].values[j].data[len] = 0; + + remaining -= len+4+1; + p += len+4+1; + } + } + + if (remaining != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %d bytes unread in ldb_unpack_data", remaining); + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} diff -Nru ldb-1.1.13/debian/changelog ldb-1.1.15/debian/changelog --- ldb-1.1.13/debian/changelog 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/changelog 2013-01-28 16:52:25.000000000 +0000 @@ -1,3 +1,15 @@ +ldb (1:1.1.15-SprezzOS1) unstable; urgency=low + + * New upstream + + -- Nick Black Mon, 28 Jan 2013 11:48:39 -0500 + +ldb (1:1.1.14-SprezzOS1) unstable; urgency=low + + * New upstream 1.1.14 + + -- Nick Black Wed, 02 Jan 2013 18:07:02 -0500 + ldb (1:1.1.13-1) experimental; urgency=low * New upstream release. diff -Nru ldb-1.1.13/debian/control ldb-1.1.15/debian/control --- ldb-1.1.13/debian/control 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/control 2013-01-28 16:52:25.000000000 +0000 @@ -1,7 +1,8 @@ Source: ldb Section: devel Priority: optional -Maintainer: Jelmer Vernooij +Maintainer: Nick Black +XSBC-Original-Maintainer: Jelmer Vernooij Build-Depends: debhelper (>> 8.1.3), docbook-xml, docbook-xsl, @@ -18,7 +19,7 @@ python-tdb (>= 1.2.10~), xsltproc Homepage: http://ldb.samba.org/ -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Vcs-Git: git://git.debian.org/pkg-samba/ldb.git Package: libldb1 diff -Nru ldb-1.1.13/debian/libldb1.symbols ldb-1.1.15/debian/libldb1.symbols --- ldb-1.1.13/debian/libldb1.symbols 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/libldb1.symbols 2013-01-28 16:52:25.000000000 +0000 @@ -1,4 +1,4 @@ -libldb.so.1 #PACKAGE# #MINVER# +libldb.so.1 libldb1 #MINVER# LDB_0.9.10@LDB_0.9.10 0.9.21 LDB_0.9.12@LDB_0.9.12 0.9.21 LDB_0.9.15@LDB_0.9.15 0.9.21 @@ -14,6 +14,12 @@ LDB_1.0.1@LDB_1.0.1 1.0.1~ LDB_1.0.2@LDB_1.0.2 1.0.2~ LDB_1.1.0@LDB_1.1.0 1.1.0 + LDB_1.1.10@LDB_1.1.10 1.1.12 + LDB_1.1.11@LDB_1.1.11 1.1.12 + LDB_1.1.12@LDB_1.1.12 1.1.12 + LDB_1.1.13@LDB_1.1.13 1.1.13 + LDB_1.1.14@LDB_1.1.14 1:1.1.14 + LDB_1.1.15@LDB_1.1.15 1:1.1.15 LDB_1.1.1@LDB_1.1.1 1.1.1~ LDB_1.1.2@LDB_1.1.2 1.1.2~ LDB_1.1.3@LDB_1.1.3 1.1.3 @@ -23,13 +29,6 @@ LDB_1.1.7@LDB_1.1.7 1.1.12 LDB_1.1.8@LDB_1.1.8 1.1.12 LDB_1.1.9@LDB_1.1.9 1.1.12 - LDB_1.1.10@LDB_1.1.10 1.1.12 - LDB_1.1.11@LDB_1.1.11 1.1.12 - LDB_1.1.12@LDB_1.1.12 1.1.12 - LDB_1.1.13@LDB_1.1.13 1.1.13 - ldb_check_critical_controls@LDB_0.9.22 0.9.22 - ldb_controls_except_specified@LDB_0.9.22 0.9.22 - ldb_control_to_string@LDB_1.0.2 1.0.2~git20110403 ldb_add@LDB_0.9.10 0.9.21 ldb_any_comparison@LDB_0.9.10 0.9.21 ldb_asprintf_errstring@LDB_0.9.10 0.9.21 @@ -52,10 +51,12 @@ ldb_build_search_req_ex@LDB_0.9.10 0.9.21 ldb_casefold@LDB_0.9.10 0.9.21 ldb_casefold_default@LDB_0.9.10 0.9.21 + ldb_check_critical_controls@LDB_0.9.22 0.9.22 ldb_comparison_binary@LDB_0.9.10 0.9.21 ldb_comparison_fold@LDB_0.9.10 0.9.21 ldb_connect@LDB_0.9.10 0.9.21 ldb_control_to_string@LDB_1.0.2 1.0.2 + ldb_controls_except_specified@LDB_0.9.22 0.9.22 ldb_debug@LDB_0.9.10 0.9.21 ldb_debug_add@LDB_0.9.10 0.9.21 ldb_debug_end@LDB_0.9.10 0.9.21 @@ -216,6 +217,7 @@ ldb_next_start_trans@LDB_0.9.10 0.9.21 ldb_op_default_callback@LDB_0.9.10 0.9.21 ldb_options_find@LDB_0.9.17 0.9.21 + ldb_pack_data@LDB_1.1.14 1:1.1.14 ldb_parse_control_from_string@LDB_1.0.2 1.0.2~git20110403 ldb_parse_control_strings@LDB_0.9.10 0.9.21 ldb_parse_tree@LDB_0.9.10 0.9.21 @@ -244,6 +246,7 @@ ldb_request_replace_control@LDB_0.9.15 0.9.21 ldb_request_set_state@LDB_0.9.10 0.9.21 ldb_reset_err_string@LDB_0.9.10 0.9.21 + ldb_save_controls@LDB_0.9.22 0.9.22 ldb_schema_attribute_add@LDB_0.9.10 0.9.21 ldb_schema_attribute_add_with_syntax@LDB_0.9.10 0.9.21 ldb_schema_attribute_by_name@LDB_0.9.10 0.9.21 @@ -278,6 +281,7 @@ ldb_transaction_commit@LDB_0.9.10 0.9.21 ldb_transaction_prepare_commit@LDB_0.9.10 0.9.21 ldb_transaction_start@LDB_0.9.10 0.9.21 + ldb_unpack_data@LDB_1.1.14 1:1.1.14 ldb_val_dup@LDB_0.9.10 0.9.21 ldb_val_equal_exact@LDB_0.9.10 0.9.21 ldb_val_map_local@LDB_0.9.10 0.9.21 @@ -287,4 +291,3 @@ ldb_valid_attr_name@LDB_0.9.10 0.9.21 ldb_vdebug@LDB_1.1.10 1.1.12 ldb_wait@LDB_0.9.10 0.9.21 - ldb_save_controls@LDB_0.9.22 0.9.22 diff -Nru ldb-1.1.13/debian/patches/01_exclude_symbols ldb-1.1.15/debian/patches/01_exclude_symbols --- ldb-1.1.13/debian/patches/01_exclude_symbols 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/patches/01_exclude_symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -Description: Properly hide private symbols in libldb1 -Author: Jelmer Vernooij -Bug: https://bugzilla.samba.org/show_bug.cgi?id=9357 -Status: submitted upstream - -diff -ur ldb-1.1.13/buildtools/wafsamba/samba_abi.py ldb-1.1.13-fixd/buildtools/wafsamba/samba_abi.py ---- ldb-1.1.13/buildtools/wafsamba/samba_abi.py 2012-09-07 16:47:16.000000000 +0200 -+++ ldb-1.1.13-fixd/buildtools/wafsamba/samba_abi.py 2012-11-05 19:23:40.010206344 +0100 -@@ -190,12 +190,12 @@ - f.write("\t\t%s;\n" % x) - else: - f.write("\t\t*;\n") -- if len(local_abi) > 0: -+ if abi_match != ["*"]: - f.write("\tlocal:\n") - for x in local_abi: - f.write("\t\t%s;\n" % x[1:]) -- elif abi_match != ["*"]: -- f.write("\tlocal: *;\n") -+ if len(global_abi) > 0: -+ f.write("\t\t*;\n") - f.write("};\n") - f.close() - diff -Nru ldb-1.1.13/debian/patches/series ldb-1.1.15/debian/patches/series --- ldb-1.1.13/debian/patches/series 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -01_exclude_symbols diff -Nru ldb-1.1.13/debian/python-ldb.symbols ldb-1.1.15/debian/python-ldb.symbols --- ldb-1.1.13/debian/python-ldb.symbols 2012-11-05 21:45:02.000000000 +0000 +++ ldb-1.1.15/debian/python-ldb.symbols 2013-01-28 16:52:25.000000000 +0000 @@ -1,4 +1,10 @@ -libpyldb-util.so.1 #PACKAGE# #MINVER# +libpyldb-util.so.1 python-ldb #MINVER# + PYLDB_UTIL_1.1.10@PYLDB_UTIL_1.1.10 1:1.1.12 + PYLDB_UTIL_1.1.11@PYLDB_UTIL_1.1.11 1:1.1.12 + PYLDB_UTIL_1.1.12@PYLDB_UTIL_1.1.12 1:1.1.12 + PYLDB_UTIL_1.1.13@PYLDB_UTIL_1.1.13 1:1.1.13 + PYLDB_UTIL_1.1.14@PYLDB_UTIL_1.1.14 1:1.1.14 + PYLDB_UTIL_1.1.15@PYLDB_UTIL_1.1.15 1:1.1.15 PYLDB_UTIL_1.1.2@PYLDB_UTIL_1.1.2 1.1.2~ PYLDB_UTIL_1.1.3@PYLDB_UTIL_1.1.3 1.1.3 PYLDB_UTIL_1.1.4@PYLDB_UTIL_1.1.4 1.1.4 @@ -7,9 +13,5 @@ PYLDB_UTIL_1.1.7@PYLDB_UTIL_1.1.7 1:1.1.12 PYLDB_UTIL_1.1.8@PYLDB_UTIL_1.1.8 1:1.1.12 PYLDB_UTIL_1.1.9@PYLDB_UTIL_1.1.9 1:1.1.12 - PYLDB_UTIL_1.1.10@PYLDB_UTIL_1.1.10 1:1.1.12 - PYLDB_UTIL_1.1.11@PYLDB_UTIL_1.1.11 1:1.1.12 - PYLDB_UTIL_1.1.12@PYLDB_UTIL_1.1.12 1:1.1.12 - PYLDB_UTIL_1.1.13@PYLDB_UTIL_1.1.13 1:1.1.13 pyldb_Dn_FromDn@PYLDB_UTIL_1.1.2 1.1.2~ pyldb_Object_AsDn@PYLDB_UTIL_1.1.2 1.1.2~ diff -Nru ldb-1.1.13/include/ldb.h ldb-1.1.15/include/ldb.h --- ldb-1.1.13/include/ldb.h 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/include/ldb.h 2013-01-27 11:51:43.000000000 +0000 @@ -1033,6 +1033,18 @@ */ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); +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); + /** Connect to a database. @@ -1056,19 +1068,6 @@ (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[]); /* diff -Nru ldb-1.1.13/include/ldb_private.h ldb-1.1.15/include/ldb_private.h --- ldb-1.1.13/include/ldb_private.h 2012-09-03 09:48:09.000000000 +0000 +++ ldb-1.1.15/include/ldb_private.h 2013-01-27 11:51:43.000000000 +0000 @@ -194,4 +194,15 @@ char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif); +/* + * these pack/unpack functions are exposed in the library for use by + * ldb tools like ldbdump, but are not part of the public API + */ +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data); +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message); + #endif diff -Nru ldb-1.1.13/ldb_tdb/ldb_index.c ldb-1.1.15/ldb_tdb/ldb_index.c --- ldb-1.1.13/ldb_tdb/ldb_index.c 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/ldb_tdb/ldb_index.c 2013-01-27 11:51:43.000000000 +0000 @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" struct dn_list { unsigned int count; @@ -1509,7 +1510,7 @@ return -1; } - ret = ltdb_unpack_data(module, &data, msg); + ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", ldb_dn_get_linearized(msg->dn)); diff -Nru ldb-1.1.13/ldb_tdb/ldb_pack.c ldb-1.1.15/ldb_tdb/ldb_pack.c --- ldb-1.1.13/ldb_tdb/ldb_pack.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/ldb_tdb/ldb_pack.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - 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 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 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - 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, see . -*/ - -/* - * Name: ldb - * - * Component: ldb pack/unpack - * - * Description: pack/unpack routines for ldb messages as key/value blobs - * - * Author: Andrew Tridgell - */ - -#include "ldb_tdb.h" - -/* change this if the data format ever changes */ -#define LTDB_PACKING_FORMAT 0x26011967 - -/* old packing formats */ -#define LTDB_PACKING_FORMAT_NODN 0x26011966 - -/* use a portable integer format */ -static void put_uint32(uint8_t *p, int ofs, unsigned int val) -{ - p += ofs; - p[0] = val&0xFF; - p[1] = (val>>8) & 0xFF; - p[2] = (val>>16) & 0xFF; - p[3] = (val>>24) & 0xFF; -} - -static unsigned int pull_uint32(uint8_t *p, int ofs) -{ - p += ofs; - return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); -} - -static int attribute_storable_values(const struct ldb_message_element *el) -{ - if (el->num_values == 0) return 0; - - if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; - - return el->num_values; -} - -/* - pack a ldb message into a linear buffer in a TDB_DATA - - note that this routine avoids saving elements with zero values, - as these are equivalent to having no element - - caller frees the data buffer after use -*/ -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - TDB_DATA *data) -{ - struct ldb_context *ldb; - unsigned int i, j, real_elements=0; - size_t size; - const char *dn; - uint8_t *p; - size_t len; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_get_linearized(message->dn); - if (dn == NULL) { - errno = ENOMEM; - return -1; - } - - /* work out how big it needs to be */ - size = 8; - - size += 1 + strlen(dn); - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - real_elements++; - - size += 1 + strlen(message->elements[i].name) + 4; - for (j=0;jelements[i].num_values;j++) { - size += 4 + message->elements[i].values[j].length + 1; - } - } - - /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); - if (!data->dptr) { - errno = ENOMEM; - return -1; - } - data->dsize = size; - - p = data->dptr; - put_uint32(p, 0, LTDB_PACKING_FORMAT); - put_uint32(p, 4, real_elements); - p += 8; - - /* the dn needs to be packed so we can be case preserving - while hashing on a case folded dn */ - len = strlen(dn); - memcpy(p, dn, len+1); - p += len + 1; - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - len = strlen(message->elements[i].name); - memcpy(p, message->elements[i].name, len+1); - p += len + 1; - put_uint32(p, 0, message->elements[i].num_values); - p += 4; - for (j=0;jelements[i].num_values;j++) { - put_uint32(p, 0, message->elements[i].values[j].length); - memcpy(p+4, message->elements[i].values[j].data, - message->elements[i].values[j].length); - p[4+message->elements[i].values[j].length] = 0; - p += 4 + message->elements[i].values[j].length + 1; - } - } - - return 0; -} - -/* - unpack a ldb message from a linear buffer in TDB_DATA - - Free with ltdb_unpack_data_free() -*/ -int ltdb_unpack_data(struct ldb_module *module, - const TDB_DATA *data, - struct ldb_message *message) -{ - struct ldb_context *ldb; - uint8_t *p; - unsigned int remaining; - unsigned int i, j; - unsigned format; - size_t len; - - ldb = ldb_module_get_ctx(module); - message->elements = NULL; - - p = data->dptr; - if (data->dsize < 8) { - errno = EIO; - goto failed; - } - - format = pull_uint32(p, 0); - message->num_elements = pull_uint32(p, 4); - p += 8; - - remaining = data->dsize - 8; - - switch (format) { - case LTDB_PACKING_FORMAT_NODN: - message->dn = NULL; - break; - - case LTDB_PACKING_FORMAT: - len = strnlen((char *)p, remaining); - if (len == remaining) { - errno = EIO; - goto failed; - } - message->dn = ldb_dn_new(message, ldb, (char *)p); - if (message->dn == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - break; - - default: - errno = EIO; - goto failed; - } - - if (message->num_elements == 0) { - return 0; - } - - if (message->num_elements > remaining / 6) { - errno = EIO; - goto failed; - } - - message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); - if (!message->elements) { - errno = ENOMEM; - goto failed; - } - - memset(message->elements, 0, - message->num_elements * sizeof(struct ldb_message_element)); - - for (i=0;inum_elements;i++) { - if (remaining < 10) { - errno = EIO; - goto failed; - } - len = strnlen((char *)p, remaining-6); - if (len == remaining-6) { - errno = EIO; - goto failed; - } - if (len == 0) { - errno = EIO; - goto failed; - } - message->elements[i].flags = 0; - message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); - if (message->elements[i].name == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - message->elements[i].num_values = pull_uint32(p, 0); - message->elements[i].values = NULL; - if (message->elements[i].num_values != 0) { - message->elements[i].values = talloc_array(message->elements, - struct ldb_val, - message->elements[i].num_values); - if (!message->elements[i].values) { - errno = ENOMEM; - goto failed; - } - } - p += 4; - remaining -= 4; - for (j=0;jelements[i].num_values;j++) { - len = pull_uint32(p, 0); - if (len > remaining-5) { - errno = EIO; - goto failed; - } - - message->elements[i].values[j].length = len; - message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); - if (message->elements[i].values[j].data == NULL) { - errno = ENOMEM; - goto failed; - } - memcpy(message->elements[i].values[j].data, p+4, len); - message->elements[i].values[j].data[len] = 0; - - remaining -= len+4+1; - p += len+4+1; - } - } - - if (remaining != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %d bytes unread in ltdb_unpack_data", remaining); - } - - return 0; - -failed: - talloc_free(message->elements); - return -1; -} diff -Nru ldb-1.1.13/ldb_tdb/ldb_search.c ldb-1.1.15/ldb_tdb/ldb_search.c --- ldb-1.1.13/ldb_tdb/ldb_search.c 2012-08-17 14:39:01.000000000 +0000 +++ ldb-1.1.15/ldb_tdb/ldb_search.c 2013-01-27 11:51:43.000000000 +0000 @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" #include /* @@ -244,9 +245,9 @@ { struct ltdb_parse_data_unpack_ctx *ctx = private_data; - int ret = ltdb_unpack_data(ctx->module, &data, ctx->msg); + struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); + int ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, ctx->msg); if (ret == -1) { - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", (int)key.dsize, (int)key.dsize, key.dptr); return LDB_ERR_OPERATIONS_ERROR; @@ -440,7 +441,7 @@ } /* unpack the record */ - ret = ltdb_unpack_data(ac->module, &data, msg); + ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, msg); if (ret == -1) { talloc_free(msg); return -1; diff -Nru ldb-1.1.13/ldb_tdb/ldb_tdb.c ldb-1.1.15/ldb_tdb/ldb_tdb.c --- ldb-1.1.13/ldb_tdb/ldb_tdb.c 2012-08-28 09:36:26.000000000 +0000 +++ ldb-1.1.15/ldb_tdb/ldb_tdb.c 2013-01-27 11:51:43.000000000 +0000 @@ -50,6 +50,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" #include /* @@ -264,7 +265,7 @@ return LDB_ERR_OTHER; } - ret = ltdb_pack_data(module, msg, &tdb_data); + ret = ldb_pack_data(module, msg, (struct ldb_val *)&tdb_data); if (ret == -1) { talloc_free(tdb_key.dptr); return LDB_ERR_OTHER; @@ -693,7 +694,7 @@ goto done; } - ret = ltdb_unpack_data(module, &tdb_data, msg2); + ret = ldb_unpack_data(ldb_module_get_ctx(module), (struct ldb_val *)&tdb_data, msg2); free(tdb_data.dptr); if (ret == -1) { ret = LDB_ERR_OTHER; diff -Nru ldb-1.1.13/ldb_tdb/ldb_tdb.h ldb-1.1.15/ldb_tdb/ldb_tdb.h --- ldb-1.1.13/ldb_tdb/ldb_tdb.h 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/ldb_tdb/ldb_tdb.h 2013-01-27 11:51:43.000000000 +0000 @@ -92,17 +92,6 @@ int ltdb_index_transaction_commit(struct ldb_module *module); int ltdb_index_transaction_cancel(struct ldb_module *module); -/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */ - -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - TDB_DATA *data); -void ltdb_unpack_data_free(struct ldb_module *module, - struct ldb_message *message); -int ltdb_unpack_data(struct ldb_module *module, - const TDB_DATA *data, - struct ldb_message *message); - /* The following definitions come from lib/ldb/ldb_tdb/ldb_search.c */ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, diff -Nru ldb-1.1.13/lib/replace/README ldb-1.1.15/lib/replace/README --- ldb-1.1.13/lib/replace/README 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/lib/replace/README 2013-01-27 11:51:43.000000000 +0000 @@ -49,7 +49,6 @@ pwrite chown lchown -getpass readline (the library) inet_ntoa inet_ntop @@ -73,6 +72,7 @@ symlink realpath poll +setproctitle Types: bool diff -Nru ldb-1.1.13/lib/replace/getpass.c ldb-1.1.15/lib/replace/getpass.c --- ldb-1.1.13/lib/replace/getpass.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/getpass.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +0,0 @@ -/* Copyright (C) 1992-1998 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C 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 3 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, see . */ - -/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "system/terminal.h" -#include "system/passwd.h" - -/* - * Define additional missing types - */ -#ifndef HAVE_SIG_ATOMIC_T_TYPE -typedef int sig_atomic_t; -#endif - -#ifndef SIGCLD -#define SIGCLD SIGCHLD -#endif - -#ifdef SYSV_TERMIO - -/* SYSTEM V TERMIO HANDLING */ - -static struct termio t; - -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -#ifndef TCSAFLUSH -#define TCSAFLUSH 1 -#endif - -#ifndef TCSANOW -#define TCSANOW 0 -#endif - -static int tcgetattr(int fd, struct termio *_t) -{ - return ioctl(fd, TCGETA, _t); -} - -static int tcsetattr(int fd, int flags, struct termio *_t) -{ - if(flags & TCSAFLUSH) - ioctl(fd, TCFLSH, TCIOFLUSH); - return ioctl(fd, TCSETS, _t); -} - -#elif !defined(TCSAFLUSH) - -/* BSD TERMIO HANDLING */ - -static struct sgttyb t; - -#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) -#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) - -#define TCSAFLUSH 1 -#define TCSANOW 0 - -static int tcgetattr(int fd, struct sgttyb *_t) -{ - return ioctl(fd, TIOCGETP, (char *)_t); -} - -static int tcsetattr(int fd, int flags, struct sgttyb *_t) -{ - return ioctl(fd, TIOCSETP, (char *)_t); -} - -#else /* POSIX TERMIO HANDLING */ -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -static struct termios t; -#endif /* SYSV_TERMIO */ - -static void catch_signal(int signum, void (*handler)(int )) -{ -#ifdef HAVE_SIGACTION - struct sigaction act; - struct sigaction oldact; - - memset(&act, 0, sizeof(act)); - - act.sa_handler = handler; -#ifdef SA_RESTART - /* - * We *want* SIGALRM to interrupt a system call. - */ - if(signum != SIGALRM) - act.sa_flags = SA_RESTART; -#endif - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask,signum); - sigaction(signum,&act,&oldact); -#else /* !HAVE_SIGACTION */ - /* FIXME: need to handle sigvec and systems with broken signal() */ - signal(signum, handler); -#endif -} - -static sig_atomic_t gotintr; -static int in_fd = -1; - -/*************************************************************** - Signal function to tell us were ^C'ed. -****************************************************************/ - -static void gotintr_sig(int signum) -{ - gotintr = 1; - if (in_fd != -1) - close(in_fd); /* Safe way to force a return. */ - in_fd = -1; -} - -char *rep_getpass(const char *prompt) -{ - FILE *in, *out; - int echo_off; - static char buf[256]; - static size_t bufsize = sizeof(buf); - size_t nread; - - /* Catch problematic signals */ - catch_signal(SIGINT, gotintr_sig); - - /* Try to write to and read from the terminal if we can. - If we can't open the terminal, use stderr and stdin. */ - - in = fopen ("/dev/tty", "w+"); - if (in == NULL) { - in = stdin; - out = stderr; - } else { - out = in; - } - - setvbuf(in, NULL, _IONBF, 0); - - /* Turn echoing off if it is on now. */ - - if (tcgetattr (fileno (in), &t) == 0) { - if (ECHO_IS_ON(t)) { - TURN_ECHO_OFF(t); - echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; - TURN_ECHO_ON(t); - } else { - echo_off = 0; - } - } else { - echo_off = 0; - } - - /* Write the prompt. */ - fputs(prompt, out); - fflush(out); - - /* Read the password. */ - buf[0] = 0; - if (!gotintr) { - in_fd = fileno(in); - if (fgets(buf, bufsize, in) == NULL) { - buf[0] = 0; - } - } - nread = strlen(buf); - if (nread) { - if (buf[nread - 1] == '\n') - buf[nread - 1] = '\0'; - } - - /* Restore echoing. */ - if (echo_off) { - if (gotintr && in_fd == -1) { - in = fopen ("/dev/tty", "w+"); - } - if (in != NULL) - tcsetattr (fileno (in), TCSANOW, &t); - } - - fprintf(out, "\n"); - fflush(out); - - if (in && in != stdin) /* We opened the terminal; now close it. */ - fclose(in); - - /* Catch problematic signals */ - catch_signal(SIGINT, SIG_DFL); - - if (gotintr) { - printf("Interrupted by signal.\n"); - fflush(stdout); - exit(1); - } - return buf; -} diff -Nru ldb-1.1.13/lib/replace/getpass.m4 ldb-1.1.15/lib/replace/getpass.m4 --- ldb-1.1.13/lib/replace/getpass.m4 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/getpass.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -AC_CHECK_FUNC(getpass, libreplace_cv_HAVE_GETPASS=yes) -AC_CHECK_FUNC(getpassphrase, libreplace_cv_HAVE_GETPASSPHRASE=yes) -if test x"$libreplace_cv_HAVE_GETPASS" = x"yes" -a x"$libreplace_cv_HAVE_GETPASSPHRASE" = x"yes"; then - AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars]) - AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} $libreplacedir/getpass.o" -else - -AC_CACHE_CHECK([whether getpass should be replaced],libreplace_cv_REPLACE_GETPASS,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I$libreplacedir/" -AC_TRY_COMPILE([ -#include "confdefs.h" -#define NO_CONFIG_H -#include "$libreplacedir/getpass.c" -],[],libreplace_cv_REPLACE_GETPASS=yes,libreplace_cv_REPLACE_GETPASS=no) -CPPFLAGS="$SAVE_CPPFLAGS" -]) -if test x"$libreplace_cv_REPLACE_GETPASS" = x"yes"; then - AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} $libreplacedir/getpass.o" -fi - -fi diff -Nru ldb-1.1.13/lib/replace/libreplace.m4 ldb-1.1.15/lib/replace/libreplace.m4 --- ldb-1.1.13/lib/replace/libreplace.m4 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/lib/replace/libreplace.m4 2013-01-27 11:51:43.000000000 +0000 @@ -68,7 +68,7 @@ AC_CHECK_FUNCS([pipe strftime srandom random srand rand usleep setbuffer lstat getpgrp utime utimes]) AC_CHECK_HEADERS(stdbool.h stdint.h sys/select.h) -AC_CHECK_HEADERS(setjmp.h utime.h) +AC_CHECK_HEADERS(setjmp.h utime.h sys/wait.h) LIBREPLACE_PROVIDE_HEADER([stdint.h]) LIBREPLACE_PROVIDE_HEADER([stdbool.h]) @@ -126,6 +126,7 @@ AC_CHECK_HEADERS(malloc.h) AC_CHECK_HEADERS(syscall.h) AC_CHECK_HEADERS(sys/syscall.h) +AC_CHECK_HEADERS(sys/ucontext.h) AC_CHECK_FUNCS(syscall setuid seteuid setreuid setresuid setgid setegid setregid setresgid setgroups) AC_CHECK_FUNCS(chroot bzero strerror strerror_r memalign posix_memalign getpagesize) @@ -212,12 +213,27 @@ #include main() { struct stat st; - char tpl[20]="/tmp/test.XXXXXX"; - int fd = mkstemp(tpl); - if (fd == -1) exit(1); + char tpl[20]="/tmp/test.XXXXXX"; + char tpl2[20]="/tmp/test.XXXXXX"; + int fd = mkstemp(tpl); + int fd2 = mkstemp(tpl2); + if (fd == -1) { + if (fd2 != -1) { + unlink(tpl2); + } + exit(1); + } + if (fd2 == -1) exit(1); unlink(tpl); + unlink(tpl2); if (fstat(fd, &st) != 0) exit(1); if ((st.st_mode & 0777) != 0600) exit(1); + if (strcmp(tpl, "/tmp/test.XXXXXX") == 0) { + exit(1); + } + if (strcmp(tpl, tpl2) == 0) { + exit(1); + } exit(0); }], libreplace_cv_HAVE_SECURE_MKSTEMP=yes, @@ -342,6 +358,16 @@ fi +dnl Check if the C compiler understands volatile (it should, being ANSI). +AC_CACHE_CHECK([that the C compiler understands volatile],libreplace_cv_volatile, [ + AC_TRY_COMPILE([#include ],[volatile int i = 0], + libreplace_cv_volatile=yes,libreplace_cv_volatile=no)]) +if test x"$libreplace_cv_volatile" = x"yes"; then + AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) +fi + +m4_include(system/config.m4) + AC_CACHE_CHECK([for O_DIRECT flag to open(2)],libreplace_cv_HAVE_OPEN_O_DIRECT,[ AC_TRY_COMPILE([ #include @@ -354,19 +380,7 @@ AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT]) fi - -dnl Check if the C compiler understands volatile (it should, being ANSI). -AC_CACHE_CHECK([that the C compiler understands volatile],libreplace_cv_volatile, [ - AC_TRY_COMPILE([#include ],[volatile int i = 0], - libreplace_cv_volatile=yes,libreplace_cv_volatile=no)]) -if test x"$libreplace_cv_volatile" = x"yes"; then - AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) -fi - -m4_include(system/config.m4) - m4_include(dlfcn.m4) -m4_include(getpass.m4) m4_include(strptime.m4) m4_include(win32.m4) m4_include(timegm.m4) @@ -402,6 +416,18 @@ AC_DEFINE(HAVE_STRUCT_TIMESPEC,1,[Whether we have struct timespec]) fi +AC_CACHE_CHECK([for ucontext_t type],libreplace_cv_ucontext_t, [ + AC_TRY_COMPILE([ +#include +#if HAVE_SYS_UCONTEXT_H +#include +# endif +],[ucontext_t uc; sigaddset(&uc.uc_sigmask, SIGUSR1);], + libreplace_cv_ucontext_t=yes,libreplace_cv_ucontext_t=no)]) +if test x"$libreplace_cv_ucontext_t" = x"yes"; then + AC_DEFINE(HAVE_UCONTEXT_T,1,[Whether we have ucontext_t]) +fi + AC_CHECK_FUNCS([printf memset memcpy],,[AC_MSG_ERROR([Required function not found])]) echo "LIBREPLACE_BROKEN_CHECKS: END" diff -Nru ldb-1.1.13/lib/replace/poll.c ldb-1.1.15/lib/replace/poll.c --- ldb-1.1.13/lib/replace/poll.c 2012-10-02 08:20:23.000000000 +0000 +++ ldb-1.1.15/lib/replace/poll.c 2013-01-27 11:51:43.000000000 +0000 @@ -33,7 +33,7 @@ #ifdef HAVE_SYS_TIME_H #include #endif -#ifdef HAVE_SYS_IOCTL +#ifdef HAVE_SYS_IOCTL_H #include #endif @@ -46,7 +46,7 @@ int rc; nfds_t i; - if (fds == NULL) { + if ((fds == NULL) && (nfds != 0)) { errno = EFAULT; return -1; } diff -Nru ldb-1.1.13/lib/replace/replace-test.h ldb-1.1.15/lib/replace/replace-test.h --- ldb-1.1.13/lib/replace/replace-test.h 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/replace-test.h 2013-01-27 11:51:43.000000000 +0000 @@ -1,10 +1,6 @@ #ifndef __LIB_REPLACE_REPLACE_TEST_H__ #define __LIB_REPLACE_REPLACE_TEST_H__ -#include -struct torture_context; - -bool torture_local_replace(struct torture_context *ctx); int libreplace_test_strptime(void); int test_readdir_os2_delete(void); int getifaddrs_test(void); diff -Nru ldb-1.1.13/lib/replace/replace-testsuite.h ldb-1.1.15/lib/replace/replace-testsuite.h --- ldb-1.1.13/lib/replace/replace-testsuite.h 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/replace/replace-testsuite.h 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,10 @@ +#ifndef __LIB_REPLACE_REPLACE_TESTSUITE_H__ +#define __LIB_REPLACE_REPLACE_TESTSUITE_H__ + +#include +struct torture_context; + +bool torture_local_replace(struct torture_context *ctx); + +#endif /* __LIB_REPLACE_REPLACE_TESTSUITE_H__ */ + diff -Nru ldb-1.1.13/lib/replace/replace.c ldb-1.1.15/lib/replace/replace.c --- ldb-1.1.13/lib/replace/replace.c 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/lib/replace/replace.c 2013-01-27 11:51:43.000000000 +0000 @@ -214,16 +214,6 @@ #endif /* HAVE_INITGROUPS */ -#if (defined(SecureWare) && defined(SCO)) -/* This is needed due to needing the nap() function but we don't want - to include the Xenix libraries since that will break other things... - BTW: system call # 0x0c28 is the same as calling nap() */ -long nap(long milliseconds) { - return syscall(0x0c28, milliseconds); - } -#endif - - #ifndef HAVE_MEMMOVE /******************************************************************* safely copies memory, ensuring no overlap problems. @@ -415,7 +405,7 @@ mktemp(template); if (template[0] == 0) return -1; - return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); + return open(template, O_CREAT|O_EXCL|O_RDWR, 0600); } #endif @@ -751,7 +741,7 @@ } #endif -#ifndef HAVE_VDPRINTF +#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_vdprintf(int fd, const char *format, va_list ap) { char *s = NULL; @@ -768,7 +758,7 @@ } #endif -#ifndef HAVE_DPRINTF +#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_dprintf(int fd, const char *format, ...) { int ret; @@ -795,7 +785,7 @@ } #endif -#if !defined(HAVE_STRERROR_R) || !defined(STRERROR_R_PROTO_COMPATIBLE) +#ifndef HAVE_STRERROR_R int rep_strerror_r(int errnum, char *buf, size_t buflen) { char *s = strerror(errnum); @@ -904,3 +894,9 @@ return 0; } #endif /* HAVE_USLEEP */ + +#ifndef HAVE_SETPROCTITLE +void rep_setproctitle(const char *fmt, ...) +{ +} +#endif diff -Nru ldb-1.1.13/lib/replace/replace.h ldb-1.1.15/lib/replace/replace.h --- ldb-1.1.13/lib/replace/replace.h 2012-09-12 20:47:32.000000000 +0000 +++ ldb-1.1.15/lib/replace/replace.h 2013-01-27 11:51:43.000000000 +0000 @@ -128,6 +128,10 @@ #include #endif +#ifdef HAVE_SETPROCTITLE_H +#include +#endif + #if STDC_HEADERS #include #include @@ -372,16 +376,6 @@ /* prototype is in system/network.h */ #endif -#ifndef HAVE_VDPRINTF -#define vdprintf rep_vdprintf -int rep_vdprintf(int fd, const char *format, va_list ap); -#endif - -#ifndef HAVE_DPRINTF -#define dprintf rep_dprintf -int rep_dprintf(int fd, const char *format, ...); -#endif - #ifndef PRINTF_ATTRIBUTE #if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) /** Use gcc attribute to check printf fns. a1 is the 1-based index of @@ -402,7 +396,17 @@ #endif #endif -#ifndef HAVE_VASPRINTF +#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define vdprintf rep_vdprintf +int rep_vdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +#endif + +#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define dprintf rep_dprintf +int rep_dprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define vasprintf rep_vasprintf int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); #endif @@ -417,11 +421,29 @@ int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); #endif -#ifndef HAVE_ASPRINTF +#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) #define asprintf rep_asprintf int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); #endif +#if !defined(HAVE_C99_VSNPRINTF) +#ifdef REPLACE_BROKEN_PRINTF +/* + * We do not redefine printf by default + * as it breaks the build if system headers + * use __attribute__((format(printf, 3, 0))) + * instead of __attribute__((format(__printf__, 3, 0))) + */ +#define printf rep_printf +#endif +int rep_printf(const char *, ...) PRINTF_ATTRIBUTE(1,2); +#endif + +#if !defined(HAVE_C99_VSNPRINTF) +#define fprintf rep_fprintf +int rep_fprintf(FILE *stream, const char *, ...) PRINTF_ATTRIBUTE(2,3); +#endif + #ifndef HAVE_VSYSLOG #ifdef HAVE_SYSLOG #define vsyslog rep_vsyslog @@ -548,8 +570,7 @@ char *rep_get_current_dir_name(void); #endif -#if !defined(HAVE_STRERROR_R) || !defined(STRERROR_R_PROTO_COMPATIBLE) -#undef strerror_r +#ifndef HAVE_STRERROR_R #define strerror_r rep_strerror_r int rep_strerror_r(int errnum, char *buf, size_t buflen); #endif @@ -823,17 +844,6 @@ /* prototype is in "system/network.h" */ #endif -#if !defined(getpass) -#ifdef REPLACE_GETPASS -#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE) -#define getpass(prompt) getpassphrase(prompt) -#else -#define getpass(prompt) rep_getpass(prompt) -char *rep_getpass(const char *prompt); -#endif -#endif -#endif - #ifndef HAVE_GETPEEREID #define getpeereid rep_getpeereid int rep_getpeereid(int s, uid_t *uid, gid_t *gid); @@ -845,4 +855,9 @@ int usleep(useconds_t); #endif +#ifndef HAVE_SETPROCTITLE +#define setproctitle rep_setproctitle +void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); +#endif + #endif /* _LIBREPLACE_REPLACE_H */ diff -Nru ldb-1.1.13/lib/replace/snprintf.c ldb-1.1.15/lib/replace/snprintf.c --- ldb-1.1.13/lib/replace/snprintf.c 2012-06-08 10:37:05.000000000 +0000 +++ ldb-1.1.15/lib/replace/snprintf.c 2013-01-27 11:51:43.000000000 +0000 @@ -1256,7 +1256,7 @@ #endif -#ifndef HAVE_VASPRINTF +#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_vasprintf(char **ptr, const char *format, va_list ap) { int ret; @@ -1278,8 +1278,7 @@ } #endif - -#ifndef HAVE_ASPRINTF +#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) int rep_asprintf(char **ptr, const char *format, ...) { va_list ap; diff -Nru ldb-1.1.13/lib/replace/system/passwd.h ldb-1.1.15/lib/replace/system/passwd.h --- ldb-1.1.13/lib/replace/system/passwd.h 2012-06-18 08:05:37.000000000 +0000 +++ ldb-1.1.15/lib/replace/system/passwd.h 2013-01-27 11:51:43.000000000 +0000 @@ -67,17 +67,6 @@ #include #endif -#if !defined(getpass) -#ifdef REPLACE_GETPASS -#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE) -#define getpass(prompt) getpassphrase(prompt) -#else -#define getpass(prompt) rep_getpass(prompt) -char *rep_getpass(const char *prompt); -#endif -#endif -#endif - #ifndef NGROUPS_MAX #define NGROUPS_MAX 32 /* Guess... */ #endif diff -Nru ldb-1.1.13/lib/replace/system/wait.h ldb-1.1.15/lib/replace/system/wait.h --- ldb-1.1.13/lib/replace/system/wait.h 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/system/wait.h 2013-01-27 11:51:43.000000000 +0000 @@ -40,6 +40,10 @@ #include #endif +#ifdef HAVE_SYS_UCONTEXT_H +#include +#endif + #if !defined(HAVE_SIG_ATOMIC_T_TYPE) typedef int sig_atomic_t; #endif diff -Nru ldb-1.1.13/lib/replace/test/main.c ldb-1.1.15/lib/replace/test/main.c --- ldb-1.1.13/lib/replace/test/main.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/test/main.c 2013-01-27 11:51:43.000000000 +0000 @@ -24,9 +24,7 @@ */ #include "replace.h" - -struct torture_context; -bool torture_local_replace(struct torture_context *ctx); +#include "replace-testsuite.h" int main(void) { diff -Nru ldb-1.1.13/lib/replace/test/testsuite.c ldb-1.1.15/lib/replace/test/testsuite.c --- ldb-1.1.13/lib/replace/test/testsuite.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/replace/test/testsuite.c 2013-01-27 11:51:43.000000000 +0000 @@ -24,6 +24,8 @@ */ #include "replace.h" +#include "replace-test.h" +#include "replace-testsuite.h" /* we include all the system/ include files here so that libreplace tests @@ -48,8 +50,6 @@ #define TESTFILE "testfile.dat" -struct torture_context; -bool torture_local_replace(struct torture_context *ctx); /* test ftruncate() function @@ -379,8 +379,6 @@ return true; } -extern int test_readdir_os2_delete(void); - static int test_readdir(void) { printf("test: readdir\n"); @@ -465,12 +463,6 @@ return true; } -static int test_getpass(void) -{ - /* FIXME */ - return true; -} - static int test_inet_ntoa(void) { /* FIXME */ @@ -1091,7 +1083,6 @@ ret &= test_mkstemp(); ret &= test_pread(); ret &= test_pwrite(); - ret &= test_getpass(); ret &= test_inet_ntoa(); ret &= test_strtoll(); ret &= test_strtoull(); diff -Nru ldb-1.1.13/lib/replace/wscript ldb-1.1.15/lib/replace/wscript --- ldb-1.1.13/lib/replace/wscript 2012-09-12 20:47:32.000000000 +0000 +++ ldb-1.1.15/lib/replace/wscript 2013-01-27 11:51:43.000000000 +0000 @@ -43,6 +43,32 @@ conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) conf.DEFINE('_BSD_TYPES', 1, add_to_cflags=True) + # Try to find the right extra flags for C99 initialisers + for f in ["", "-AC99", "-qlanglvl=extc99", "-qlanglvl=stdc99", "-c99"]: + if conf.CHECK_CFLAGS([f], ''' +struct foo {int x;char y;}; +struct foo bar = { .y = 'X', .x = 1 }; +'''): + if f != "": + conf.ADD_CFLAGS(f) + break + + if conf.CHECK_CFLAGS(['-Wstack-protector']): + conf.ADD_CFLAGS('-Wstack-protector') + + # Try to find the right extra flags for -Werror behaviour + for f in ["-Werror", # GCC + "-errwarn=%all", # Sun Studio + "-qhalt=w", # IBM xlc + "-w2", # Tru64 + ]: + if conf.CHECK_CFLAGS([f], ''' +'''): + if not 'WERROR_CFLAGS' in conf.env: + conf.env['WERROR_CFLAGS'] = [] + conf.env['WERROR_CFLAGS'].extend([f]) + break + conf.CHECK_HEADERS('linux/types.h crypt.h locale.h acl/libacl.h compat.h') conf.CHECK_HEADERS('acl/libacl.h attr/xattr.h compat.h ctype.h dustat.h') conf.CHECK_HEADERS('fcntl.h fnmatch.h glob.h history.h krb5.h langinfo.h') @@ -53,7 +79,7 @@ conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h') conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h') conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h') - conf.CHECK_HEADERS('sys/wait.h sys/stat.h malloc.h grp.h') + conf.CHECK_HEADERS('sys/ucontext.h sys/wait.h sys/stat.h malloc.h grp.h') conf.CHECK_HEADERS('sys/select.h setjmp.h utime.h sys/syslog.h syslog.h') conf.CHECK_HEADERS('stdarg.h vararg.h sys/mount.h mntent.h') conf.CHECK_HEADERS('stropts.h unix.h string.h strings.h sys/param.h limits.h') @@ -70,13 +96,27 @@ conf.CHECK_HEADERS('rpcsvc/nis.h rpcsvc/ypclnt.h sys/prctl.h sys/sysctl.h') conf.CHECK_HEADERS('sys/fileio.h sys/filesys.h sys/dustat.h sys/sysmacros.h') - conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h rpcsvc/yp_prot.h') + conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h') + + conf.CHECK_CODE('', headers='rpc/rpc.h rpcsvc/yp_prot.h', define='HAVE_RPCSVC_YP_PROT_H') + conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h valgrind/memcheck.h') conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h') conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h') conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h malloc.h') conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h') + conf.CHECK_CODE(''' + #include + #ifdef HAVE_FCNTL_H + #include + #endif + int main(void) { int fd = open("/dev/null", O_DIRECT); } + ''', + define='HAVE_OPEN_O_DIRECT', + addmain=False, + msg='Checking for O_DIRECT flag to open(2)') + conf.CHECK_TYPES('"long long" intptr_t uintptr_t ptrdiff_t comparison_fn_t') conf.CHECK_TYPE('_Bool', define='HAVE__Bool') conf.CHECK_TYPE('bool', define='HAVE_BOOL') @@ -163,6 +203,15 @@ lib='nsl socket', headers='sys/socket.h netdb.h netinet/in.h') + if conf.CONFIG_SET('HAVE_SYS_UCONTEXT_H') and conf.CONFIG_SET('HAVE_SIGNAL_H'): + conf.CHECK_CODE(''' + ucontext_t uc; + sigaddset(&uc.uc_sigmask, SIGUSR1); + ''', + 'HAVE_UCONTEXT_T', + msg="Checking whether we have ucontext_t", + headers='signal.h sys/ucontext.h') + # these may be builtins, so we need the link=False strategy conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False) @@ -183,6 +232,8 @@ checklibc=True) if not conf.CHECK_FUNCS('getpeereid'): conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h') + if not conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h'): + conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h') conf.CHECK_CODE(''' struct ucred cred; @@ -206,7 +257,6 @@ msg="Checking correct behavior of strtoll", headers = 'errno.h', execute = True, - define_ret = True, define = 'HAVE_BSD_STRTOLL', ) conf.CHECK_FUNCS('if_nametoindex strerror_r') @@ -233,7 +283,7 @@ attr_get attr_getf attr_list attr_listf attropen attr_remove attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file -extattr_set_fd extattr_set_file fgetea flistea +extattr_set_fd extattr_set_file fgetea fremoveea fsetea getea listea removeea setea ''', 'attr', checklibc=True, headers=xattr_headers) @@ -399,11 +449,26 @@ conf.CHECK_CODE(''' struct stat st; char tpl[20]="/tmp/test.XXXXXX"; + char tpl2[20]="/tmp/test.XXXXXX"; int fd = mkstemp(tpl); - if (fd == -1) exit(1); + int fd2 = mkstemp(tpl2); + if (fd == -1) { + if (fd2 != -1) { + unlink(tpl2); + } + exit(1); + } + if (fd2 == -1) exit(1); unlink(tpl); + unlink(tpl2); if (fstat(fd, &st) != 0) exit(1); if ((st.st_mode & 0777) != 0600) exit(1); + if (strcmp(tpl, "/tmp/test.XXXXXX") == 0) { + exit(1); + } + if (strcmp(tpl, tpl2) == 0) { + exit(1); + } exit(0); ''', define='HAVE_SECURE_MKSTEMP', @@ -437,17 +502,6 @@ execute=True): break - if conf.CHECK_FUNCS('getpass getpassphrase'): - # if we have both, then we prefer getpassphrase - conf.DEFINE('REPLACE_GETPASS_BY_GETPASSPHRASE', 1) - conf.DEFINE('REPLACE_GETPASS', 1) - else: - conf.CHECK_CODE('''#include "getpass.c" - int main(void) { return 0; }''', - addmain=False, - define='REPLACE_GETPASS', - cflags='-DNO_CONFIG_H') - conf.RECURSE('system') conf.SAMBA_CONFIG_H() @@ -497,7 +551,6 @@ REPLACE_SOURCE = REPLACE_HOSTCC_SOURCE - if bld.CONFIG_SET('REPLACE_GETPASS'): REPLACE_SOURCE += ' getpass.c' if not bld.CONFIG_SET('HAVE_CRYPT'): REPLACE_SOURCE += ' crypt.c' if not bld.CONFIG_SET('HAVE_DLOPEN'): REPLACE_SOURCE += ' dlfcn.c' if not bld.CONFIG_SET('HAVE_POLL'): REPLACE_SOURCE += ' poll.c' diff -Nru ldb-1.1.13/lib/replace/xattr.c ldb-1.1.15/lib/replace/xattr.c --- ldb-1.1.13/lib/replace/xattr.c 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/lib/replace/xattr.c 2013-01-27 11:51:43.000000000 +0000 @@ -71,7 +71,9 @@ * that the buffer is large enough to fit the returned value. */ if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { - if(retval > size) { + if (size == 0) { + return retval; + } else if (retval > size) { errno = ERANGE; return -1; } @@ -88,6 +90,9 @@ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; retval = attr_get(path, attrname, (char *)value, &valuelength, flags); + if (size == 0 && retval == -1 && errno == E2BIG) { + return valuelength; + } return retval ? retval : valuelength; #elif defined(HAVE_ATTROPEN) @@ -126,7 +131,9 @@ const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1; if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { - if(retval > size) { + if (size == 0) { + return retval; + } else if (retval > size) { errno = ERANGE; return -1; } @@ -143,7 +150,9 @@ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); - + if (size == 0 && retval == -1 && errno == E2BIG) { + return valuelength; + } return retval ? retval : valuelength; #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; diff -Nru ldb-1.1.13/lib/talloc/ABI/pytalloc-util-2.0.8.sigs ldb-1.1.15/lib/talloc/ABI/pytalloc-util-2.0.8.sigs --- ldb-1.1.13/lib/talloc/ABI/pytalloc-util-2.0.8.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/talloc/ABI/pytalloc-util-2.0.8.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff -Nru ldb-1.1.13/lib/talloc/ABI/talloc-2.0.8.sigs ldb-1.1.15/lib/talloc/ABI/talloc-2.0.8.sigs --- ldb-1.1.13/lib/talloc/ABI/talloc-2.0.8.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/talloc/ABI/talloc-2.0.8.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,63 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff -Nru ldb-1.1.13/lib/talloc/man/talloc.3.xml ldb-1.1.15/lib/talloc/man/talloc.3.xml --- ldb-1.1.13/lib/talloc/man/talloc.3.xml 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/talloc/man/talloc.3.xml 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + talloc + 3 + Samba + System Administration tools + 4.0 + + + talloc +hierarchical reference counted memory pool system with destructors + + +#include <talloc.h> + + DESCRIPTION + + If you are used to talloc from Samba3 then please read this + carefully, as talloc has changed a lot. + + + The new talloc is a hierarchical, reference counted memory pool + system with destructors. Quite a mouthful really, but not too bad + once you get used to it. + + + Perhaps the biggest change from Samba3 is that there is no + distinction between a "talloc context" and a "talloc pointer". Any + pointer returned from talloc() is itself a valid talloc context. + This means you can do this: + + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + + + and the pointer X->name + would be a "child" of the talloc context X which is itself a child of + mem_ctx. So if you do + talloc_free(mem_ctx) then + it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if + you do talloc_free(X->name) then just + the name element of X is + destroyed. + + + If you think about this, then what this effectively gives you is an + n-ary tree, where you can free any part of the tree with + talloc_free(). + + + If you find this confusing, then I suggest you run the testsuite program to watch talloc + in action. You may also like to add your own tests to testsuite.c to clarify how some + particular situation is handled. + + + TALLOC API + + The following is a complete guide to the talloc API. Read it all at + least twice. + + (type *)talloc(const void *ctx, type); + + The talloc() macro is the core of the talloc library. It takes a + memory ctx and a type, and returns a pointer to a new + area of memory of the given type. + + + The returned pointer is itself a talloc context, so you can use + it as the ctx argument to more + calls to talloc() if you wish. + + + The returned pointer is a "child" of the supplied context. This + means that if you talloc_free() the ctx then the new child disappears as + well. Alternatively you can free just the child. + + + The ctx argument to talloc() + can be NULL, in which case a new top level context is created. + + + void *talloc_size(const void *ctx, size_t size); + + The function talloc_size() should be used when you don't have a + convenient type to pass to talloc(). Unlike talloc(), it is not + type safe (as it returns a void *), so you are on your own for + type checking. + + + (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + + The talloc_ptrtype() macro should be used when you have a pointer and + want to allocate memory to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + int talloc_free(void *ptr); + + The talloc_free() function frees a piece of talloc memory, and + all its children. You can call talloc_free() on any pointer + returned by talloc(). + + + The return value of talloc_free() indicates success or failure, + with 0 returned for success and -1 for failure. The only + possible failure condition is if ptr had a destructor attached to it and + the destructor returned -1. See talloc_set_destructor() + for details on destructors. + + + If this pointer has an additional parent when talloc_free() is + called then the memory is not actually released, but instead the + most recently established parent is destroyed. See talloc_reference() + for details on establishing additional parents. + + + For more control on which parent is removed, see talloc_unlink(). + + + talloc_free() operates recursively on its children. + + + From the 2.0 version of talloc, as a special case, + talloc_free() is refused on pointers that have more than one + parent, as talloc would have no way of knowing which parent + should be removed. To free a pointer that has more than one + parent please use talloc_unlink(). + + + To help you find problems in your code caused by this behaviour, if + you do try and free a pointer with more than one parent then the + talloc logging function will be called to give output like this: + + + + ERROR: talloc_free with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + + + + Please see the documentation for talloc_set_log_fn() and + talloc_set_log_stderr() for more information on talloc logging + functions. + + + void *talloc_reference(const void *ctx, const void *ptr); + + The talloc_reference() function makes ctx an additional parent of ptr. + + + The return value of talloc_reference() is always the original + pointer ptr, unless talloc ran + out of memory in creating the reference in which case it will + return NULL (each additional reference consumes around 48 bytes + of memory on intel x86 platforms). + + + If ptr is NULL, then the + function is a no-op, and simply returns NULL. + + + After creating a reference you can free it in one of the + following ways: + + + + + + you can talloc_free() any parent of the original pointer. + That will reduce the number of parents of this pointer by 1, + and will cause this pointer to be freed if it runs out of + parents. + + + + + you can talloc_free() the pointer itself. That will destroy + the most recently established parent to the pointer and leave + the pointer as a child of its current parent. + + + + + + For more control on which parent to remove, see talloc_unlink(). + + + int talloc_unlink(const void *ctx, const void *ptr); + + The talloc_unlink() function removes a specific parent from + ptr. The ctx passed must either be a context used + in talloc_reference() with this pointer, or must be a direct + parent of ptr. + + + Note that if the parent has already been removed using + talloc_free() then this function will fail and will return -1. + Likewise, if ptr is NULL, then + the function will make no modifications and return -1. + + + Usually you can just use talloc_free() instead of + talloc_unlink(), but sometimes it is useful to have the + additional control on which parent is removed. + + + void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + + The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called + when the memory used by a pointer is about to be released. The + destructor receives ptr as an + argument, and should return 0 for success and -1 for failure. + + + The destructor can do anything + it wants to, including freeing other pieces of memory. A common + use for destructors is to clean up operating system resources + (such as open file descriptors) contained in the structure the + destructor is placed on. + + + You can only place one destructor on a pointer. If you need more + than one destructor then you can create a zero-length child of + the pointer and place an additional destructor on that. + + + To remove a destructor call talloc_set_destructor() with NULL for + the destructor. + + + If your destructor attempts to talloc_free() the pointer that it + is the destructor for then talloc_free() will return -1 and the + free will be ignored. This would be a pointless operation + anyway, as the destructor is only called when the memory is just + about to go away. + + + int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + + You can use either syntax, depending on which you think is + clearer in your code. + + + It returns 0 on success and -1 on failure. + + + size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); + + Return the number of references to the pointer. + + + void talloc_set_name(const void *ptr, const char *fmt, ...); + + Each talloc pointer has a "name". The name is used principally + for debugging purposes, although it is also possible to set and + get the name on a pointer in as a way of "marking" pointers in + your code. + + + The main use for names on pointer is for "talloc reports". See + talloc_report_depth_cb(), + talloc_report_depth_file(), + talloc_report() + talloc_report() + and talloc_report_full() + for details. Also see talloc_enable_leak_report() + and talloc_enable_leak_report_full(). + + + The talloc_set_name() function allocates memory as a child of the + pointer. It is logically equivalent to: + + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + + Note that multiple calls to talloc_set_name() will allocate more + memory without releasing the name. All of the memory is released + when the ptr is freed using talloc_free(). + + + void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + The function talloc_set_name_const() is just like + talloc_set_name(), but it takes a string constant, and is much + faster. It is extensively used by the "auto naming" macros, such + as talloc_p(). + + + This function does not allocate any memory. It just copies the + supplied pointer into the internal representation of the talloc + ptr. This means you must not pass a name pointer to memory that will + disappear before ptr is freed + with talloc_free(). + + + void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_named() function creates a named talloc pointer. It + is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name(ptr, fmt, ....); + + void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + This is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name_const(ptr, name); + + const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); + + This returns the current name for the given talloc pointer, + ptr. See talloc_set_name() + for details. + + + void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); + + This function creates a zero length named talloc context as a top + level context. It is equivalent to: + + talloc_named(NULL, 0, fmt, ...); + + void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); + + This is a utility macro that creates a new memory context hanging + off an existing context, automatically naming it "talloc_new: + __location__" where __location__ is the source line it is called + from. It is particularly useful for creating a new temporary + working context. + + + (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); + + The talloc_realloc() macro changes the size of a talloc pointer. + It has the following equivalences: + + talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); +talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); + + The ctx argument is only used + if ptr is not NULL, otherwise + it is ignored. + + + talloc_realloc() returns the new pointer, or NULL on failure. + The call will fail either due to a lack of memory, or because the + pointer has more than one parent (see talloc_reference()). + + + void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); + + the talloc_realloc_size() function is useful when the type is not + known so the type-safe talloc_realloc() cannot be used. + + + TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); + + The talloc_steal() function changes the parent context of a + talloc pointer. It is typically used when the context that the + pointer is currently a child of is going to be freed and you wish + to keep the memory for a longer time. + + + The talloc_steal() function returns the pointer that you pass it. + It does not have any failure modes. + + + It is possible to produce loops in the parent/child + relationship if you are not careful with talloc_steal(). No + guarantees are provided as to your sanity or the safety of your + data if you do this. + + + Note that if you try and call talloc_steal() on a pointer that has + more than one parent then the result is ambiguous. Talloc will choose + to remove the parent that is currently indicated by talloc_parent() + and replace it with the chosen parent. You will also get a message + like this via the talloc logging functions: + + + + WARNING: talloc_steal with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + + + + To unambiguously change the parent of a pointer please see + the + function talloc_reparent(). See + the talloc_set_log_fn() documentation for more information + on talloc logging. + + + TYPE *talloc_reparent(const void *<emphasis role="italic">old_parent</emphasis>, const void *<emphasis role="italic">new_parent</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); + + The talloc_reparent() function changes the parent context of a talloc + pointer. It is typically used when the context that the pointer is + currently a child of is going to be freed and you wish to keep the + memory for a longer time. + + + The talloc_reparent() function returns the pointer that you pass it. It + does not have any failure modes. + + + The difference between talloc_reparent() and talloc_steal() is that + talloc_reparent() can specify which parent you wish to change. This is + useful when a pointer has multiple parents via references. + + + TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); + + The talloc_move() function is a wrapper around + talloc_steal() which zeros the source pointer after the + move. This avoids a potential source of bugs where a + programmer leaves a pointer in two structures, and uses the + pointer from the old structure after it has been moved to a + new one. + + + size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_size() function returns the total size in bytes + used by this pointer and all child pointers. Mostly useful for + debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_blocks() function returns the total memory block + count used by this pointer and all child pointers. Mostly useful + for debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + void talloc_report(const void *ptr, FILE *f); + + The talloc_report() function prints a summary report of all + memory used by ptr. One line + of report is printed for each immediate child of ptr, showing the + total memory and number of blocks used by that child. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); + + This provides a more detailed report than talloc_report(). It + will recursively print the entire tree of memory referenced by + the pointer. References in the tree are shown by giving the name + of the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + + + void talloc_report_depth_cb + const void *ptr + int depth + int max_depth + void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) + void *priv + + + This provides a more flexible reports than talloc_report(). It + will recursively call the callback for the entire tree of memory + referenced by the pointer. References in the tree are passed with + is_ref = 1 and the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + The recursion is stopped when depth >= max_depth. + max_depth = -1 means only stop at leaf nodes. + + + + + void talloc_report_depth_file + const void *ptr + int depth + int max_depth + FILE *f + + + This provides a more flexible reports than talloc_report(). It + will let you specify the depth and max_depth. + + + void talloc_enable_leak_report(void); + + This enables calling of talloc_report(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical talloc report: + + talloc report on 'null_context' (total 267 bytes in 15 blocks) +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(UTF8,CP850) contains 42 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(CP850,UTF8) contains 42 bytes in 2 blocks +iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks +iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + + void talloc_enable_leak_report_full(void); + + This enables calling of talloc_report_full(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report-full command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical full report: + + full talloc report on 'root' (total 18 bytes in 8 blocks) +p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + + (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); + + The talloc_zero() macro is equivalent to: + + ptr = talloc(ctx, type); +if (ptr) memset(ptr, 0, sizeof(type)); + + void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) + + The talloc_zero_size() function is useful when you don't have a + known type. + + + void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); + + The talloc_memdup() function is equivalent to: + + ptr = talloc_size(ctx, size); +if (ptr) memcpy(ptr, p, size); + + char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); + + The talloc_strdup() function is equivalent to: + + ptr = talloc_size(ctx, strlen(p)+1); +if (ptr) memcpy(ptr, p, strlen(p)+1); + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); + + The talloc_strndup() function is the talloc equivalent of the C + library function strndup(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); + + The talloc_vasprintf() function is the talloc equivalent of the C + library function vasprintf(3). + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_asprintf() function is the talloc equivalent of the C + library function asprintf(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf_append(char *s, const char *fmt, ...); + + The talloc_asprintf_append() function appends the given formatted + string to the given string. + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + (type *)talloc_array(const void *ctx, type, unsigned int count); + + The talloc_array() macro is equivalent to: + + (type *)talloc_size(ctx, sizeof(type) * count); + + except that it provides integer overflow protection for the + multiply, returning NULL if the multiply overflows. + + + void *talloc_array_size(const void *ctx, size_t size, unsigned int count); + + The talloc_array_size() function is useful when the type is not + known. It operates in the same way as talloc_array(), but takes a + size instead of a type. + + + (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); + + The talloc_ptrtype() macro should be used when you have a pointer to an array + and want to allocate memory of an array to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) + + This is a non-macro version of talloc_realloc(), which is useful + as libraries sometimes want a realloc function pointer. A + realloc(3) implementation encapsulates the functionality of + malloc(3), free(3) and realloc(3) in one call, which is why it is + useful to be able to pass around a single function pointer. + + + void *talloc_autofree_context(void); + + This is a handy utility function that returns a talloc context + which will be automatically freed on program exit. This can be + used to reduce the noise in memory leak reports. + + + void *talloc_check_name(const void *ptr, const char *name); + + This function checks if a pointer has the specified name. If it does then the pointer is + returned. It it doesn't then NULL is returned. + + + (type *)talloc_get_type(const void *ptr, type); + + This macro allows you to do type checking on talloc pointers. It + is particularly useful for void* private pointers. It is + equivalent to this: + + (type *)talloc_check_name(ptr, #type) + + talloc_set_type(const void *ptr, type); + + This macro allows you to force the name of a pointer to be a + particular type. This can be + used in conjunction with talloc_get_type() to do type checking on + void* pointers. + + + It is equivalent to this: + + talloc_set_name_const(ptr, #type) + + talloc_set_log_fn(void (*log_fn)(const char *message)); + + This function sets a logging function that talloc will use for + warnings and errors. By default talloc will not print any warnings or + errors. + + + talloc_set_log_stderr(void); + + This sets the talloc log function to write log messages to stderr + + + + PERFORMANCE + + All the additional features of talloc(3) over malloc(3) do come at a + price. We have a simple performance test in Samba4 that measures + talloc() versus malloc() performance, and it seems that talloc() is + about 10% slower than malloc() on my x86 Debian Linux box. For + Samba, the great reduction in code complexity that we get by using + talloc makes this worthwhile, especially as the total overhead of + talloc/malloc in Samba is already quite small. + + + SEE ALSO + + malloc(3), strndup(3), vasprintf(3), asprintf(3), + + + + + AUTHOR + The original Samba software and related utilities were + created by Andrew Tridgell. Samba is now developed by the + Samba Team as an Open Source project similar to the way the + Linux kernel is developed. + + + + COPYRIGHT/LICENSE + + Copyright (C) Andrew Tridgell 2004 + + + This program 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 3 of the + License, or (at your option) any later version. + + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + + You should have received a copy of the GNU General Public License + along with this program; if not, see http://www.gnu.org/licenses/. + + + diff -Nru ldb-1.1.13/lib/talloc/talloc.3.xml ldb-1.1.15/lib/talloc/talloc.3.xml --- ldb-1.1.13/lib/talloc/talloc.3.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/talloc/talloc.3.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,801 +0,0 @@ - - - - - talloc - 3 - - - talloc -hierarchical reference counted memory pool system with destructors - - -#include <talloc.h> - - DESCRIPTION - - If you are used to talloc from Samba3 then please read this - carefully, as talloc has changed a lot. - - - The new talloc is a hierarchical, reference counted memory pool - system with destructors. Quite a mouthful really, but not too bad - once you get used to it. - - - Perhaps the biggest change from Samba3 is that there is no - distinction between a "talloc context" and a "talloc pointer". Any - pointer returned from talloc() is itself a valid talloc context. - This means you can do this: - - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - - - and the pointer X->name - would be a "child" of the talloc context X which is itself a child of - mem_ctx. So if you do - talloc_free(mem_ctx) then - it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if - you do talloc_free(X->name) then just - the name element of X is - destroyed. - - - If you think about this, then what this effectively gives you is an - n-ary tree, where you can free any part of the tree with - talloc_free(). - - - If you find this confusing, then I suggest you run the testsuite program to watch talloc - in action. You may also like to add your own tests to testsuite.c to clarify how some - particular situation is handled. - - - TALLOC API - - The following is a complete guide to the talloc API. Read it all at - least twice. - - (type *)talloc(const void *ctx, type); - - The talloc() macro is the core of the talloc library. It takes a - memory ctx and a type, and returns a pointer to a new - area of memory of the given type. - - - The returned pointer is itself a talloc context, so you can use - it as the ctx argument to more - calls to talloc() if you wish. - - - The returned pointer is a "child" of the supplied context. This - means that if you talloc_free() the ctx then the new child disappears as - well. Alternatively you can free just the child. - - - The ctx argument to talloc() - can be NULL, in which case a new top level context is created. - - - void *talloc_size(const void *ctx, size_t size); - - The function talloc_size() should be used when you don't have a - convenient type to pass to talloc(). Unlike talloc(), it is not - type safe (as it returns a void *), so you are on your own for - type checking. - - - (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - - The talloc_ptrtype() macro should be used when you have a pointer and - want to allocate memory to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - int talloc_free(void *ptr); - - The talloc_free() function frees a piece of talloc memory, and - all its children. You can call talloc_free() on any pointer - returned by talloc(). - - - The return value of talloc_free() indicates success or failure, - with 0 returned for success and -1 for failure. The only - possible failure condition is if ptr had a destructor attached to it and - the destructor returned -1. See talloc_set_destructor() - for details on destructors. - - - If this pointer has an additional parent when talloc_free() is - called then the memory is not actually released, but instead the - most recently established parent is destroyed. See talloc_reference() - for details on establishing additional parents. - - - For more control on which parent is removed, see talloc_unlink(). - - - talloc_free() operates recursively on its children. - - - From the 2.0 version of talloc, as a special case, - talloc_free() is refused on pointers that have more than one - parent, as talloc would have no way of knowing which parent - should be removed. To free a pointer that has more than one - parent please use talloc_unlink(). - - - To help you find problems in your code caused by this behaviour, if - you do try and free a pointer with more than one parent then the - talloc logging function will be called to give output like this: - - - - ERROR: talloc_free with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - - - - Please see the documentation for talloc_set_log_fn() and - talloc_set_log_stderr() for more information on talloc logging - functions. - - - void *talloc_reference(const void *ctx, const void *ptr); - - The talloc_reference() function makes ctx an additional parent of ptr. - - - The return value of talloc_reference() is always the original - pointer ptr, unless talloc ran - out of memory in creating the reference in which case it will - return NULL (each additional reference consumes around 48 bytes - of memory on intel x86 platforms). - - - If ptr is NULL, then the - function is a no-op, and simply returns NULL. - - - After creating a reference you can free it in one of the - following ways: - - - - - - you can talloc_free() any parent of the original pointer. - That will reduce the number of parents of this pointer by 1, - and will cause this pointer to be freed if it runs out of - parents. - - - - - you can talloc_free() the pointer itself. That will destroy - the most recently established parent to the pointer and leave - the pointer as a child of its current parent. - - - - - - For more control on which parent to remove, see talloc_unlink(). - - - int talloc_unlink(const void *ctx, const void *ptr); - - The talloc_unlink() function removes a specific parent from - ptr. The ctx passed must either be a context used - in talloc_reference() with this pointer, or must be a direct - parent of ptr. - - - Note that if the parent has already been removed using - talloc_free() then this function will fail and will return -1. - Likewise, if ptr is NULL, then - the function will make no modifications and return -1. - - - Usually you can just use talloc_free() instead of - talloc_unlink(), but sometimes it is useful to have the - additional control on which parent is removed. - - - void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - - The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called - when the memory used by a pointer is about to be released. The - destructor receives ptr as an - argument, and should return 0 for success and -1 for failure. - - - The destructor can do anything - it wants to, including freeing other pieces of memory. A common - use for destructors is to clean up operating system resources - (such as open file descriptors) contained in the structure the - destructor is placed on. - - - You can only place one destructor on a pointer. If you need more - than one destructor then you can create a zero-length child of - the pointer and place an additional destructor on that. - - - To remove a destructor call talloc_set_destructor() with NULL for - the destructor. - - - If your destructor attempts to talloc_free() the pointer that it - is the destructor for then talloc_free() will return -1 and the - free will be ignored. This would be a pointless operation - anyway, as the destructor is only called when the memory is just - about to go away. - - - int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - - You can use either syntax, depending on which you think is - clearer in your code. - - - It returns 0 on success and -1 on failure. - - - size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); - - Return the number of references to the pointer. - - - void talloc_set_name(const void *ptr, const char *fmt, ...); - - Each talloc pointer has a "name". The name is used principally - for debugging purposes, although it is also possible to set and - get the name on a pointer in as a way of "marking" pointers in - your code. - - - The main use for names on pointer is for "talloc reports". See - talloc_report_depth_cb(), - talloc_report_depth_file(), - talloc_report() - talloc_report() - and talloc_report_full() - for details. Also see talloc_enable_leak_report() - and talloc_enable_leak_report_full(). - - - The talloc_set_name() function allocates memory as a child of the - pointer. It is logically equivalent to: - - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - - Note that multiple calls to talloc_set_name() will allocate more - memory without releasing the name. All of the memory is released - when the ptr is freed using talloc_free(). - - - void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - The function talloc_set_name_const() is just like - talloc_set_name(), but it takes a string constant, and is much - faster. It is extensively used by the "auto naming" macros, such - as talloc_p(). - - - This function does not allocate any memory. It just copies the - supplied pointer into the internal representation of the talloc - ptr. This means you must not pass a name pointer to memory that will - disappear before ptr is freed - with talloc_free(). - - - void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_named() function creates a named talloc pointer. It - is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name(ptr, fmt, ....); - - void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - This is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name_const(ptr, name); - - const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); - - This returns the current name for the given talloc pointer, - ptr. See talloc_set_name() - for details. - - - void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); - - This function creates a zero length named talloc context as a top - level context. It is equivalent to: - - talloc_named(NULL, 0, fmt, ...); - - void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); - - This is a utility macro that creates a new memory context hanging - off an existing context, automatically naming it "talloc_new: - __location__" where __location__ is the source line it is called - from. It is particularly useful for creating a new temporary - working context. - - - (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); - - The talloc_realloc() macro changes the size of a talloc pointer. - It has the following equivalences: - - talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); -talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); - - The ctx argument is only used - if ptr is not NULL, otherwise - it is ignored. - - - talloc_realloc() returns the new pointer, or NULL on failure. - The call will fail either due to a lack of memory, or because the - pointer has more than one parent (see talloc_reference()). - - - void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); - - the talloc_realloc_size() function is useful when the type is not - known so the type-safe talloc_realloc() cannot be used. - - - TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); - - The talloc_steal() function changes the parent context of a - talloc pointer. It is typically used when the context that the - pointer is currently a child of is going to be freed and you wish - to keep the memory for a longer time. - - - The talloc_steal() function returns the pointer that you pass it. - It does not have any failure modes. - - - It is possible to produce loops in the parent/child - relationship if you are not careful with talloc_steal(). No - guarantees are provided as to your sanity or the safety of your - data if you do this. - - - Note that if you try and call talloc_steal() on a pointer that has - more than one parent then the result is ambiguous. Talloc will choose - to remove the parent that is currently indicated by talloc_parent() - and replace it with the chosen parent. You will also get a message - like this via the talloc logging functions: - - - - WARNING: talloc_steal with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - - - - To unambiguously change the parent of a pointer please see - the - function talloc_reparent(). See - the talloc_set_log_fn() documentation for more information - on talloc logging. - - - TYPE *talloc_reparent(const void *<emphasis role="italic">old_parent</emphasis>, const void *<emphasis role="italic">new_parent</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); - - The talloc_reparent() function changes the parent context of a talloc - pointer. It is typically used when the context that the pointer is - currently a child of is going to be freed and you wish to keep the - memory for a longer time. - - - The talloc_reparent() function returns the pointer that you pass it. It - does not have any failure modes. - - - The difference between talloc_reparent() and talloc_steal() is that - talloc_reparent() can specify which parent you wish to change. This is - useful when a pointer has multiple parents via references. - - - TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); - - The talloc_move() function is a wrapper around - talloc_steal() which zeros the source pointer after the - move. This avoids a potential source of bugs where a - programmer leaves a pointer in two structures, and uses the - pointer from the old structure after it has been moved to a - new one. - - - size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_size() function returns the total size in bytes - used by this pointer and all child pointers. Mostly useful for - debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_blocks() function returns the total memory block - count used by this pointer and all child pointers. Mostly useful - for debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - void talloc_report(const void *ptr, FILE *f); - - The talloc_report() function prints a summary report of all - memory used by ptr. One line - of report is printed for each immediate child of ptr, showing the - total memory and number of blocks used by that child. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); - - This provides a more detailed report than talloc_report(). It - will recursively print the entire tree of memory referenced by - the pointer. References in the tree are shown by giving the name - of the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - - - void talloc_report_depth_cb - const void *ptr - int depth - int max_depth - void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) - void *priv - - - This provides a more flexible reports than talloc_report(). It - will recursively call the callback for the entire tree of memory - referenced by the pointer. References in the tree are passed with - is_ref = 1 and the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - The recursion is stopped when depth >= max_depth. - max_depth = -1 means only stop at leaf nodes. - - - - - void talloc_report_depth_file - const void *ptr - int depth - int max_depth - FILE *f - - - This provides a more flexible reports than talloc_report(). It - will let you specify the depth and max_depth. - - - void talloc_enable_leak_report(void); - - This enables calling of talloc_report(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical talloc report: - - talloc report on 'null_context' (total 267 bytes in 15 blocks) -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(UTF8,CP850) contains 42 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(CP850,UTF8) contains 42 bytes in 2 blocks -iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks -iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - - void talloc_enable_leak_report_full(void); - - This enables calling of talloc_report_full(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report-full command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical full report: - - full talloc report on 'root' (total 18 bytes in 8 blocks) -p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - - (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); - - The talloc_zero() macro is equivalent to: - - ptr = talloc(ctx, type); -if (ptr) memset(ptr, 0, sizeof(type)); - - void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) - - The talloc_zero_size() function is useful when you don't have a - known type. - - - void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); - - The talloc_memdup() function is equivalent to: - - ptr = talloc_size(ctx, size); -if (ptr) memcpy(ptr, p, size); - - char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); - - The talloc_strdup() function is equivalent to: - - ptr = talloc_size(ctx, strlen(p)+1); -if (ptr) memcpy(ptr, p, strlen(p)+1); - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); - - The talloc_strndup() function is the talloc equivalent of the C - library function strndup(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); - - The talloc_vasprintf() function is the talloc equivalent of the C - library function vasprintf(3). - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_asprintf() function is the talloc equivalent of the C - library function asprintf(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf_append(char *s, const char *fmt, ...); - - The talloc_asprintf_append() function appends the given formatted - string to the given string. - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - (type *)talloc_array(const void *ctx, type, unsigned int count); - - The talloc_array() macro is equivalent to: - - (type *)talloc_size(ctx, sizeof(type) * count); - - except that it provides integer overflow protection for the - multiply, returning NULL if the multiply overflows. - - - void *talloc_array_size(const void *ctx, size_t size, unsigned int count); - - The talloc_array_size() function is useful when the type is not - known. It operates in the same way as talloc_array(), but takes a - size instead of a type. - - - (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); - - The talloc_ptrtype() macro should be used when you have a pointer to an array - and want to allocate memory of an array to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) - - This is a non-macro version of talloc_realloc(), which is useful - as libraries sometimes want a realloc function pointer. A - realloc(3) implementation encapsulates the functionality of - malloc(3), free(3) and realloc(3) in one call, which is why it is - useful to be able to pass around a single function pointer. - - - void *talloc_autofree_context(void); - - This is a handy utility function that returns a talloc context - which will be automatically freed on program exit. This can be - used to reduce the noise in memory leak reports. - - - void *talloc_check_name(const void *ptr, const char *name); - - This function checks if a pointer has the specified name. If it does then the pointer is - returned. It it doesn't then NULL is returned. - - - (type *)talloc_get_type(const void *ptr, type); - - This macro allows you to do type checking on talloc pointers. It - is particularly useful for void* private pointers. It is - equivalent to this: - - (type *)talloc_check_name(ptr, #type) - - talloc_set_type(const void *ptr, type); - - This macro allows you to force the name of a pointer to be a - particular type. This can be - used in conjunction with talloc_get_type() to do type checking on - void* pointers. - - - It is equivalent to this: - - talloc_set_name_const(ptr, #type) - - talloc_set_log_fn(void (*log_fn)(const char *message)); - - This function sets a logging function that talloc will use for - warnings and errors. By default talloc will not print any warnings or - errors. - - - talloc_set_log_stderr(void); - - This sets the talloc log function to write log messages to stderr - - - - PERFORMANCE - - All the additional features of talloc(3) over malloc(3) do come at a - price. We have a simple performance test in Samba4 that measures - talloc() versus malloc() performance, and it seems that talloc() is - about 10% slower than malloc() on my x86 Debian Linux box. For - Samba, the great reduction in code complexity that we get by using - talloc makes this worthwhile, especially as the total overhead of - talloc/malloc in Samba is already quite small. - - - SEE ALSO - - malloc(3), strndup(3), vasprintf(3), asprintf(3), - - - - COPYRIGHT/LICENSE - - Copyright (C) Andrew Tridgell 2004 - - - This program 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 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - - You should have received a copy of the GNU General Public License - along with this program; if not, see http://www.gnu.org/licenses/. - - - diff -Nru ldb-1.1.13/lib/talloc/talloc.c ldb-1.1.15/lib/talloc/talloc.c --- ldb-1.1.13/lib/talloc/talloc.c 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/lib/talloc/talloc.c 2013-01-27 11:51:43.000000000 +0000 @@ -71,6 +71,7 @@ #define TALLOC_FLAG_LOOP 0x02 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ + #define TALLOC_MAGIC_REFERENCE ((const char *)1) /* by default we abort when given a bad pointer (such as when talloc_free() is called @@ -227,6 +228,17 @@ const char *location; }; +struct talloc_memlimit { + struct talloc_chunk *parent; + struct talloc_memlimit *upper; + size_t max_size; + size_t cur_size; +}; + +static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); +static bool talloc_memlimit_update(struct talloc_memlimit *limit, + size_t old_size, size_t new_size); + typedef int (*talloc_destructor_t)(void *); struct talloc_chunk { @@ -239,6 +251,15 @@ unsigned flags; /* + * limit semantics: + * if 'limit' is set it means all *new* children of the context will + * be limited to a total aggregate size ox max_size for memory + * allocations. + * cur_size is used to kep track of the current use + */ + struct talloc_memlimit *limit; + + /* * "pool" has dual use: * * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" @@ -543,6 +564,7 @@ static inline void *__talloc(const void *context, size_t size) { struct talloc_chunk *tc = NULL; + struct talloc_memlimit *limit = NULL; if (unlikely(context == NULL)) { context = null_context; @@ -553,8 +575,18 @@ } if (context != NULL) { - tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), - TC_HDR_SIZE+size); + struct talloc_chunk *ptc = talloc_chunk_from_ptr(context); + + if (ptc->limit != NULL) { + limit = ptc->limit; + } + + if (!talloc_memlimit_check(limit, (TC_HDR_SIZE+size))) { + errno = ENOMEM; + return NULL; + } + + tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); } if (tc == NULL) { @@ -564,6 +596,15 @@ tc->pool = NULL; } + if (limit != NULL) { + struct talloc_memlimit *l; + + for (l = limit; l != NULL; l = l->upper) { + l->cur_size += TC_HDR_SIZE+size; + } + } + + tc->limit = limit; tc->size = size; tc->destructor = NULL; tc->child = NULL; @@ -852,6 +893,29 @@ tc->flags |= TALLOC_FLAG_FREE; + /* + * If we are part of a memory limited context hierarchy + * we need to subtract the memory used from the counters + */ + if (tc->limit) { + struct talloc_memlimit *l; + + for (l = tc->limit; l != NULL; l = l->upper) { + if (l->cur_size >= tc->size+TC_HDR_SIZE) { + l->cur_size -= tc->size+TC_HDR_SIZE; + } else { + talloc_abort("cur_size memlimit counter not correct!"); + return 0; + } + } + + if (tc->limit->parent == tc) { + free(tc->limit); + } + + tc->limit = NULL; + } + /* we mark the freed memory with where we called the free * from. This means on a double free error we can report where * the first free came from @@ -880,6 +944,10 @@ return 0; } +static size_t _talloc_total_limit_size(const void *ptr, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit); + /* move a lump of memory from one talloc context to another return the ptr on success, or NULL if it could not be transferred. @@ -888,6 +956,7 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) { struct talloc_chunk *tc, *new_tc; + size_t ctx_size = 0; if (unlikely(!ptr)) { return NULL; @@ -899,6 +968,23 @@ tc = talloc_chunk_from_ptr(ptr); + if (tc->limit != NULL) { + + ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); + + if (!talloc_memlimit_update(tc->limit->upper, ctx_size, 0)) { + talloc_abort("cur_size memlimit counter not correct!"); + errno = EINVAL; + return NULL; + } + + if (tc->limit->parent == tc) { + tc->limit->upper = NULL; + } else { + tc->limit = NULL; + } + } + if (unlikely(new_ctx == NULL)) { if (tc->parent) { _TLIST_REMOVE(tc->parent->child, tc); @@ -909,7 +995,7 @@ if (tc->prev) tc->prev->next = tc->next; if (tc->next) tc->next->prev = tc->prev; } - + tc->parent = tc->next = tc->prev = NULL; return discard_const_p(void, ptr); } @@ -935,6 +1021,19 @@ if (new_tc->child) new_tc->child->parent = NULL; _TLIST_ADD(new_tc->child, tc); + if (tc->limit || new_tc->limit) { + ctx_size = _talloc_total_limit_size(ptr, tc->limit, + new_tc->limit); + } + + if (new_tc->limit) { + struct talloc_memlimit *l; + + for (l = new_tc->limit; l != NULL; l = l->upper) { + l->cur_size += ctx_size; + } + } + return discard_const_p(void, ptr); } @@ -1068,7 +1167,7 @@ if (tc_c != talloc_parent_chunk(ptr)) { return -1; } - + tc_p = talloc_chunk_from_ptr(ptr); if (tc_p->refs == NULL) { @@ -1411,6 +1510,13 @@ return NULL; } + if (tc->limit && (size - tc->size > 0)) { + if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { + errno = ENOMEM; + return NULL; + } + } + /* handle realloc inside a talloc_pool */ if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { pool_tc = (union talloc_pool_chunk *)tc->pool; @@ -1418,7 +1524,7 @@ #if (ALWAYS_REALLOC == 0) /* don't shrink if we have less than 1k to gain */ - if (size < tc->size) { + if (size < tc->size && tc->limit == NULL) { if (pool_tc) { void *next_tc = tc_next_chunk(tc); TC_INVALIDATE_SHRINK_CHUNK(tc, size); @@ -1526,6 +1632,14 @@ if (new_chunk_size == old_chunk_size) { TC_UNDEFINE_GROW_CHUNK(tc, size); tc->flags &= ~TALLOC_FLAG_FREE; + if (!talloc_memlimit_update(tc->limit, + tc->size, size)) { + talloc_abort("cur_size memlimit counter not" + " correct!"); + errno = EINVAL; + return NULL; + } + tc->size = size; return ptr; } @@ -1541,6 +1655,13 @@ if (space_left >= space_needed) { TC_UNDEFINE_GROW_CHUNK(tc, size); tc->flags &= ~TALLOC_FLAG_FREE; + if (!talloc_memlimit_update(tc->limit, + tc->size, size)) { + talloc_abort("cur_size memlimit " + "counter not correct!"); + errno = EINVAL; + return NULL; + } tc->size = size; pool_tc->hdr.c.pool = tc_next_chunk(tc); return ptr; @@ -1589,6 +1710,11 @@ tc->next->prev = tc; } + if (!talloc_memlimit_update(tc->limit, tc->size, size)) { + talloc_abort("cur_size memlimit counter not correct!"); + errno = EINVAL; + return NULL; + } tc->size = size; _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); @@ -1607,10 +1733,16 @@ return ret; } -/* - return the total size of a talloc pool (subtree) -*/ -_PUBLIC_ size_t talloc_total_size(const void *ptr) +enum talloc_mem_count_type { + TOTAL_MEM_SIZE, + TOTAL_MEM_BLOCKS, + TOTAL_MEM_LIMIT, +}; + +static size_t _talloc_total_mem_internal(const void *ptr, + enum talloc_mem_count_type type, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit) { size_t total = 0; struct talloc_chunk *c, *tc; @@ -1624,17 +1756,50 @@ tc = talloc_chunk_from_ptr(ptr); + if (old_limit || new_limit) { + if (tc->limit && tc->limit->upper == old_limit) { + tc->limit->upper = new_limit; + } + } + + /* optimize in the memlimits case */ + if (type == TOTAL_MEM_LIMIT && + tc->limit != NULL && + tc->limit != old_limit && + tc->limit->parent == tc) { + return tc->limit->cur_size; + } + if (tc->flags & TALLOC_FLAG_LOOP) { return 0; } tc->flags |= TALLOC_FLAG_LOOP; - if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { - total = tc->size; + if (old_limit || new_limit) { + if (old_limit == tc->limit) { + tc->limit = new_limit; + } } - for (c=tc->child;c;c=c->next) { - total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); + + switch (type) { + case TOTAL_MEM_SIZE: + if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { + total = tc->size; + } + break; + case TOTAL_MEM_BLOCKS: + total++; + break; + case TOTAL_MEM_LIMIT: + if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { + total = tc->size + TC_HDR_SIZE; + } + break; + } + for (c = tc->child; c; c = c->next) { + total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type, + old_limit, new_limit); } tc->flags &= ~TALLOC_FLAG_LOOP; @@ -1643,36 +1808,19 @@ } /* + return the total size of a talloc pool (subtree) +*/ +_PUBLIC_ size_t talloc_total_size(const void *ptr) +{ + return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL); +} + +/* return the total number of blocks in a talloc pool (subtree) */ _PUBLIC_ size_t talloc_total_blocks(const void *ptr) { - size_t total = 0; - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total++; - for (c=tc->child;c;c=c->next) { - total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; + return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL); } /* @@ -1734,6 +1882,7 @@ static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) { const char *name = talloc_get_name(ptr); + struct talloc_chunk *tc; FILE *f = (FILE *)_f; if (is_ref) { @@ -1741,6 +1890,16 @@ return; } + tc = talloc_chunk_from_ptr(ptr); + if (tc->limit && tc->limit->parent == tc) { + fprintf(f, "%*s%-30s is a memlimit context" + " (max_size = %lu bytes, cur_size = %lu bytes)\n", + depth*4, "", + name, + (unsigned long)tc->limit->max_size, + (unsigned long)tc->limit->cur_size); + } + if (depth == 0) { fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", (max_depth < 0 ? "full " :""), name, @@ -2359,3 +2518,80 @@ { return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); } + +/* + return the total size of memory used by this context and all children +*/ +static size_t _talloc_total_limit_size(const void *ptr, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit) +{ + return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT, + old_limit, new_limit); +} + +static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) +{ + struct talloc_memlimit *l; + + for (l = limit; l != NULL; l = l->upper) { + if (l->max_size != 0 && + ((l->max_size <= l->cur_size) || + (l->max_size - l->cur_size < TC_HDR_SIZE+size))) { + return false; + } + } + + return true; +} + +static bool talloc_memlimit_update(struct talloc_memlimit *limit, + size_t old_size, size_t new_size) +{ + struct talloc_memlimit *l; + ssize_t d; + + if (old_size == 0) { + d = new_size + TC_HDR_SIZE; + } else { + d = new_size - old_size; + } + for (l = limit; l != NULL; l = l->upper) { + ssize_t new_cur_size = l->cur_size + d; + if (new_cur_size < 0) { + return false; + } + l->cur_size = new_cur_size; + } + + return true; +} + +_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); + struct talloc_memlimit *orig_limit; + struct talloc_memlimit *limit = NULL; + + if (tc->limit && tc->limit->parent == tc) { + tc->limit->max_size = max_size; + return 0; + } + orig_limit = tc->limit; + + limit = malloc(sizeof(struct talloc_memlimit)); + if (limit == NULL) { + return 1; + } + limit->parent = tc; + limit->max_size = max_size; + limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit); + + if (orig_limit) { + limit->upper = orig_limit; + } else { + limit->upper = NULL; + } + + return 0; +} diff -Nru ldb-1.1.13/lib/talloc/talloc.h ldb-1.1.15/lib/talloc/talloc.h --- ldb-1.1.13/lib/talloc/talloc.h 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/lib/talloc/talloc.h 2013-01-27 11:51:43.000000000 +0000 @@ -1842,6 +1842,25 @@ */ void talloc_set_log_stderr(void); +/** + * @brief Set a max memory limit for the current context hierarchy + * This affects all children of this context and constrain any + * allocation in the hierarchy to never exceed the limit set. + * The limit can be removed by setting 0 (unlimited) as the + * max_size by calling the funciton again on the sam context. + * Memory limits can also be nested, meaning a hild can have + * a stricter memory limit than a parent. + * Memory limits are enforced only at memory allocation time. + * Stealing a context into a 'limited' hierarchy properly + * updates memory usage but does *not* cause failure if the + * move causes the new parent to exceed its limits. However + * any further allocation on that hierarchy will then fail. + * + * @param[in] ctx The talloc context to set the limit on + * @param[in] max_size The (new) max_size + */ +int talloc_set_memlimit(const void *ctx, size_t max_size); + /* @} ******************************************************************/ #if TALLOC_DEPRECATED diff -Nru ldb-1.1.13/lib/talloc/testsuite.c ldb-1.1.15/lib/talloc/testsuite.c --- ldb-1.1.13/lib/talloc/testsuite.c 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/lib/talloc/testsuite.c 2013-01-27 11:51:43.000000000 +0000 @@ -1355,6 +1355,175 @@ return true; } +static bool test_memlimit(void) +{ + void *root; + char *l1, *l2, *l3, *l4, *l5, *t; + + printf("test: memlimit\n# MEMORY LIMITS\n"); + + printf("==== talloc_new(NULL)\n"); + root = talloc_new(NULL); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(root, 2048)\n"); + l1 = talloc_size(root, 2048); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l1)\n"); + talloc_free(l1); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(root, level 1)\n"); + l1 = talloc_strdup(root, "level 1"); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l1, 2048)\n"); + torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(root, 2048)\n"); + l2 = talloc_size(l1, 2048); + torture_assert("memlimit", l2 == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l1, level 2)\n"); + l2 = talloc_strdup(l1, "level 2"); + torture_assert("memlimit", l2 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l2)\n"); + talloc_free(l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(NULL, 2048)\n"); + l2 = talloc_size(NULL, 2048); + + talloc_report_full(root, stdout); + + printf("==== talloc_steal(l1, l2)\n"); + talloc_steal(l1, l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l2, level 3)\n"); + l3 = talloc_strdup(l2, "level 3"); + torture_assert("memlimit", l3 == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l2)\n"); + talloc_free(l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(NULL, level 2)\n"); + l2 = talloc_strdup(NULL, "level 2"); + talloc_steal(l1, l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l2, level 3)\n"); + l3 = talloc_strdup(l2, "level 3"); + torture_assert("memlimit", l3 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l3, 1024)\n"); + torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l3, level 4)\n"); + l4 = talloc_strdup(l3, "level 4"); + torture_assert("memlimit", l4 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l4, 512)\n"); + torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l4, level 5)\n"); + l5 = talloc_strdup(l4, "level 5"); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_realloc(NULL, l5, char, 600)\n"); + t = talloc_realloc(NULL, l5, char, 600); + torture_assert("memlimit", t == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_realloc(NULL, l5, char, 5)\n"); + l5 = talloc_realloc(NULL, l5, char, 5); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l3, level 4)\n"); + l4 = talloc_strdup(l3, "level 4"); + torture_assert("memlimit", l4 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l4, 512)\n"); + torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l4, level 5)\n"); + l5 = talloc_strdup(l4, "level 5"); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== Make new temp context and steal l5\n"); + t = talloc_new(root); + talloc_steal(t, l5); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(t, 2048)\n"); + l1 = talloc_size(t, 2048); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + talloc_free(root); + + printf("success: memlimit\n"); + + return true; +} static void test_reset(void) { @@ -1416,6 +1585,9 @@ ret &= test_rusty(); test_reset(); ret &= test_free_children(); + test_reset(); + ret &= test_memlimit(); + if (ret) { test_reset(); diff -Nru ldb-1.1.13/lib/talloc/wscript ldb-1.1.15/lib/talloc/wscript --- ldb-1.1.13/lib/talloc/wscript 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/talloc/wscript 2013-01-27 11:51:43.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'talloc' -VERSION = '2.0.7' +VERSION = '2.0.8' blddir = 'bin' @@ -108,7 +108,7 @@ pc_files='talloc.pc', public_headers_install=not private_library, private_library=private_library, - manpages='talloc.3') + manpages='man/talloc.3') if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL') and not bld.env.disable_python: bld.SAMBA_LIBRARY('pytalloc-util', diff -Nru ldb-1.1.13/lib/tdb/ABI/tdb-1.2.11.sigs ldb-1.1.15/lib/tdb/ABI/tdb-1.2.11.sigs --- ldb-1.1.13/lib/tdb/ABI/tdb-1.2.11.sigs 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/ABI/tdb-1.2.11.sigs 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,67 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff -Nru ldb-1.1.13/lib/tdb/common/dump.c ldb-1.1.15/lib/tdb/common/dump.c --- ldb-1.1.13/lib/tdb/common/dump.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/dump.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -33,7 +33,7 @@ struct tdb_record rec; tdb_off_t tailer_ofs, tailer; - if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, + if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { printf("ERROR: failed to read record at %u\n", offset); return 0; @@ -110,7 +110,7 @@ printf("freelist top=[0x%08x]\n", rec_ptr ); while (rec_ptr) { - if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, + if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return -1; @@ -122,14 +122,14 @@ return -1; } - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", + printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); total_free += rec.rec_len; /* move to the next record */ rec_ptr = rec.next; } - printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, + printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, (int)total_free); return tdb_unlock(tdb, -1, F_WRLCK); diff -Nru ldb-1.1.13/lib/tdb/common/error.c ldb-1.1.15/lib/tdb/common/error.c --- ldb-1.1.13/lib/tdb/common/error.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/error.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library diff -Nru ldb-1.1.13/lib/tdb/common/freelist.c ldb-1.1.15/lib/tdb/common/freelist.c --- ldb-1.1.13/lib/tdb/common/freelist.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/freelist.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -28,7 +28,7 @@ #include "tdb_private.h" /* 'right' merges can involve O(n^2) cost when combined with a - traverse, so they are disabled until we find a way to do them in + traverse, so they are disabled until we find a way to do them in O(1) time */ #define USE_RIGHT_MERGES 0 @@ -42,17 +42,17 @@ if (rec->magic == TDB_MAGIC) { /* this happens when a app is showdown while deleting a record - we should not completely fail when this happens */ - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; - if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1) + if (tdb_rec_write(tdb, off, rec) == -1) return -1; } if (rec->magic != TDB_FREE_MAGIC) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", rec->magic, off)); return -1; } @@ -170,7 +170,7 @@ /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { - /* we now merge the new record into the left record, rather than the other + /* we now merge the new record into the left record, rather than the other way around. This makes the operation O(1) instead of O(n). This change prevents traverse from being O(n^2) after a lot of deletes */ l.rec_len += sizeof(*rec) + rec->rec_len; @@ -210,7 +210,7 @@ -/* +/* the core of tdb_allocate - called when we have decided which free list entry to use @@ -218,7 +218,7 @@ not the beginning. This is so the left merge in a free is more likely to be able to free up the record without fragmentation */ -static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, +static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr, struct tdb_record *rec, tdb_off_t last_ptr) { @@ -250,7 +250,7 @@ } /* and setup the new record */ - rec_ptr += sizeof(*rec) + rec->rec_len; + rec_ptr += sizeof(*rec) + rec->rec_len; memset(rec, '\0', sizeof(*rec)); rec->rec_len = length; @@ -303,7 +303,7 @@ bestfit.last_ptr = 0; bestfit.rec_len = 0; - /* + /* this is a best fit allocation strategy. Originally we used a first fit strategy, but it suffered from massive fragmentation issues when faced with a slowly increasing record size. @@ -347,7 +347,7 @@ goto fail; } - newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, + newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr); tdb_unlock(tdb, -1, F_WRLCK); return newrec_ptr; @@ -364,8 +364,8 @@ -/* - return the size of the freelist - used to decide if we should repack +/* + return the size of the freelist - used to decide if we should repack */ _PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) { diff -Nru ldb-1.1.13/lib/tdb/common/io.c ldb-1.1.15/lib/tdb/common/io.c --- ldb-1.1.13/lib/tdb/common/io.c 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/io.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -30,7 +30,7 @@ /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand - if necessary + if necessary */ static int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) @@ -63,16 +63,6 @@ return -1; } - if (st.st_size < (size_t)off + len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", - (int)(off + len), (int)st.st_size)); - } - return -1; - } - /* Beware >4G files! */ if ((tdb_off_t)st.st_size != st.st_size) { /* Ensure ecode is set for log fn. */ @@ -82,17 +72,35 @@ return -1; } - /* Unmap, update size, remap */ + /* Unmap, update size, remap. We do this unconditionally, to handle + * the unusual case where the db is truncated. + * + * This can happen to a child using tdb_reopen_all(true) on a + * TDB_CLEAR_IF_FIRST tdb whose parent crashes: the next + * opener will truncate the database. */ if (tdb_munmap(tdb) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } tdb->map_size = st.st_size; - return tdb_mmap(tdb); + if (tdb_mmap(tdb) != 0) { + return - 1; + } + + if (st.st_size < (size_t)off + len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", + (int)(off + len), (int)st.st_size)); + } + return -1; + } + return 0; } /* write a lump of data at a specified offset */ -static int tdb_write(struct tdb_context *tdb, tdb_off_t off, +static int tdb_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { if (len == 0) { @@ -154,7 +162,7 @@ /* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, +static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { if (tdb->methods->tdb_oob(tdb, off, len, 0) != 0) { @@ -191,7 +199,7 @@ /* do an unlocked scan of the hash table heads to find the next non-zero head. The value will then be confirmed with the lock held -*/ +*/ static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) { uint32_t h = *chain; @@ -248,8 +256,8 @@ #ifdef HAVE_MMAP if (should_mmap(tdb)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, 0); /* @@ -258,7 +266,7 @@ if (tdb->map_ptr == MAP_FAILED) { tdb->map_ptr = NULL; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", tdb->map_size, strerror(errno))); #ifdef HAVE_INCOHERENT_MMAP tdb->ecode = TDB_ERR_IO; @@ -297,7 +305,7 @@ errno = ENOSPC; } if (written != 1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", size+addition, strerror(errno))); return -1; } diff -Nru ldb-1.1.13/lib/tdb/common/lock.c ldb-1.1.15/lib/tdb/common/lock.c --- ldb-1.1.13/lib/tdb/common/lock.c 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/lock.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -126,10 +126,10 @@ } /* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. + this functions locks/unlocks "len" byte at the specified offset. On error, errno is also set so that errors are passed back properly - through tdb_open(). + through tdb_open(). note that a len of zero means lock to end of file */ @@ -201,7 +201,7 @@ upgrade a read lock to a write lock. This needs to be handled in a special way as some OSes (such as solaris) have too conservative deadlock detection and claim a deadlock when progress can be - made. For those OSes we may loop for a while. + made. For those OSes we may loop for a while. */ int tdb_allrecord_upgrade(struct tdb_context *tdb) { @@ -334,34 +334,60 @@ return false; } +/* + * A allrecord lock allows us to avoid per chain locks. Check if the allrecord + * lock is strong enough. + */ +static int tdb_lock_covered_by_allrecord_lock(struct tdb_context *tdb, + int ltype) +{ + if (ltype == F_RDLCK) { + /* + * The allrecord_lock is equal (F_RDLCK) or stronger + * (F_WRLCK). Pass. + */ + return 0; + } + + if (tdb->allrecord_lock.ltype == F_RDLCK) { + /* + * We ask for ltype==F_WRLCK, but the allrecord_lock + * is too weak. We can't upgrade here, so fail. + */ + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + /* + * Asking for F_WRLCK, allrecord is F_WRLCK as well. Pass. + */ + return 0; +} + static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype, enum tdb_lock_flags waitflag) { int ret; bool check = false; - /* a allrecord lock allows us to avoid per chain locks */ - if (tdb->allrecord_lock.count && - (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) { - return 0; + if (tdb->allrecord_lock.count) { + return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } - if (tdb->allrecord_lock.count) { - tdb->ecode = TDB_ERR_LOCK; - ret = -1; - } else { - /* Only check when we grab first data lock. */ - check = !have_data_locks(tdb); - ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); + /* + * Check for recoveries: Someone might have kill -9'ed a process + * during a commit. + */ + check = !have_data_locks(tdb); + ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); - if (ret == 0 && check && tdb_needs_recovery(tdb)) { - tdb_nest_unlock(tdb, lock_offset(list), ltype, false); + if (ret == 0 && check && tdb_needs_recovery(tdb)) { + tdb_nest_unlock(tdb, lock_offset(list), ltype, false); - if (tdb_lock_and_recover(tdb) == -1) { - return -1; - } - return tdb_lock_list(tdb, list, ltype, waitflag); + if (tdb_lock_and_recover(tdb) == -1) { + return -1; } + return tdb_lock_list(tdb, list, ltype, waitflag); } return ret; } @@ -441,21 +467,15 @@ } if (ret) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); return ret; } _PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) { /* a global lock allows us to avoid per chain locks */ - if (tdb->allrecord_lock.count && - (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) { - return 0; - } - if (tdb->allrecord_lock.count) { - tdb->ecode = TDB_ERR_LOCK; - return -1; + return tdb_lock_covered_by_allrecord_lock(tdb, ltype); } return tdb_nest_unlock(tdb, lock_offset(list), ltype, false); @@ -562,7 +582,7 @@ /* We cover two kinds of locks: * 1) Normal chain locks. Taken for almost all operations. - * 3) Individual records locks. Taken after normal or free + * 2) Individual records locks. Taken after normal or free * chain locks. * * It is (1) which cause the starvation problem, so we're only @@ -863,12 +883,14 @@ /* Following functions are added specifically to support CTDB. */ /* Don't do actual fcntl locking, just mark tdb locked */ +int tdb_transaction_write_lock_mark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) { return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); } /* Don't do actual fcntl unlocking, just mark tdb unlocked */ +int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); _PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); diff -Nru ldb-1.1.13/lib/tdb/common/open.c ldb-1.1.15/lib/tdb/common/open.c --- ldb-1.1.13/lib/tdb/common/open.c 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/open.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -94,10 +94,11 @@ memcpy(&tdb->header, newdb, sizeof(tdb->header)); /* Don't endian-convert the magic food! */ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - /* we still have "ret == -1" here */ - if (tdb_write_all(tdb->fd, newdb, size)) - ret = 0; + if (!tdb_write_all(tdb->fd, newdb, size)) + goto fail; + + ret = 0; fail: SAFE_FREE(newdb); return ret; @@ -119,13 +120,13 @@ return 0; } -/* open the database, creating it if necessary +/* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid. The hash size is advisory, use zero for a default value. - Return is NULL on error, in which case errno is also set. Don't + Return is NULL on error, in which case errno is also set. Don't try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ @@ -313,12 +314,36 @@ if ((tdb_flags & TDB_CLEAR_IF_FIRST) && (!tdb->read_only) && (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) { - open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { + int ret; + ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, + TDB_LOCK_WAIT); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "tdb_brlock failed for %s: %s\n", + name, strerror(errno))); + goto fail; + } + ret = tdb_new_database(tdb, hash_size); + if (ret == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "failed to truncate %s: %s\n", + "tdb_new_database failed for %s: %s\n", name, strerror(errno))); - goto fail; /* errno set by ftruncate */ + tdb_unlockall(tdb); + goto fail; + } + ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "tdb_unlockall failed for %s: %s\n", + name, strerror(errno))); + goto fail; + } + ret = lseek(tdb->fd, 0, SEEK_SET); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "lseek failed for %s: %s\n", + name, strerror(errno))); + goto fail; } } diff -Nru ldb-1.1.13/lib/tdb/common/rescue.c ldb-1.1.15/lib/tdb/common/rescue.c --- ldb-1.1.13/lib/tdb/common/rescue.c 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/rescue.c 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,349 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library, rescue attempt code. + + Copyright (C) Rusty Russell 2012 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + 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 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + 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, see . +*/ +#include "tdb_private.h" +#include + + +struct found { + tdb_off_t head; /* 0 -> invalid. */ + struct tdb_record rec; + TDB_DATA key; + bool in_hash; + bool in_free; +}; + +struct found_table { + /* As an ordered array (by head offset). */ + struct found *arr; + unsigned int num, max; +}; + +static bool looks_like_valid_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec, + TDB_DATA *key) +{ + unsigned int hval; + + if (rec->magic != TDB_MAGIC) + return false; + + if (rec->key_len + rec->data_len > rec->rec_len) + return false; + + if (rec->rec_len % TDB_ALIGNMENT) + return false; + + /* Next pointer must make some sense. */ + if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->header.hash_size)) + return false; + + if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 1)) + return false; + + key->dsize = rec->key_len; + key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); + if (!key->dptr) + return false; + + hval = tdb->hash_fn(key); + if (hval != rec->full_hash) { + free(key->dptr); + return false; + } + + /* Caller frees up key->dptr */ + return true; +} + +static bool add_to_table(struct found_table *found, + tdb_off_t off, + struct tdb_record *rec, + TDB_DATA key) +{ + if (found->num + 1 > found->max) { + struct found *new; + found->max = (found->max ? found->max * 2 : 128); + new = realloc(found->arr, found->max * sizeof(found->arr[0])); + if (!new) + return false; + found->arr = new; + } + + found->arr[found->num].head = off; + found->arr[found->num].rec = *rec; + found->arr[found->num].key = key; + found->arr[found->num].in_hash = false; + found->arr[found->num].in_free = false; + + found->num++; + return true; +} + +static bool walk_record(struct tdb_context *tdb, + const struct found *f, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + TDB_DATA data; + + data.dsize = f->rec.data_len; + data.dptr = tdb_alloc_read(tdb, + f->head + sizeof(f->rec) + f->rec.key_len, + data.dsize); + if (!data.dptr) { + if (tdb->ecode == TDB_ERR_OOM) + return false; + /* I/O errors are expected. */ + return true; + } + + walk(f->key, data, private_data); + free(data.dptr); + return true; +} + +/* First entry which has offset >= this one. */ +static unsigned int find_entry(struct found_table *found, tdb_off_t off) +{ + unsigned int start = 0, end = found->num; + + while (start < end) { + /* We can't overflow here. */ + unsigned int mid = (start + end) / 2; + + if (off < found->arr[mid].head) { + end = mid; + } else if (off > found->arr[mid].head) { + start = mid + 1; + } else { + return mid; + } + } + + assert(start == end); + return end; +} + +static void found_in_hashchain(struct found_table *found, tdb_off_t head) +{ + unsigned int match; + + match = find_entry(found, head); + if (match < found->num && found->arr[match].head == head) { + found->arr[match].in_hash = true; + } +} + +static void mark_free_area(struct found_table *found, tdb_off_t head, + tdb_len_t len) +{ + unsigned int match; + + match = find_entry(found, head); + /* Mark everything within this free entry. */ + while (match < found->num) { + if (found->arr[match].head >= head + len) { + break; + } + found->arr[match].in_free = true; + match++; + } +} + +static int cmp_key(const void *a, const void *b) +{ + const struct found *fa = a, *fb = b; + + if (fa->key.dsize < fb->key.dsize) { + return -1; + } else if (fa->key.dsize > fb->key.dsize) { + return 1; + } + return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); +} + +static bool key_eq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize + && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static void free_table(struct found_table *found) +{ + unsigned int i; + + for (i = 0; i < found->num; i++) { + free(found->arr[i].key.dptr); + } + free(found->arr); +} + +static void logging_suppressed(struct tdb_context *tdb, + enum tdb_debug_level level, const char *fmt, ...) +{ +} + +_PUBLIC_ int tdb_rescue(struct tdb_context *tdb, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + struct found_table found = { NULL, 0, 0 }; + tdb_off_t h, off, i; + tdb_log_func oldlog = tdb->log.log_fn; + struct tdb_record rec; + TDB_DATA key; + bool locked; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return -1; + locked = true; + } + + /* Make sure we know true size of the underlying file. */ + tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); + + /* Suppress logging, since we anticipate errors. */ + tdb->log.log_fn = logging_suppressed; + + /* Now walk entire db looking for records. */ + for (off = TDB_DATA_START(tdb->header.hash_size); + off < tdb->map_size; + off += TDB_ALIGNMENT) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + continue; + + if (looks_like_valid_record(tdb, off, &rec, &key)) { + if (!add_to_table(&found, off, &rec, key)) { + goto oom; + } + } + } + + /* Walk hash chains to positive vet. */ + for (h = 0; h < 1+tdb->header.hash_size; h++) { + bool slow_chase = false; + tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); + + if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), + &off) == -1) + continue; + + while (off && off != slow_off) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) != 0) { + break; + } + + /* 0 is the free list, rest are hash chains. */ + if (h == 0) { + /* Don't mark garbage as free. */ + if (rec.magic != TDB_FREE_MAGIC) { + break; + } + mark_free_area(&found, off, + sizeof(rec) + rec.rec_len); + } else { + found_in_hashchain(&found, off); + } + + off = rec.next; + + /* Loop detection using second pointer at half-speed */ + if (slow_chase) { + /* First entry happens to be next ptr */ + tdb_ofs_read(tdb, slow_off, &slow_off); + } + slow_chase = !slow_chase; + } + } + + /* Recovery area: must be marked as free, since it often has old + * records in there! */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == 0) { + mark_free_area(&found, off, sizeof(rec) + rec.rec_len); + } + } + + /* Now sort by key! */ + qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); + + for (i = 0; i < found.num; ) { + unsigned int num, num_in_hash = 0; + + /* How many are identical? */ + for (num = 0; num < found.num - i; num++) { + if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { + break; + } + if (found.arr[i+num].in_hash) { + if (!walk_record(tdb, &found.arr[i+num], + walk, private_data)) + goto oom; + num_in_hash++; + } + } + assert(num); + + /* If none were in the hash, we print any not in free list. */ + if (num_in_hash == 0) { + unsigned int j; + + for (j = i; j < i + num; j++) { + if (!found.arr[j].in_free) { + if (!walk_record(tdb, &found.arr[j], + walk, private_data)) + goto oom; + } + } + } + + i += num; + } + + tdb->log.log_fn = oldlog; + if (locked) { + tdb_unlockall_read(tdb); + } + return 0; + +oom: + tdb->log.log_fn = oldlog; + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); + free_table(&found); + if (locked) { + tdb_unlockall_read(tdb); + } + return -1; +} diff -Nru ldb-1.1.13/lib/tdb/common/summary.c ldb-1.1.15/lib/tdb/common/summary.c --- ldb-1.1.13/lib/tdb/common/summary.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/summary.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,7 +1,7 @@ - /* + /* Trivial Database: human-readable summary code Copyright (C) Rusty Russell 2010 - + 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 diff -Nru ldb-1.1.13/lib/tdb/common/tdb.c ldb-1.1.15/lib/tdb/common/tdb.c --- ldb-1.1.13/lib/tdb/common/tdb.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/tdb.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -152,7 +152,7 @@ /* it could be an exact duplicate of what is there - this is * surprisingly common (eg. with a ldb re-index). */ - if (rec.key_len == key.dsize && + if (rec.key_len == key.dsize && rec.data_len == dbuf.dsize && rec.full_hash == hash && tdb_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == 0) { @@ -258,7 +258,7 @@ return ret; } -/* check if an entry in the database exists +/* check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is @@ -777,7 +777,7 @@ /* - add a region of the file to the freelist. Length is the size of the region in bytes, + add a region of the file to the freelist. Length is the size of the region in bytes, which includes the free list header that needs to be added */ static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) @@ -789,7 +789,7 @@ } if (length + offset > tdb->map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); - return -1; + return -1; } memset(&rec,'\0',sizeof(rec)); rec.rec_len = length - sizeof(rec); @@ -835,7 +835,7 @@ if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); return -1; - } + } recovery_size = rec.rec_len + sizeof(rec); } @@ -853,7 +853,7 @@ goto failed; } - /* add all the rest of the file to the freelist, possibly leaving a gap + /* add all the rest of the file to the freelist, possibly leaving a gap for the recovery area */ if (recovery_size == 0) { /* the simple case - the whole file can be used as a freelist */ @@ -863,7 +863,7 @@ } } else { /* we need to add two freelist entries - one on either - side of the recovery area + side of the recovery area Note that we cannot shift the recovery area during this operation. Only the transaction.c code may @@ -942,7 +942,7 @@ TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); - return -1; + return -1; } if (state.error) { @@ -966,7 +966,7 @@ TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n")); tdb_transaction_cancel(tdb); tdb_close(tmp_db); - return -1; + return -1; } if (state.error) { diff -Nru ldb-1.1.13/lib/tdb/common/tdb_private.h ldb-1.1.15/lib/tdb/common/tdb_private.h --- ldb-1.1.13/lib/tdb/common/tdb_private.h 2012-04-11 13:14:43.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/tdb_private.h 2013-01-27 11:51:43.000000000 +0000 @@ -1,6 +1,6 @@ #ifndef TDB_PRIVATE_H #define TDB_PRIVATE_H - /* + /* Unix SMB/CIFS implementation. trivial database library - private includes diff -Nru ldb-1.1.13/lib/tdb/common/transaction.c ldb-1.1.15/lib/tdb/common/transaction.c --- ldb-1.1.13/lib/tdb/common/transaction.c 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/transaction.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -148,7 +148,7 @@ read while in a transaction. We need to check first if the data is in our list of transaction elements, then if not do a real read */ -static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, +static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { uint32_t blk; @@ -205,7 +205,7 @@ /* write while in a transaction */ -static int transaction_write(struct tdb_context *tdb, tdb_off_t off, +static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; @@ -261,7 +261,7 @@ tdb->ecode = TDB_ERR_OOM; goto fail; } - memset(&new_blocks[tdb->transaction->num_blocks], 0, + memset(&new_blocks[tdb->transaction->num_blocks], 0, (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); tdb->transaction->blocks = new_blocks; tdb->transaction->num_blocks = blk+1; @@ -274,23 +274,23 @@ if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; - return -1; + return -1; } if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size; if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); } - if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, - tdb->transaction->blocks[blk], + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], len2, 0) != 0) { - SAFE_FREE(tdb->transaction->blocks[blk]); + SAFE_FREE(tdb->transaction->blocks[blk]); tdb->ecode = TDB_ERR_IO; goto fail; } if (blk == tdb->transaction->num_blocks-1) { tdb->transaction->last_block_size = len2; - } + } } } @@ -309,7 +309,7 @@ return 0; fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; @@ -317,10 +317,10 @@ /* - write while in a transaction - this varient never expands the transaction blocks, it only + write while in a transaction - this variant never expands the transaction blocks, it only updates existing blocks. This means it cannot change the recovery size */ -static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { uint32_t blk; @@ -396,7 +396,7 @@ /* transaction version of tdb_expand(). */ -static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, +static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { /* add a write to the transaction elements, so subsequent @@ -440,7 +440,7 @@ return -1; } tdb->transaction->nesting++; - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", tdb->transaction->nesting)); return 0; } @@ -545,7 +545,7 @@ sync to disk */ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) -{ +{ if (tdb->flags & TDB_NOSYNC) { return 0; } @@ -562,7 +562,7 @@ #ifdef HAVE_MMAP if (tdb->map_ptr) { tdb_off_t moffset = offset & ~(tdb->page_size-1); - if (msync(moffset + (char *)tdb->map_ptr, + if (msync(moffset + (char *)tdb->map_ptr, length + (offset - moffset), MS_SYNC) != 0) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", @@ -576,7 +576,7 @@ static int _tdb_transaction_cancel(struct tdb_context *tdb) -{ +{ int i, ret = 0; if (tdb->transaction == NULL) { @@ -588,7 +588,7 @@ tdb->transaction->transaction_error = 1; tdb->transaction->nesting--; return 0; - } + } tdb->map_size = tdb->transaction->old_map_size; @@ -655,7 +655,7 @@ } else { recovery_size += tdb->transaction->block_size; } - } + } return recovery_size; } @@ -692,7 +692,7 @@ allocate the recovery area, or use an existing recovery area if it is large enough */ -static int tdb_recovery_allocate(struct tdb_context *tdb, +static int tdb_recovery_allocate(struct tdb_context *tdb, tdb_len_t *recovery_size, tdb_off_t *recovery_offset, tdb_len_t *recovery_max_size) @@ -752,7 +752,7 @@ new_end = recovery_head + sizeof(rec) + *recovery_max_size; - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, new_end - tdb->transaction->old_map_size) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); @@ -769,7 +769,7 @@ /* write the recovery header offset and sync - we can sync without a race here as the magic ptr in the recovery record has not been set */ CONVERT(recovery_head); - if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, + if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; @@ -786,7 +786,7 @@ /* setup the recovery data that will be used on a crash during commit */ -static int transaction_setup_recovery(struct tdb_context *tdb, +static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { tdb_len_t recovery_size; @@ -801,7 +801,7 @@ /* check that the recovery area has enough space */ - if (tdb_recovery_allocate(tdb, &recovery_size, + if (tdb_recovery_allocate(tdb, &recovery_size, &recovery_offset, &recovery_max_size) == -1) { return -1; } @@ -919,7 +919,7 @@ } static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) -{ +{ const struct tdb_methods *methods; if (tdb->transaction == NULL) { @@ -944,7 +944,7 @@ if (tdb->transaction->nesting != 0) { return 0; - } + } /* check for a null transaction */ if (tdb->transaction->blocks == NULL) { @@ -988,8 +988,8 @@ /* expand the file to the new size if needed */ if (tdb->map_size != tdb->transaction->old_map_size) { - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - tdb->map_size - + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + tdb->map_size - tdb->transaction->old_map_size) == -1) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); @@ -1101,7 +1101,7 @@ possibly expanded the file, so we need to run the crash recovery code */ tdb->methods = methods; - tdb_transaction_recover(tdb); + tdb_transaction_recover(tdb); _tdb_transaction_cancel(tdb); @@ -1109,7 +1109,7 @@ return -1; } SAFE_FREE(tdb->transaction->blocks[i]); - } + } /* Do this before we drop lock or blocks. */ if (tdb->transaction->expanded) { @@ -1176,9 +1176,9 @@ } /* read the recovery record */ - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); tdb->ecode = TDB_ERR_IO; return -1; } @@ -1198,7 +1198,7 @@ data = (unsigned char *)malloc(rec.data_len); if (data == NULL) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); tdb->ecode = TDB_ERR_OOM; return -1; } @@ -1206,7 +1206,7 @@ /* read the full recovery data */ if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, rec.data_len, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); tdb->ecode = TDB_ERR_IO; return -1; } @@ -1243,7 +1243,7 @@ if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); tdb->ecode = TDB_ERR_IO; - return -1; + return -1; } } @@ -1252,7 +1252,7 @@ &zero) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); tdb->ecode = TDB_ERR_IO; - return -1; + return -1; } if (transaction_sync(tdb, 0, recovery_eof) == -1) { @@ -1261,7 +1261,7 @@ return -1; } - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", recovery_eof)); /* all done */ diff -Nru ldb-1.1.13/lib/tdb/common/traverse.c ldb-1.1.15/lib/tdb/common/traverse.c --- ldb-1.1.13/lib/tdb/common/traverse.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/common/traverse.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,4 +1,4 @@ - /* + /* Unix SMB/CIFS implementation. trivial database library @@ -117,7 +117,7 @@ /* Try to clean dead ones from old traverses */ current = tlock->off; tlock->off = rec->next; - if (!(tdb->read_only || tdb->traverse_read) && + if (!(tdb->read_only || tdb->traverse_read) && tdb_do_delete(tdb, current, rec) != 0) goto fail; } @@ -140,7 +140,7 @@ if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop */ -static int tdb_traverse_internal(struct tdb_context *tdb, +static int tdb_traverse_internal(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data, struct tdb_traverse_lock *tl) { @@ -149,7 +149,7 @@ int ret = 0, count = 0; tdb_off_t off; - /* This was in the initializaton, above, but the IRIX compiler + /* This was in the initialization, above, but the IRIX compiler * did not like it. crh */ tl->next = tdb->travlocks.next; @@ -165,7 +165,7 @@ } count++; /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), + key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), rec.key_len + rec.data_len); if (!key.dptr) { ret = -1; @@ -210,9 +210,9 @@ /* - a write style traverse - temporarily marks the db read only + a read style traverse - temporarily marks the db read only */ -_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, +_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; @@ -241,7 +241,7 @@ WARNING: The data buffer given to the callback fn does NOT meet the alignment restrictions malloc gives you. */ -_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, +_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; diff -Nru ldb-1.1.13/lib/tdb/include/tdb.h ldb-1.1.15/lib/tdb/include/tdb.h --- ldb-1.1.13/lib/tdb/include/tdb.h 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/include/tdb.h 2013-01-27 11:51:43.000000000 +0000 @@ -212,9 +212,12 @@ * This can be used after a fork to ensure that we have an independent seek * pointer from our parent and to re-establish locks. * - * @param[in] tdb The database to reopen. + * @param[in] tdb The database to reopen. It will be free'd on error! * * @return 0 on success, -1 on error. + * + * @note Don't call tdb_error() after this function cause the tdb context will + * be freed on error. */ int tdb_reopen(struct tdb_context *tdb); @@ -361,9 +364,12 @@ /** * @brief Close a database. * - * @param[in] tdb The database to close. + * @param[in] tdb The database to close. The context will be free'd. * * @return 0 for success, -1 on error. + * + * @note Don't call tdb_error() after this function cause the tdb context will + * be freed on error. */ int tdb_close(struct tdb_context *tdb); @@ -814,6 +820,28 @@ int (*check) (TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); +/** + * @brief Dump all possible records in a corrupt database. + * + * This is the only way to get data out of a database where tdb_check() fails. + * It will call walk() with anything which looks like a database record; this + * may well include invalid, incomplete or duplicate records. + * + * @param[in] tdb The database to check. + * + * @param[in] walk The walk function to use. + * + * @param[in] private_data the private data to pass to the walk function. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_rescue(struct tdb_context *tdb, + void (*walk) (TDB_DATA key, TDB_DATA data, void *private_data), + void *private_data); + /* @} ******************************************************************/ /* Low level locking functions: use with care */ diff -Nru ldb-1.1.13/lib/tdb/libtdb.m4 ldb-1.1.15/lib/tdb/libtdb.m4 --- ldb-1.1.13/lib/tdb/libtdb.m4 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/libtdb.m4 2013-01-27 11:51:43.000000000 +0000 @@ -13,7 +13,7 @@ AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) fi TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" -TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o common/check.o common/hash.o common/summary.o" +TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o common/check.o common/hash.o common/summary.o common/rescue.o" AC_SUBST(TDB_OBJ) AC_SUBST(LIBREPLACEOBJ) diff -Nru ldb-1.1.13/lib/tdb/man/tdbbackup.8.xml ldb-1.1.15/lib/tdb/man/tdbbackup.8.xml --- ldb-1.1.13/lib/tdb/man/tdbbackup.8.xml 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/man/tdbbackup.8.xml 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,136 @@ + + + + + + tdbbackup + 8 + Samba + System Administration tools + 3.6 + + + + + tdbbackup + tool for backing up and for validating the integrity of samba .tdb files + + + + + tdbbackup + -s suffix + -v + -h + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbbackup is a tool that may be used to backup samba .tdb + files. This tool may also be used to verify the integrity of the .tdb files prior + to samba startup or during normal operation. If it finds file damage and it finds + a prior backup the backup file will be restored. + + + + + + OPTIONS + + + + + -h + + Get help information. + + + + + -s suffix + + The -s option allows the adminisistrator to specify a file + backup extension. This way it is possible to keep a history of tdb backup + files by using a new suffix for each backup. + + + + + -v + + The -v will check the database for damages (currupt data) + which if detected causes the backup to be restored. + + + + + + + + + COMMANDS + + GENERAL INFORMATION + + + The tdbbackup utility can safely be run at any time. It was designed so + that it can be used at any time to validate the integrity of tdb files, even during Samba + operation. Typical usage for the command will be: + + + tdbbackup [-s suffix] *.tdb + + + Before restarting samba the following command may be run to validate .tdb files: + + + tdbbackup -v [-s suffix] *.tdb + + + Samba .tdb files are stored in various locations, be sure to run backup all + .tdb file on the system. Important files includes: + + + + + secrets.tdb - usual location is in the /usr/local/samba/private + directory, or on some systems in /etc/samba. + + + + passdb.tdb - usual location is in the /usr/local/samba/private + directory, or on some systems in /etc/samba. + + + + *.tdb located in the /usr/local/samba/var directory or on some + systems in the /var/cache or /var/lib/samba directories. + + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + + The tdbbackup man page was written by John H Terpstra. + + + diff -Nru ldb-1.1.13/lib/tdb/man/tdbdump.8.xml ldb-1.1.15/lib/tdb/man/tdbdump.8.xml --- ldb-1.1.13/lib/tdb/man/tdbdump.8.xml 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/man/tdbdump.8.xml 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,92 @@ + + + + + + tdbdump + 8 + Samba + System Administration tools + 3.6 + + + + + tdbdump + tool for printing the contents of a TDB file + + + + + tdbdump + -k keyname + -e + -h + filename + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbdump is a very simple utility that 'dumps' the + contents of a TDB (Trivial DataBase) file to standard output in a + human-readable format. + + + This tool can be used when debugging problems with TDB files. It is + intended for those who are somewhat familiar with Samba internals. + + + + + OPTIONS + + + + + -h + + Get help information. + + + + + -k keyname + + The -k option restricts dumping to a single key, if found. + + + + + -e + + The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. + + + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + + The tdbdump man page was written by Jelmer Vernooij. + + + diff -Nru ldb-1.1.13/lib/tdb/man/tdbrestore.8.xml ldb-1.1.15/lib/tdb/man/tdbrestore.8.xml --- ldb-1.1.13/lib/tdb/man/tdbrestore.8.xml 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/man/tdbrestore.8.xml 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,66 @@ + + + + + + tdbrestore + 8 + Samba + System Administration tools + 3.6 + + + + + tdbrestore + tool for creating a TDB file out of a tdbdump output + + + + + tdbrestore + tdbfilename + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbrestore is a very simple utility that 'restores' the + contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump + command. + + + This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename + parameter. + + This tool can be used for unpacking the content of tdb as backup mean. + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + This tool was initially written by Volker Lendecke based on an + idea by Simon McVittie. + + + The tdbrestore man page was written by Matthieu Patou. + + + diff -Nru ldb-1.1.13/lib/tdb/man/tdbtool.8.xml ldb-1.1.15/lib/tdb/man/tdbtool.8.xml --- ldb-1.1.13/lib/tdb/man/tdbtool.8.xml 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/man/tdbtool.8.xml 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,235 @@ + + + + + + tdbtool + 8 + Samba + System Administration tools + 4.0 + + + + + tdbtool + manipulate the contents TDB files + + + + + + tdbtool + + + + tdbtool + + TDBFILE + + + COMMANDS + + + + + + + DESCRIPTION + + This tool is part of the + samba + 1 suite. + + tdbtool a tool for displaying and + altering the contents of Samba TDB (Trivial DataBase) files. Each + of the commands listed below can be entered interactively or + provided on the command line. + + + + + + COMMANDS + + + + + + TDBFILE + Create a new database named + TDBFILE. + + + + + + TDBFILE + Open an existing database named + TDBFILE. + + + + + + Erase the current database. + + + + + + Dump the current database as strings. + + + + + + Dump the current database as connection records. + + + + + + Dump the current database keys as strings. + + + + + + Dump the current database keys as hex values. + + + + + + Print summary information about the + current database. + + + + + + KEY + DATA + + Insert a record into the + current database. + + + + + + KEY + TDBFILE + + Move a record from the + current database into TDBFILE. + + + + + + KEY + DATA + + Store (replace) a record in the + current database. + + + + + + KEY + + Show a record by key. + + + + + + KEY + + Delete a record by key. + + + + + + + Print the current database hash table and free list. + + + + + + + Print the current database and free list. + + + + + + COMMAND + + Execute the given system command. + + + + + + + + Print the first record in the current database. + + + + + + + + Print the next record in the current database. + + + + + + + + Check the integrity of the current database. + + + + + + + + Exit tdbtool. + + + + + + + + CAVEATS + The contents of the Samba TDB files are private + to the implementation and should not be altered with + tdbtool. + + + + + VERSION + This man page is correct for version 3.0.25 of the Samba suite. + + + + AUTHOR + + The original Samba software and related utilities were + created by Andrew Tridgell. Samba is now developed by the + Samba Team as an Open Source project similar to the way the + Linux kernel is developed. + + + diff -Nru ldb-1.1.13/lib/tdb/manpages/tdbbackup.8.xml ldb-1.1.15/lib/tdb/manpages/tdbbackup.8.xml --- ldb-1.1.13/lib/tdb/manpages/tdbbackup.8.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/manpages/tdbbackup.8.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ - - - - - - tdbbackup - 8 - Samba - System Administration tools - 3.6 - - - - - tdbbackup - tool for backing up and for validating the integrity of samba .tdb files - - - - - tdbbackup - -s suffix - -v - -h - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbbackup is a tool that may be used to backup samba .tdb - files. This tool may also be used to verify the integrity of the .tdb files prior - to samba startup or during normal operation. If it finds file damage and it finds - a prior backup the backup file will be restored. - - - - - - OPTIONS - - - - - -h - - Get help information. - - - - - -s suffix - - The -s option allows the adminisistrator to specify a file - backup extension. This way it is possible to keep a history of tdb backup - files by using a new suffix for each backup. - - - - - -v - - The -v will check the database for damages (currupt data) - which if detected causes the backup to be restored. - - - - - - - - - COMMANDS - - GENERAL INFORMATION - - - The tdbbackup utility can safely be run at any time. It was designed so - that it can be used at any time to validate the integrity of tdb files, even during Samba - operation. Typical usage for the command will be: - - - tdbbackup [-s suffix] *.tdb - - - Before restarting samba the following command may be run to validate .tdb files: - - - tdbbackup -v [-s suffix] *.tdb - - - Samba .tdb files are stored in various locations, be sure to run backup all - .tdb file on the system. Important files includes: - - - - - secrets.tdb - usual location is in the /usr/local/samba/private - directory, or on some systems in /etc/samba. - - - - passdb.tdb - usual location is in the /usr/local/samba/private - directory, or on some systems in /etc/samba. - - - - *.tdb located in the /usr/local/samba/var directory or on some - systems in the /var/cache or /var/lib/samba directories. - - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - - The tdbbackup man page was written by John H Terpstra. - - - diff -Nru ldb-1.1.13/lib/tdb/manpages/tdbdump.8.xml ldb-1.1.15/lib/tdb/manpages/tdbdump.8.xml --- ldb-1.1.13/lib/tdb/manpages/tdbdump.8.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/manpages/tdbdump.8.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ - - - - - - tdbdump - 8 - Samba - System Administration tools - 3.6 - - - - - tdbdump - tool for printing the contents of a TDB file - - - - - tdbdump - filename - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbdump is a very simple utility that 'dumps' the - contents of a TDB (Trivial DataBase) file to standard output in a - human-readable format. - - - This tool can be used when debugging problems with TDB files. It is - intended for those who are somewhat familiar with Samba internals. - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - - The tdbdump man page was written by Jelmer Vernooij. - - - diff -Nru ldb-1.1.13/lib/tdb/manpages/tdbrestore.8.xml ldb-1.1.15/lib/tdb/manpages/tdbrestore.8.xml --- ldb-1.1.13/lib/tdb/manpages/tdbrestore.8.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/manpages/tdbrestore.8.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ - - - - - - tdbrestore - 8 - Samba - System Administration tools - 3.6 - - - - - tdbrestore - tool for creating a TDB file out of a tdbdump output - - - - - tdbrestore - tdbfilename - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbrestore is a very simple utility that 'restores' the - contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump - command. - - - This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename - parameter. - - This tool can be used for unpacking the content of tdb as backup mean. - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - This tool was initially written by Volker Lendecke based on an - idea by Simon McVittie. - - - The tdbrestore man page was written by Matthieu Patou. - - - diff -Nru ldb-1.1.13/lib/tdb/manpages/tdbtool.8.xml ldb-1.1.15/lib/tdb/manpages/tdbtool.8.xml --- ldb-1.1.13/lib/tdb/manpages/tdbtool.8.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/manpages/tdbtool.8.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,235 +0,0 @@ - - - - - - tdbtool - 8 - Samba - System Administration tools - 3.6 - - - - - tdbtool - manipulate the contents TDB files - - - - - - tdbtool - - - - tdbtool - - TDBFILE - - - COMMANDS - - - - - - - DESCRIPTION - - This tool is part of the - samba - 1 suite. - - tdbtool a tool for displaying and - altering the contents of Samba TDB (Trivial DataBase) files. Each - of the commands listed below can be entered interactively or - provided on the command line. - - - - - - COMMANDS - - - - - - TDBFILE - Create a new database named - TDBFILE. - - - - - - TDBFILE - Open an existing database named - TDBFILE. - - - - - - Erase the current database. - - - - - - Dump the current database as strings. - - - - - - Dump the current database as connection records. - - - - - - Dump the current database keys as strings. - - - - - - Dump the current database keys as hex values. - - - - - - Print summary information about the - current database. - - - - - - KEY - DATA - - Insert a record into the - current database. - - - - - - KEY - TDBFILE - - Move a record from the - current database into TDBFILE. - - - - - - KEY - DATA - - Store (replace) a record in the - current database. - - - - - - KEY - - Show a record by key. - - - - - - KEY - - Delete a record by key. - - - - - - - Print the current database hash table and free list. - - - - - - - Print the current database and free list. - - - - - - COMMAND - - Execute the given system command. - - - - - - - - Print the first record in the current database. - - - - - - - - Print the next record in the current database. - - - - - - - - Check the integrity of the current database. - - - - - - - - Exit tdbtool. - - - - - - - - CAVEATS - The contents of the Samba TDB files are private - to the implementation and should not be altered with - tdbtool. - - - - - VERSION - This man page is correct for version 3.0.25 of the Samba suite. - - - - AUTHOR - - The original Samba software and related utilities were - created by Andrew Tridgell. Samba is now developed by the - Samba Team as an Open Source project similar to the way the - Linux kernel is developed. - - - diff -Nru ldb-1.1.13/lib/tdb/pytdb.c ldb-1.1.15/lib/tdb/pytdb.c --- ldb-1.1.13/lib/tdb/pytdb.c 2012-07-23 13:43:05.000000000 +0000 +++ ldb-1.1.15/lib/tdb/pytdb.c 2013-01-27 11:51:43.000000000 +0000 @@ -164,7 +164,14 @@ int ret; PyErr_TDB_RAISE_IF_CLOSED(self); ret = tdb_reopen(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + if (ret != 0) { + self->closed = true; + PyErr_SetObject(PyExc_RuntimeError, + Py_BuildValue("(i,s)", + TDB_ERR_IO, + "Failed to reopen database")); + return NULL; + } Py_RETURN_NONE; } @@ -209,7 +216,13 @@ Py_RETURN_NONE; ret = tdb_close(self->ctx); self->closed = true; - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + if (ret != 0) { + PyErr_SetObject(PyExc_RuntimeError, + Py_BuildValue("(i,s)", + TDB_ERR_IO, + "Failed to close database")); + return NULL; + } Py_RETURN_NONE; } diff -Nru ldb-1.1.13/lib/tdb/test/run-rescue-find_entry.c ldb-1.1.15/lib/tdb/test/run-rescue-find_entry.c --- ldb-1.1.13/lib/tdb/test/run-rescue-find_entry.c 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/test/run-rescue-find_entry.c 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,50 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "tap-interface.h" +#include +#include "logging.h" + +#define NUM 20 + +/* Binary searches are deceptively simple: easy to screw up! */ +int main(int argc, char *argv[]) +{ + unsigned int i, j, n; + struct found f[NUM+1]; + struct found_table table; + + /* Set up array for searching. */ + for (i = 0; i < NUM+1; i++) { + f[i].head = i * 3; + } + table.arr = f; + + for (i = 0; i < NUM; i++) { + table.num = i; + for (j = 0; j < (i + 2) * 3; j++) { + n = find_entry(&table, j); + ok1(n <= i); + + /* If we were searching for something too large... */ + if (j > i*3) + ok1(n == i); + else { + /* It must give us something after j */ + ok1(f[n].head >= j); + ok1(n == 0 || f[n-1].head < j); + } + } + } + + return exit_status(); +} diff -Nru ldb-1.1.13/lib/tdb/test/run-rescue.c ldb-1.1.15/lib/tdb/test/run-rescue.c --- ldb-1.1.13/lib/tdb/test/run-rescue.c 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/lib/tdb/test/run-rescue.c 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,126 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "tap-interface.h" +#include +#include "logging.h" + +struct walk_data { + TDB_DATA key; + TDB_DATA data; + bool fail; + unsigned count; +}; + +static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static inline TDB_DATA tdb_mkdata(const void *p, size_t len) +{ + TDB_DATA d; + d.dptr = (void *)p; + d.dsize = len; + return d; +} + +static void walk(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key)) { + wd->fail = true; + } + + if (!tdb_deq(data, wd->data)) { + wd->fail = true; + } + wd->count++; +} + +static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) + diag("%.*s::%.*s\n", + (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); + wd->count++; +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + (*count)++; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + struct walk_data wd; + unsigned int i, size, log_count = 0; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(8); + tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); + + wd.key.dsize = strlen("hi"); + wd.key.dptr = (void *)"hi"; + wd.data.dsize = strlen("world"); + wd.data.dptr = (void *)"world"; + wd.count = 0; + wd.fail = false; + + ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); + + ok1(tdb_rescue(tdb, walk, &wd) == 0); + ok1(!wd.fail); + ok1(wd.count == 1); + + /* Corrupt the database, walk should either get it or not. */ + size = tdb->map_size; + for (i = sizeof(struct tdb_header); i < size; i++) { + char c; + if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) + fail("Reading offset %i", i); + if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) + fail("Writing X at offset %i", i); + + wd.count = 0; + if (tdb_rescue(tdb, count_records, &wd) != 0) { + wd.fail = true; + break; + } + /* Could be 0 or 1. */ + if (wd.count > 1) { + wd.fail = true; + break; + } + if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) + fail("Restoring offset %i", i); + } + ok1(log_count == 0); + ok1(!wd.fail); + tdb_close(tdb); + + /* Now try our known-corrupt db. */ + tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + wd.count = 0; + ok1(tdb_rescue(tdb, count_records, &wd) == 0); + ok1(wd.count == 1627); + tdb_close(tdb); + + return exit_status(); +} diff -Nru ldb-1.1.13/lib/tdb/tools/tdbdump.c ldb-1.1.15/lib/tdb/tools/tdbdump.c --- ldb-1.1.13/lib/tdb/tools/tdbdump.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/tools/tdbdump.c 2013-01-27 11:51:43.000000000 +0000 @@ -51,19 +51,66 @@ return 0; } -static int dump_tdb(const char *fname, const char *keyname) +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + if (keyname) { + if (key.dsize != strlen(keyname)) + return; + if (memcmp(key.dptr, keyname, key.dsize) != 0) + return; + } + traverse_fn(NULL, key, dbuf, NULL); +} + +static int dump_tdb(const char *fname, const char *keyname, bool emergency) { TDB_CONTEXT *tdb; TDB_DATA key, value; + struct tdb_logging_context logfn = { log_stderr }; - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); if (!tdb) { printf("Failed to open %s\n", fname); return 1; } + if (emergency) { + return tdb_rescue(tdb, emergency_walk, keyname) == 0; + } if (!keyname) { - tdb_traverse(tdb, traverse_fn, NULL); + return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; } else { key.dptr = discard_const_p(uint8_t, keyname); key.dsize = strlen(keyname); @@ -84,11 +131,13 @@ printf( "Usage: tdbdump [options] \n\n"); printf( " -h this help message\n"); printf( " -k keyname dumps value of keyname\n"); + printf( " -e emergency dump, for corrupt databases\n"); } int main(int argc, char *argv[]) { char *fname, *keyname=NULL; + bool emergency = false; int c; if (argc < 2) { @@ -96,7 +145,7 @@ exit(1); } - while ((c = getopt( argc, argv, "hk:")) != -1) { + while ((c = getopt( argc, argv, "hk:e")) != -1) { switch (c) { case 'h': usage(); @@ -104,6 +153,9 @@ case 'k': keyname = optarg; break; + case 'e': + emergency = true; + break; default: usage(); exit( 1); @@ -112,5 +164,5 @@ fname = argv[optind]; - return dump_tdb(fname, keyname); + return dump_tdb(fname, keyname, emergency); } diff -Nru ldb-1.1.13/lib/tdb/tools/tdbtorture.c ldb-1.1.15/lib/tdb/tools/tdbtorture.c --- ldb-1.1.13/lib/tdb/tools/tdbtorture.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tdb/tools/tdbtorture.c 2013-01-27 11:51:43.000000000 +0000 @@ -438,10 +438,10 @@ db = tdb_open_ex(test_tdb, hash_size, TDB_DEFAULT, O_RDWR, 0, &log_ctx, NULL); if (!db) { - fatal("db open failed"); + fatal("db open failed\n"); } if (tdb_check(db, NULL, NULL) == -1) { - printf("db check failed"); + printf("db check failed\n"); exit(1); } tdb_close(db); diff -Nru ldb-1.1.13/lib/tdb/wscript ldb-1.1.15/lib/tdb/wscript --- ldb-1.1.13/lib/tdb/wscript 2012-06-23 11:50:58.000000000 +0000 +++ ldb-1.1.15/lib/tdb/wscript 2013-01-27 11:51:43.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tdb' -VERSION = '1.2.10' +VERSION = '1.2.11' blddir = 'bin' @@ -65,7 +65,7 @@ COMMON_SRC = bld.SUBDIR('common', '''check.c error.c tdb.c traverse.c freelistcheck.c lock.c dump.c freelist.c - io.c open.c transaction.c hash.c summary.c''') + io.c open.c transaction.c hash.c summary.c rescue.c''') if bld.env.standalone_tdb: bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' @@ -94,20 +94,20 @@ bld.SAMBA_BINARY('tdbrestore', 'tools/tdbrestore.c', - 'tdb', manpages='manpages/tdbrestore.8') + 'tdb', manpages='man/tdbrestore.8') bld.SAMBA_BINARY('tdbdump', 'tools/tdbdump.c', - 'tdb', manpages='manpages/tdbdump.8') + 'tdb', manpages='man/tdbdump.8') bld.SAMBA_BINARY('tdbbackup', 'tools/tdbbackup.c', 'tdb', - manpages='manpages/tdbbackup.8') + manpages='man/tdbbackup.8') bld.SAMBA_BINARY('tdbtool', 'tools/tdbtool.c', - 'tdb', manpages='manpages/tdbtool.8') + 'tdb', manpages='man/tdbtool.8') # FIXME: This hardcoded list is stupid, stupid, stupid. bld.SAMBA_SUBSYSTEM('tdb-test-helpers', @@ -143,6 +143,10 @@ 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-readonly-check', 'test/run-readonly-check.c', 'replace tdb-test-helpers', includes='include', install=False) + bld.SAMBA_BINARY('tdb1-run-rescue', 'test/run-rescue.c', + 'replace tdb-test-helpers', includes='include', install=False) + bld.SAMBA_BINARY('tdb1-run-rescue-find_entry', 'test/run-rescue-find_entry.c', + 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-rwlock-check', 'test/run-rwlock-check.c', 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-summary', 'test/run-summary.c', @@ -185,7 +189,7 @@ if not os.path.exists(link): os.symlink(os.path.abspath(os.path.join(env.cwd, 'test')), link) - for f in 'tdb1-run-3G-file', 'tdb1-run-bad-tdb-header', 'tdb1-run', 'tdb1-run-check', 'tdb1-run-corrupt', 'tdb1-run-die-during-transaction', 'tdb1-run-endian', 'tdb1-run-incompatible', 'tdb1-run-nested-transactions', 'tdb1-run-nested-traverse', 'tdb1-run-no-lock-during-traverse', 'tdb1-run-oldhash', 'tdb1-run-open-during-transaction', 'tdb1-run-readonly-check', 'tdb1-run-rwlock-check', 'tdb1-run-summary', 'tdb1-run-transaction-expand', 'tdb1-run-traverse-in-transaction', 'tdb1-run-wronghash-fail', 'tdb1-run-zero-append': + for f in 'tdb1-run-3G-file', 'tdb1-run-bad-tdb-header', 'tdb1-run', 'tdb1-run-check', 'tdb1-run-corrupt', 'tdb1-run-die-during-transaction', 'tdb1-run-endian', 'tdb1-run-incompatible', 'tdb1-run-nested-transactions', 'tdb1-run-nested-traverse', 'tdb1-run-no-lock-during-traverse', 'tdb1-run-oldhash', 'tdb1-run-open-during-transaction', 'tdb1-run-readonly-check', 'tdb1-run-rescue', 'tdb1-run-rescue-find_entry', 'tdb1-run-rwlock-check', 'tdb1-run-summary', 'tdb1-run-transaction-expand', 'tdb1-run-traverse-in-transaction', 'tdb1-run-wronghash-fail', 'tdb1-run-zero-append': cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(Utils.g_module.blddir, f)) + " > test-output 2>&1" print("..." + f) ret = samba_utils.RUN_COMMAND(cmd) diff -Nru ldb-1.1.13/lib/tevent/tevent_liboop.c ldb-1.1.15/lib/tevent/tevent_liboop.c --- ldb-1.1.13/lib/tevent/tevent_liboop.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tevent/tevent_liboop.c 2013-01-27 11:51:43.000000000 +0000 @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. main select loop and event handling - wrapper for http://liboop.org/ + wrapper for http://git.lysator.liu.se/liboop/ Copyright (C) Stefan Metzmacher 2005 diff -Nru ldb-1.1.13/lib/tevent/tevent_signal.c ldb-1.1.15/lib/tevent/tevent_signal.c --- ldb-1.1.13/lib/tevent/tevent_signal.c 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/lib/tevent/tevent_signal.c 2013-01-27 11:51:43.000000000 +0000 @@ -121,10 +121,39 @@ if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) { /* we've filled the info array - block this signal until these ones are delivered */ +#ifdef HAVE_UCONTEXT_T + /* + * This is the only way for this to work. + * By default signum is blocked inside this + * signal handler using a temporary mask, + * but what we really need to do now is + * block it in the callers mask, so it + * stays blocked when the temporary signal + * handler mask is replaced when we return + * from here. The callers mask can be found + * in the ucontext_t passed in as the + * void *uctx argument. + */ + ucontext_t *ucp = (ucontext_t *)uctx; + sigaddset(&ucp->uc_sigmask, signum); +#else + /* + * WARNING !!! WARNING !!!! + * + * This code doesn't work. + * By default signum is blocked inside this + * signal handler, but calling sigprocmask + * modifies the temporary signal mask being + * used *inside* this handler, which will be + * replaced by the callers signal mask once + * we return from here. See Samba + * bug #9550 for details. + */ sigset_t set; sigemptyset(&set); sigaddset(&set, signum); sigprocmask(SIG_BLOCK, &set, NULL); +#endif TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]); } } diff -Nru ldb-1.1.13/man/ldb.3.xml ldb-1.1.15/man/ldb.3.xml --- ldb-1.1.13/man/ldb.3.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldb.3.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldb 3 + LDB + System Administration tools + 1.1 diff -Nru ldb-1.1.13/man/ldbadd.1.xml ldb-1.1.15/man/ldbadd.1.xml --- ldb-1.1.13/man/ldbadd.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbadd.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbadd 1 + LDB + System Administration tools + 1.1 @@ -75,7 +78,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/man/ldbdel.1.xml ldb-1.1.15/man/ldbdel.1.xml --- ldb-1.1.13/man/ldbdel.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbdel.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbdel 1 + LDB + System Administration tools + 1.1 @@ -73,7 +76,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/man/ldbedit.1.xml ldb-1.1.15/man/ldbedit.1.xml --- ldb-1.1.13/man/ldbedit.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbedit.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbedit 1 + LDB + System Administration tools + 1.1 @@ -166,7 +169,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/man/ldbmodify.1.xml ldb-1.1.15/man/ldbmodify.1.xml --- ldb-1.1.13/man/ldbmodify.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbmodify.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbmodify 1 + LDB + System Administration tools + 1.1 @@ -63,7 +66,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/man/ldbrename.1.xml ldb-1.1.15/man/ldbrename.1.xml --- ldb-1.1.13/man/ldbrename.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbrename.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbrename 1 + LDB + System Administration tools + 1.1 @@ -77,7 +80,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/man/ldbsearch.1.xml ldb-1.1.15/man/ldbsearch.1.xml --- ldb-1.1.13/man/ldbsearch.1.xml 2012-04-11 12:36:12.000000000 +0000 +++ ldb-1.1.15/man/ldbsearch.1.xml 2013-01-27 11:51:43.000000000 +0000 @@ -5,6 +5,9 @@ ldbsearch 1 + LDB + System Administration tools + 1.1 @@ -89,7 +92,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. diff -Nru ldb-1.1.13/tools/ldbdump.c ldb-1.1.15/tools/ldbdump.c --- ldb-1.1.13/tools/ldbdump.c 1970-01-01 00:00:00.000000000 +0000 +++ ldb-1.1.15/tools/ldbdump.c 2013-01-27 11:51:43.000000000 +0000 @@ -0,0 +1,230 @@ +/* + Unix SMB/CIFS implementation. + simple ldb tdb dump util + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include +#include +#include + +static struct ldb_context *ldb; +bool show_index = false; +bool validate_contents = false; + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) +{ + int ret, i, j; + struct ldb_dn *dn = state; + struct ldb_message *msg = talloc_zero(NULL, struct ldb_message); + struct ldb_val dbuf = { + .data = _dbuf.dptr, + .length = _dbuf.dsize, + }; + struct ldb_ldif ldif = { + .msg = msg, + .changetype = LDB_CHANGETYPE_NONE + }; + if (!msg) { + return -1; + } + + ret = ldb_unpack_data(ldb, &dbuf, msg); + if (ret != 0) { + fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); + TALLOC_FREE(msg); + return 0; + } + + if (dn && ldb_dn_compare(msg->dn, dn) != 0) { + TALLOC_FREE(msg); + return 0; + } + + if (!show_index && ldb_dn_is_special(msg->dn)) { + const char *dn_lin = ldb_dn_get_linearized(msg->dn); + if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) { + /* + the user has asked not to show index + records. Also exclude BASEINFO as it + contains meta-data which will be re-created + if this database is restored + */ + TALLOC_FREE(msg); + return 0; + } + } + + if (!validate_contents || ldb_dn_is_special(msg->dn)) { + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + return 0; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + for (j=0;jelements[i].num_values;j++) { + struct ldb_val v; + ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v); + if (ret != 0) { + v = msg->elements[i].values[j]; + if (ldb_should_b64_encode(ldb, &v)) { + v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length); + v.length = strlen((char *)v.data); + } + fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n", + ldb_dn_get_linearized(msg->dn), + msg->elements[i].name, + j, (int)v.length, (int)v.length, + v.data); + TALLOC_FREE(msg); + return 0; + } + } + } + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + + return 0; +} + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + traverse_fn(NULL, key, dbuf, keyname); +} + +static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) +{ + TDB_CONTEXT *tdb; + struct tdb_logging_context logfn = { log_stderr }; + + tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); + if (!tdb) { + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + + if (emergency) { + return tdb_rescue(tdb, emergency_walk, dn) == 0; + } + return tdb_traverse(tdb, traverse_fn, dn) == -1 ? 1 : 0; +} + +static void usage( void) +{ + printf( "Usage: ldbdump [options] \n\n"); + printf( " -h this help message\n"); + printf( " -d DN dumps DN only\n"); + printf( " -e emergency dump, for corrupt databases\n"); + printf( " -i include index and @BASEINFO records in dump\n"); + printf( " -c validate contents of the records\n"); +} + + int main(int argc, char *argv[]) +{ + bool emergency = false; + int c, rc; + char *fname; + struct ldb_dn *dn = NULL; + + ldb = ldb_init(NULL, NULL); + if (ldb == NULL) { + fprintf(stderr, "ldb: ldb_init failed()"); + exit(1); + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); + exit(1); + } + + if (argc < 2) { + printf("Usage: ldbdump \n"); + exit(1); + } + + while ((c = getopt( argc, argv, "hd:ec")) != -1) { + switch (c) { + case 'h': + usage(); + exit( 0); + case 'd': + dn = ldb_dn_new(ldb, ldb, optarg); + if (!dn) { + fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); + exit(1); + } + break; + case 'e': + emergency = true; + break; + case 'i': + show_index = true; + break; + case 'c': + validate_contents = true; + break; + default: + usage(); + exit( 1); + } + } + + fname = argv[optind]; + + return dump_tdb(fname, dn, emergency); +} diff -Nru ldb-1.1.13/wscript ldb-1.1.15/wscript --- ldb-1.1.13/wscript 2012-10-02 08:20:23.000000000 +0000 +++ ldb-1.1.15/wscript 2013-01-27 11:51:43.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.13' +VERSION = '1.1.15' blddir = 'bin' @@ -89,7 +89,7 @@ COMMON_SRC = bld.SUBDIR('common', '''ldb_modules.c ldb_ldif.c ldb_parse.c ldb_msg.c ldb_utf8.c - ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c + ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c ldb_pack.c ldb_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', @@ -228,7 +228,7 @@ bld.SAMBA_MODULE('ldb_tdb', bld.SUBDIR('ldb_tdb', - '''ldb_tdb.c ldb_pack.c ldb_search.c ldb_index.c + '''ldb_tdb.c ldb_search.c ldb_index.c ldb_cache.c ldb_tdb_wrap.c'''), init_function='ldb_tdb_init', module_init_name='ldb_init_module', @@ -253,6 +253,10 @@ bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', install=False) + # ldbdump doesn't get installed + bld.SAMBA_BINARY('ldbdump', 'tools/ldbdump.c', deps='ldb-cmdline ldb', + install=False) + bld.SAMBA_LIBRARY('ldb-cmdline', source='tools/ldbutil.c tools/cmdline.c', deps='ldb dl popt',