From 016b44c306e61d04cc1b9717826ac55d0bcca470 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Tue, 28 May 2019 17:22:10 +1200 Subject: [PATCH 01/10] ldb: test for parse errors Parse errors aren't passed up correctly by the tdb backend. This patch modifies a test to expose the issue, next patch will fix it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13959 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 2de0aebed60b8e83508f50e5391ede618ce0e595) --- lib/ldb/tests/ldb_kv_ops_test.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/ldb/tests/ldb_kv_ops_test.c b/lib/ldb/tests/ldb_kv_ops_test.c index d6a4dc0..bd9f3ee 100644 --- a/lib/ldb/tests/ldb_kv_ops_test.c +++ b/lib/ldb/tests/ldb_kv_ops_test.c @@ -203,6 +203,17 @@ static int parse(struct ldb_val key, } /* + * Parse function that just returns the int we pass it. + */ +static int parse_return(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + int *rcode = private_data; + return *rcode; +} + +/* * Test that data can be written to the kv store and be read back. */ static void test_add_get(void **state) @@ -224,6 +235,7 @@ static void test_add_get(void **state) }; struct ldb_val read; + int rcode; int flags = 0; TALLOC_CTX *tmp_ctx; @@ -261,6 +273,17 @@ static void test_add_get(void **state) assert_int_equal(sizeof(value), read.length); assert_memory_equal(value, read.data, sizeof(value)); + /* + * Now check that the error code we return in the + * parse function is returned by fetch_and_parse. + */ + for (rcode=0; rcode<50; rcode++) { + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, + parse_return, + &rcode); + assert_int_equal(ret, rcode); + } + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); assert_int_equal(ret, 0); talloc_free(tmp_ctx); -- 2.7.4 From d023197903c98eae50409f9bcd8908f340a3245e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 May 2019 16:38:08 +1200 Subject: [PATCH 02/10] ldb: Fix segfault parsing new pack formats We need to check for the errors given by ldb_unpack() et al by preserving the error code from kv_ctx->parser() called by tdb_parse_record() in ltdb_parse_record(). Otherwise we will silently accept corrupt records and segfault later. Likewise new pack formats will confuse the parser but not be detected except by the incomplete struct ldb_message. With this patch, the user will see a message like: Invalid data for index DN=@BASEINFO Failed to connect to 'st/ad_dc/private/sam.ldb' with backend 'tdb': Unable to load ltdb cache records for backend 'ldb_tdb backend' Failed to connect to st/ad_dc/private/sam.ldb - Unable to load ltdb cache records for backend 'ldb_tdb backend' This can be refined in the future by a specific check for pack format versions in a higher caller, but this much is needed regardless to detect corrupt records. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13959 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit a3101b9704f554a350493553336cbbbd7d4ae02e) --- lib/ldb/ldb_tdb/ldb_tdb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 812ddd3..51507f5 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -242,6 +242,7 @@ struct kv_ctx { int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data); + int parser_ret; }; static int ltdb_traverse_fn_wrapper(struct tdb_context *tdb, @@ -350,7 +351,8 @@ static int ltdb_parse_record_wrapper(TDB_DATA tdb_key, .data = tdb_data.dptr, }; - return kv_ctx->parser(key, data, kv_ctx->ctx); + kv_ctx->parser_ret = kv_ctx->parser(key, data, kv_ctx->ctx); + return kv_ctx->parser_ret; } static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, @@ -374,7 +376,9 @@ static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, ret = tdb_parse_record( ldb_kv->tdb, key, ltdb_parse_record_wrapper, &kv_ctx); - if (ret == 0) { + if (kv_ctx.parser_ret != LDB_SUCCESS) { + return kv_ctx.parser_ret; + } else if (ret == 0) { return LDB_SUCCESS; } return ltdb_err_map(tdb_error(ldb_kv->tdb)); -- 2.7.4 From d899fc6bb1ec12dd7ba1da42a986332b11573b10 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Fri, 10 May 2019 18:10:51 +1200 Subject: [PATCH 03/10] ldb: baseinfo pack format check on init We will be adding a new packing format in forthcoming commits and there may be more versions in the future. We need to make sure the database contains records in a format we know how to read and write. Done by fetching the @BASEINFO record and reading the first 4 bytes which contain the packing format version. NOTE: Configure with --abi-check-disable to build this commit. This patch is part of a set of LDB ABI changes, and the version update is done on the last commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13977 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Gary Lockyer (backported from commit 474e55523224430781ed22aa2d0c8a474306e794) --- lib/ldb/common/ldb_pack.c | 23 ++++++++++++++-------- lib/ldb/include/ldb_module.h | 9 +++++++++ lib/ldb/ldb_key_value/ldb_kv.c | 2 ++ lib/ldb/ldb_key_value/ldb_kv.h | 1 + lib/ldb/ldb_key_value/ldb_kv_cache.c | 37 ++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c index 448c577..286803f 100644 --- a/lib/ldb/common/ldb_pack.c +++ b/lib/ldb/common/ldb_pack.c @@ -33,12 +33,6 @@ #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) { @@ -229,7 +223,7 @@ int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb, size_t remaining; size_t dn_len; unsigned int i, j; - unsigned format; + uint32_t format; unsigned int nelem = 0; size_t len; unsigned int found = 0; @@ -247,7 +241,10 @@ int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb, goto failed; } - format = pull_uint32(p, 0); + if (ldb_unpack_get_format(data, &format) != LDB_SUCCESS) { + errno = EIO; + goto failed; + } message->num_elements = pull_uint32(p, 4); p += 8; if (nb_elements_in_db) { @@ -504,6 +501,16 @@ failed: return -1; } +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version) +{ + if (data->length < 4) { + return LDB_ERR_OPERATIONS_ERROR; + } + *pack_format_version = pull_uint32(data->data, 0); + return LDB_SUCCESS; +} + /* * Unpack a ldb message from a linear buffer in ldb_val * diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h index c73fc37..8c47082 100644 --- a/lib/ldb/include/ldb_module.h +++ b/lib/ldb/include/ldb_module.h @@ -561,11 +561,20 @@ int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb, unsigned int flags, unsigned int *nb_elements_in_db); +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version); + #define LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC 0x0001 #define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002 #define LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC 0x0004 #define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 +/* In-use packing formats */ +#define LDB_PACKING_FORMAT 0x26011967 + +/* Old packing formats */ +#define LDB_PACKING_FORMAT_NODN 0x26011966 + /** Forces a specific ldb handle to use the global event context. diff --git a/lib/ldb/ldb_key_value/ldb_kv.c b/lib/ldb/ldb_key_value/ldb_kv.c index 31bdfb5..87ed37b 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.c +++ b/lib/ldb/ldb_key_value/ldb_kv.c @@ -1902,6 +1902,8 @@ int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, ldb_kv->sequence_number = 0; + ldb_kv->pack_format_version = LDB_PACKING_FORMAT; + ldb_kv->pid = getpid(); ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); diff --git a/lib/ldb/ldb_key_value/ldb_kv.h b/lib/ldb/ldb_key_value/ldb_kv.h index cbc5213..c31973a 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.h +++ b/lib/ldb/ldb_key_value/ldb_kv.h @@ -53,6 +53,7 @@ struct ldb_kv_private { unsigned int connect_flags; unsigned long long sequence_number; + uint32_t pack_format_version; /* the low level tdb seqnum - used to avoid loading BASEINFO when possible */ diff --git a/lib/ldb/ldb_key_value/ldb_kv_cache.c b/lib/ldb/ldb_key_value/ldb_kv_cache.c index c39273f..a795b53 100644 --- a/lib/ldb/ldb_key_value/ldb_kv_cache.c +++ b/lib/ldb/ldb_key_value/ldb_kv_cache.c @@ -393,6 +393,13 @@ int ldb_kv_cache_reload(struct ldb_module *module) ldb_kv_cache_free(module); return ldb_kv_cache_load(module); } +static int get_pack_format_version(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + uint32_t *v = (uint32_t *) private_data; + return ldb_unpack_get_format(&data, v); +} /* load the cache records @@ -409,6 +416,8 @@ int ldb_kv_cache_load(struct ldb_module *module) const struct ldb_schema_attribute *a; bool have_write_txn = false; int r; + uint32_t pack_format_version; + struct ldb_val key; ldb = ldb_module_get_ctx(module); @@ -433,6 +442,34 @@ int ldb_kv_cache_load(struct ldb_module *module) if (r != LDB_SUCCESS) { goto failed; } + + key = ldb_kv_key_dn(module, baseinfo, baseinfo_dn); + if (!key.data) { + goto failed_and_unlock; + } + + /* Read packing format from first 4 bytes of @BASEINFO record */ + r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, + get_pack_format_version, + &pack_format_version); + + if (r != LDB_ERR_NO_SUCH_OBJECT) { + if (r != LDB_SUCCESS) { + goto failed_and_unlock; + } + + /* Make sure the database has the right format */ + if (pack_format_version != ldb_kv->pack_format_version) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Unexpected packing format. " + "Expected: %#010x, Got: %#010x", + pack_format_version, + ldb_kv->pack_format_version); + goto failed_and_unlock; + } + } + + /* Now fetch the whole @BASEINFO record */ r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0); if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { goto failed_and_unlock; -- 2.7.4 From f8d63a1f8eab79587a390870669210ef0e3e0ee6 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Mon, 20 May 2019 16:19:51 +1200 Subject: [PATCH 04/10] ldb: ldbdump key and pack format version comments For testing we need to know the actual KV level key of records and each record's pack format version. This patch makes ldbdump add comments with that info. We will parse it out in python tests. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Gary Lockyer Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Wed May 22 05:58:17 UTC 2019 on sn-devel-184 (cherry picked from commit a666a99e4dc594bc153cd26b24cddd547c1cc750) --- lib/ldb/tools/ldbdump.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/ldb/tools/ldbdump.c b/lib/ldb/tools/ldbdump.c index a466e49..09b4fe0 100644 --- a/lib/ldb/tools/ldbdump.c +++ b/lib/ldb/tools/ldbdump.c @@ -36,6 +36,26 @@ static struct ldb_context *ldb; bool show_index = false; bool validate_contents = false; +static void print_data(TDB_DATA d) +{ + unsigned char *p = (unsigned char *)d.dptr; + int len = d.dsize; + while (len--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + fputc(*p, stdout); + } else { + printf("\\%02X", *p); + } + p++; + } +} + +static unsigned int pull_uint32(uint8_t *p) +{ + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + + static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) { int ret, i, j; @@ -79,6 +99,10 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *sta } } + printf("# key: "); + print_data(key); + printf("\n# pack format: %#010x\n", pull_uint32(_dbuf.dptr)); + if (!validate_contents || ldb_dn_is_special(msg->dn)) { ldb_ldif_write_file(ldb, stdout, &ldif); TALLOC_FREE(msg); -- 2.7.4 From 205f2ad6412c22bb91c08cc0be196499393a0d0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 16 Jul 2019 17:53:47 +1200 Subject: [PATCH 05/10] ldb: Release ldb 1.5.6 * Fix segfault parsing new pack formats or invalid packed data (bug 13959) * Check for new pack formats during startup (bug 13977) * Making ldbdump print out pack format info and keys so we have low level visibility for testing in python (for bug 13978) BUG: https://bugzilla.samba.org/show_bug.cgi?id=13959 Signed-off-by: Andrew Bartlett --- lib/ldb/ABI/ldb-1.5.6.sigs | 281 ++++++++++++++++++++++++++++++++++ lib/ldb/ABI/pyldb-util-1.5.6.sigs | 2 + lib/ldb/ABI/pyldb-util.py3-1.5.6.sigs | 2 + lib/ldb/wscript | 2 +- 4 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 lib/ldb/ABI/ldb-1.5.6.sigs create mode 100644 lib/ldb/ABI/pyldb-util-1.5.6.sigs create mode 100644 lib/ldb/ABI/pyldb-util.py3-1.5.6.sigs diff --git a/lib/ldb/ABI/ldb-1.5.6.sigs b/lib/ldb/ABI/ldb-1.5.6.sigs new file mode 100644 index 0000000..9bf06ce --- /dev/null +++ b/lib/ldb/ABI/ldb-1.5.6.sigs @@ -0,0 +1,281 @@ +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_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +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_ldb_context: struct ldb_context *(struct ldb_dn *) +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_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +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_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +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_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_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_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: 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_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +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_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +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_require_private_event_context: void (struct ldb_context *) +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_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +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 --git a/lib/ldb/ABI/pyldb-util-1.5.6.sigs b/lib/ldb/ABI/pyldb-util-1.5.6.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util-1.5.6.sigs @@ -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 --git a/lib/ldb/ABI/pyldb-util.py3-1.5.6.sigs b/lib/ldb/ABI/pyldb-util.py3-1.5.6.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util.py3-1.5.6.sigs @@ -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 --git a/lib/ldb/wscript b/lib/ldb/wscript index f8eabbf..92975b9 100644 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.5.5' +VERSION = '1.5.6' import sys, os -- 2.7.4 From dd552f764bee0179a2aa734982929c16ef06959b Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Sat, 9 Mar 2019 13:48:29 +1300 Subject: [PATCH 06/10] s4/scripting: MORE py3 compatible print functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett (cherry picked from commit 561b654bc5bc2f5e614c5c2ab378193ca94d481a) --- source4/scripting/bin/autoidl | 19 ++++++------- source4/scripting/bin/fullschema | 9 ++++--- source4/scripting/bin/get-descriptors | 9 ++++--- source4/scripting/bin/minschema | 47 ++++++++++++++++++--------------- source4/scripting/bin/sambaundoguididx | 8 +++--- source4/scripting/bin/smbstatus | 19 ++++++------- source4/scripting/devel/addlotscontacts | 4 +-- source4/scripting/devel/crackname | 10 +++---- source4/scripting/devel/getncchanges | 8 +++--- 9 files changed, 71 insertions(+), 62 deletions(-) diff --git a/source4/scripting/bin/autoidl b/source4/scripting/bin/autoidl index 8c4267f..07701d1 100755 --- a/source4/scripting/bin/autoidl +++ b/source4/scripting/bin/autoidl @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from __future__ import print_function import sys @@ -107,25 +108,25 @@ class Function: if base_request is None: raise Exception("Unable to determine base size for opnum %d" % self.opnum) - print "\tBase request is %r" % base_request + print("\tBase request is %r" % base_request) decision_byte_map = map(lambda x: self.check_decision_byte(base_request, x), range(len(base_request))) - print decision_byte_map + print(decision_byte_map) # find pointers possible_pointers = map(all, [decision_byte_map[i*4:(i+1)*4] for i in range(int(len(base_request)/4))]) - print possible_pointers + print(possible_pointers) pointer_deferrant_bases = map( lambda x: self.find_deferrant_data(base_request, x) if possible_pointers[x] else None, range(len(possible_pointers))) - print pointer_deferrant_bases + print(pointer_deferrant_bases) if len(sys.argv) < 3: - print "Usage: autoidl []" + print("Usage: autoidl []") sys.exit(1) (binding, uuid) = sys.argv[1:3] @@ -147,15 +148,15 @@ if version is None: else: conn = ClientConnection(binding, (uuid, version)) -print "Figuring out number of connections...", +print("Figuring out number of connections... ", end='') num_funcs = find_num_funcs(conn) -print "%d" % num_funcs +print("%d" % num_funcs) # Figure out the syntax for each one for i in range(num_funcs): - print "Function %d" % i + print("Function %d" % i) data = Function(conn, i) try: data.find_idl() except Exception as e: - print "Error: %r" % e + print("Error: %r" % e) diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema index ccfc067..26e33d8 100755 --- a/source4/scripting/bin/fullschema +++ b/source4/scripting/bin/fullschema @@ -2,6 +2,7 @@ # # Works out the full schema # +from __future__ import print_function import base64 import optparse @@ -147,12 +148,12 @@ def write_ldif_one(o, attrs): value = fix_dn(j) if a != "cn": if a == "oMObjectClass": - print "%s:: %s" % (a, base64.b64encode(value)).decode('utf8') + print("%s:: %s" % (a, base64.b64encode(value)).decode('utf8')) elif a.endswith("GUID"): - print "%s: %s" % (a, ldb.schema_format_value(a, value)) + print("%s: %s" % (a, ldb.schema_format_value(a, value))) else: - print "%s: %s" % (a, value) - print "" + print("%s: %s" % (a, value)) + print() # get the rootDSE diff --git a/source4/scripting/bin/get-descriptors b/source4/scripting/bin/get-descriptors index 0a5c31d..31106d4 100755 --- a/source4/scripting/bin/get-descriptors +++ b/source4/scripting/bin/get-descriptors @@ -26,6 +26,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from __future__ import print_function import optparse import sys @@ -97,12 +98,12 @@ class DescrGetter: l = line[i * length:((i + 1) * length)] else: l = " " + line[(i * length):((i + 1) * length)] - print l - print "\n" + print(l) + print("\n") def write_as_sddl(self, dn, descr): - print dn - print descr + "\n" + print(dn) + print(descr + "\n") def read_descr_by_base(self, search_base): res = self.samdb.search(base=search_base + self.local_domain, expression="(objectClass=*)", scope=SCOPE_SUBTREE, attrs=["nTSecurityDescriptor"]) diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index 62a0b0b..f0e532e 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -2,7 +2,7 @@ # # Works out the minimal schema for a set of objectclasses # - +from __future__ import print_function import base64 import optparse import sys @@ -251,15 +251,15 @@ def find_objectclass_auto(ldb, o): return testdn = create_testdn(o.exampleDN) - print "testdn is '%s'" % testdn + print("testdn is '%s'" % testdn) ldif = "dn: " + testdn ldif += "\nobjectClass: " + o.name try: ldb.add(ldif) except LdbError as e: - print "error adding %s: %s" % (o.name, e) - print "%s" % ldif + print("error adding %s: %s" % (o.name, e)) + print("%s" % ldif) return res = ldb.search(base=testdn, scope=ldb.SCOPE_BASE) @@ -279,7 +279,7 @@ def expand_objectclass(ldb, o): expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name, base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) - print >>sys.stderr, "Expanding class %s" % o.name + print("Expanding class %s" % o.name, file=sys.stderr) assert(len(res) == 1) msg = res[0] for aname in attrs: @@ -290,7 +290,7 @@ def expand_objectclass(ldb, o): list = [msg[aname]] for name in list: if not objectclasses.has_key(name): - print >>sys.stderr, "Found new objectclass '%s'" % name + print("Found new objectclass '%s'" % name, file=sys.stderr) objectclasses[name] = Objectclass(ldb, name) @@ -317,13 +317,15 @@ def walk_dn(ldb, dn): try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, attrs) except LdbError as e: - print >>sys.stderr, "Unable to fetch allowedAttributes for '%s' - %r" % (dn, e) + print("Unable to fetch allowedAttributes for '%s' - %r" % (dn, e), + file=sys.stderr) return allattrs = res[0]["allowedAttributes"] try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, allattrs) except LdbError as e: - print >>sys.stderr, "Unable to fetch all attributes for '%s' - %s" % (dn, e) + print("Unable to fetch all attributes for '%s' - %s" % (dn, e), + file=sys.stderr) return msg = res[0] for a in msg: @@ -336,7 +338,8 @@ def walk_naming_context(ldb, namingContext): res = ldb.search("objectClass=*", namingContext, SCOPE_DEFAULT, ["objectClass"]) except LdbError as e: - print >>sys.stderr, "Unable to fetch objectClasses for '%s' - %s" % (namingContext, e) + print("Unable to fetch objectClasses for '%s' - %s" % (namingContext, e), + file=sys.stderr) return for msg in res: msg = res.msgs[r]["objectClass"] @@ -389,7 +392,7 @@ def build_objectclass(ldb, name): base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) if len(res) == 0: - print >>sys.stderr, "unknown class '%s'" % name + print("unknown class '%s'" % name, file=sys.stderr) return None return Objectclass(ldb, name) @@ -424,7 +427,7 @@ def write_aggregate_objectclass(objectclass): list = attribute_list(objectclass, "systemMayContain", "mayContain") line += aggregate_list("MAY", list) - print line + " )" + print(line + " )") def write_aggregate_ditcontentrule(objectclass): @@ -451,7 +454,7 @@ def write_aggregate_ditcontentrule(objectclass): line += aggregate_list("MUST", must_list) line += aggregate_list("MAY", may_list) - print line + " )" + print(line + " )") def write_aggregate_attribute(attrib): """write the aggregate record for an attribute""" @@ -463,15 +466,15 @@ def write_aggregate_attribute(attrib): if attrib.get('systemOnly') == "TRUE": line += "NO-USER-MODIFICATION " - print line + ")" + print(line + ")") def write_aggregate(): """write the aggregate record""" - print "dn: CN=Aggregate,${SCHEMADN}" - print """objectClass: top + print("dn: CN=Aggregate,${SCHEMADN}") + print("""objectClass: top objectClass: subSchema -objectCategory: CN=SubSchema,${SCHEMADN}""" +objectCategory: CN=SubSchema,${SCHEMADN}""") if not opts.dump_subschema_auto: return @@ -552,15 +555,15 @@ if not opts.verbose: # # dump list of objectclasses # -print "objectClasses:\n" +print("objectClasses:\n") for objectclass in objectclasses: - print "\t%s\n" % objectclass + print("\t%s\n" % objectclass) -print "attributes:\n" +print("attributes:\n") for attr in attributes: - print "\t%s\n" % attr + print("\t%s\n" % attr) -print "autocreated attributes:\n" +print("autocreated attributes:\n") for attr in attributes: if attr.autocreate: - print "\t%s\n" % i + print("\t%s\n" % i) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index 20a84c3..00fe638 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +from __future__ import print_function import optparse import sys @@ -73,11 +74,12 @@ samdb.transaction_commit() print("Re-opening with the full DB stack") samdb = SamDB(url=url, lp=lp_ctx) -print "Re-triggering another re-index" +print("Re-triggering another re-index") chk = dbcheck(samdb) chk.reindex_database() -print "Your database has been downgraded to DN-based index values." +print("Your database has been downgraded to DN-based index values.") -print "NOTE: Any use of a Samba 4.8 tool including ldbsearch will auto-upgrade back to GUID index mode" +print("NOTE: Any use of a Samba 4.8 tool including ldbsearch will " + "auto-upgrade back to GUID index mode") diff --git a/source4/scripting/bin/smbstatus b/source4/scripting/bin/smbstatus index d171a43..fd67b2c 100755 --- a/source4/scripting/bin/smbstatus +++ b/source4/scripting/bin/smbstatus @@ -8,7 +8,7 @@ # Copyright Andrew Tridgell 2005 # Released under the GNU GPL version 3 or later # - +from __future__ import print_function import os, sys # make sure the script dies immediately when hitting control-C, @@ -40,25 +40,26 @@ def show_tcons(open_connection): """show open tree connects""" conn = open_connection("smb_server") tcons = next(conn.smbsrv_information(irpc.SMBSRV_INFO_TCONS)) - print "Share Client Connected at" - print "-" * 79 + print("Share Client Connected at") + print("-" * 79) for tcon in tcons: - print "%-30s %16s %s" % (tcon.share_name, tcon.client_ip, sys.httptime(tcon.connect_time)) + print("%-30s %16s %s" % + (tcon.share_name, tcon.client_ip, sys.httptime(tcon.connect_time))) def show_nbt(open_connection): """show nbtd information""" conn = open_connection("nbt_server") stats = next(conn.nbtd_information(irpc.NBTD_INFO_STATISTICS)) - print "NBT server statistics:" + print("NBT server statistics:") fields = [("total_received", "Total received"), ("total_sent", "Total sent"), ("query_count", "Query count"), ("register_count", "Register count"), ("release_count", "Release count")] for (field, description) in fields: - print "\t%s:\t%s" % (description, getattr(stats, field)) - print + print("\t%s:\t%s" % (description, getattr(stats, field))) + print() parser = optparse.OptionParser("%s [options]" % sys.argv[0]) sambaopts = options.SambaOptions(parser) @@ -71,7 +72,7 @@ opts, args = parser.parse_args() lp = sambaopts.get_loadparm() -print "%s" % lp.get("server string") +print("%s" % lp.get("server string")) messaging_path = (opts.messaging_path or os.path.join(lp.get("private dir"), "smbd.tmp", "messaging")) @@ -85,7 +86,7 @@ else: conn = open_connection("smb_server") except RuntimeError, (num, msg): if msg == 'NT_STATUS_OBJECT_NAME_NOT_FOUND': - print "No active connections" + print("No active connections") else: show_sessions(conn) show_tcons(conn) diff --git a/source4/scripting/devel/addlotscontacts b/source4/scripting/devel/addlotscontacts index 42c88a55..aff1409 100644 --- a/source4/scripting/devel/addlotscontacts +++ b/source4/scripting/devel/addlotscontacts @@ -15,7 +15,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +from __future__ import print_function __docformat__ = "restructuredText" @@ -88,7 +88,7 @@ if __name__ == '__main__': "objectClass") if count !=0 and (count % increment) == 0: - print "Added contacts: %d" % count + print("Added contacts: %d" % count) ldbs.sam.add(msg) count += 1 diff --git a/source4/scripting/devel/crackname b/source4/scripting/devel/crackname index 196cc45..4dbe472 100755 --- a/source4/scripting/devel/crackname +++ b/source4/scripting/devel/crackname @@ -3,7 +3,7 @@ # Copyright Matthieu Patou 2011 # script to call a DRSUAPI crackname # this is useful for plugfest testing and replication debug - +from __future__ import print_function import sys from optparse import OptionParser @@ -71,8 +71,8 @@ if __name__ == "__main__": req.names = [names] (result, ctr) = drs.DsCrackNames(drs_handle, 1, req) - print "# of result = %d" %ctr.count + print("# of result = %d" %ctr.count) if ctr.count: - print "status = %d" % ctr.array[0].status - print "result name = %s" % ctr.array[0].result_name - print "domain = %s" % ctr.array[0].dns_domain_name + print("status = %d" % ctr.array[0].status) + print("result name = %s" % ctr.array[0].result_name) + print("domain = %s" % ctr.array[0].dns_domain_name) diff --git a/source4/scripting/devel/getncchanges b/source4/scripting/devel/getncchanges index 3929b90..3c132f5 100755 --- a/source4/scripting/devel/getncchanges +++ b/source4/scripting/devel/getncchanges @@ -2,7 +2,7 @@ # script to call a DRS GetNCChanges from the command line # this is useful for plugfest testing - +from __future__ import print_function import sys from optparse import OptionParser @@ -98,17 +98,17 @@ if __name__ == "__main__": dest_dsa = opts.dest_dsa if not dest_dsa: - print "no dest_dsa specified trying to figure out from ldap" + print("no dest_dsa specified trying to figure out from ldap") msgs = samdb.search(controls=["search_options:1:2"], expression='(objectclass=ntdsdsa)') if len(msgs) == 1: dest_dsa = str(ndr_unpack(misc.GUID, msgs[0]["invocationId"][0])) - print "Found this dsa: %s" % dest_dsa + print("Found this dsa: %s" % dest_dsa) else: # TODO fixme pass if not dest_dsa: - print "Unable to find the dest_dsa automatically please specify it" + print("Unable to find the dest_dsa automatically please specify it") import sys sys.exit(1) -- 2.7.4 From 5e51447dfc878a11c34bda0b6eb97c05f495d3a9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 May 2019 16:29:10 +1200 Subject: [PATCH 07/10] sambaundoguididx: Add flags=ldb.FLG_DONT_CREATE_DB and port to Python3 In py3 we need to add an extra str() around the returned ldb value to enable .split() to be used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed By: Noel Power Autobuild-User(master): Noel Power Autobuild-Date(master): Thu May 23 14:25:52 UTC 2019 on sn-devel-184 (cherry picked from commit 1a9da378a1505daff498be6d6355debd73526a1a) --- source4/scripting/bin/sambaundoguididx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index 00fe638..f67353f 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -34,7 +34,9 @@ if opts.H is None: else: url = opts.H -samdb = ldb.Ldb(url=url, options=["modules:"]) +samdb = ldb.Ldb(url=url, + flags=ldb.FLG_DONT_CREATE_DB, + options=["modules:"]) partitions = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE, @@ -58,10 +60,11 @@ privatedir = os.path.dirname(url) dbs = [] for part in partitions[0]['partition']: - tdbname = part.split(":")[1] - tdbpath = os.path.join(privatedir, tdbname) - - db = ldb.Ldb(url=tdbpath, options=["modules:"]) + dbname = str(part).split(":")[1] + dbpath = os.path.join(privatedir, dbname) + db = ldb.Ldb(url="ldb://" + dbpath, + options=["modules:"], + flags=ldb.FLG_DONT_CREATE_DB) db.transaction_start() db.modify(modmsg) dbs.append(db) @@ -73,7 +76,8 @@ samdb.transaction_commit() print("Re-opening with the full DB stack") samdb = SamDB(url=url, - lp=lp_ctx) + flags=ldb.FLG_DONT_CREATE_DB, + lp=lp_ctx) print("Re-triggering another re-index") chk = dbcheck(samdb) -- 2.7.4 From b2d00c8a6ca1a14ad8f91bfdd8ad27550493732d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 May 2019 16:29:10 +1200 Subject: [PATCH 08/10] sambaundoguididx: fix for -s Quick fix running this script with -s instead of -H. samdb_url() returns a url with a protocol prefix, which causes issues further down in the script. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 40ca8ed5a152ae7c5ec039649c09a037a20a4143) --- source4/scripting/bin/sambaundoguididx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index f67353f..7474acb 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -30,7 +30,7 @@ lp_ctx = sambaopts.get_loadparm() lp_ctx.set("dsdb:guid index", "false") if opts.H is None: - url = lp_ctx.samdb_url() + url = lp_ctx.private_path("sam.ldb") else: url = opts.H @@ -62,7 +62,9 @@ dbs = [] for part in partitions[0]['partition']: dbname = str(part).split(":")[1] dbpath = os.path.join(privatedir, dbname) - db = ldb.Ldb(url="ldb://" + dbpath, + if os.path.isfile(dbpath): + dbpath = "ldb://" + dbpath + db = ldb.Ldb(url=dbpath, options=["modules:"], flags=ldb.FLG_DONT_CREATE_DB) db.transaction_start() -- 2.7.4 From e9b65ca72bb29caefce793a15a5fec3fae79bb7d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 29 May 2019 16:36:00 +1200 Subject: [PATCH 09/10] undoduididx: Add "or later" to warning about using tools from Samba 4.8 BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 09f2a187b3d8c161e2c11588499b3256a9dbcc95) --- source4/scripting/bin/sambaundoguididx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx index 7474acb..0d18282 100755 --- a/source4/scripting/bin/sambaundoguididx +++ b/source4/scripting/bin/sambaundoguididx @@ -87,5 +87,5 @@ chk.reindex_database() print("Your database has been downgraded to DN-based index values.") -print("NOTE: Any use of a Samba 4.8 tool including ldbsearch will " +print("NOTE: Any use of a Samba 4.8 or later tool including ldbsearch will " "auto-upgrade back to GUID index mode") -- 2.7.4 From af5b3d256e7f9a5d7b0ee66d98e19fcb9f0a9f71 Mon Sep 17 00:00:00 2001 From: Aaron Haslett Date: Thu, 23 May 2019 13:21:19 +1200 Subject: [PATCH 10/10] undoguidx: blackbox test This test confirms that running undoguididx causes all GUID keys to be replaced with DN keys at the KV level BUG: https://bugzilla.samba.org/show_bug.cgi?id=13978 Signed-off-by: Aaron Haslett Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam (backport from commit 74d15c9bf76f0a2fb5fa7b7b1d80971d10c4fe45, ab376a97c972d2d5ebfb912ed90664c787860dc8 and 56400153c8c7052fe319f273c30c6d59556102dc) ab376a97c972d2d5ebfb912ed90664c787860dc8 was: selftest: Specifically remove files generated by provision Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall 56400153c8c7052fe319f273c30c6d59556102dc was: Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- python/samba/tests/blackbox/undoguididx.py | 107 +++++++++++++++++++++++++++++ source4/selftest/tests.py | 2 + 2 files changed, 109 insertions(+) create mode 100644 python/samba/tests/blackbox/undoguididx.py diff --git a/python/samba/tests/blackbox/undoguididx.py b/python/samba/tests/blackbox/undoguididx.py new file mode 100644 index 0000000..b4e0179 --- /dev/null +++ b/python/samba/tests/blackbox/undoguididx.py @@ -0,0 +1,107 @@ +# Blackbox tests for sambaundoguididx +# +# Copyright (C) Catalyst IT Ltd. 2019 +# +# 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 . +# +from __future__ import print_function +from samba.tests import BlackboxTestCase +import os +import ldb +import shutil +from subprocess import check_output +from samba.samdb import SamDB + +COMMAND = os.path.join(os.path.dirname(__file__), + "../../../../../source4/scripting/bin/sambaundoguididx") + + +class DowngradeTest(BlackboxTestCase): + """Test that sambaundoguididx downgrades the samba database""" + backend = 'tdb' + + def setUp(self): + super(DowngradeTest, self).setUp() + + prov_cmd = "samba-tool domain provision " +\ + "--domain FOO --realm foo.example.com " +\ + "--targetdir {self.tempdir} " +\ + "--backend-store {self.backend} " +\ + "--host-name downgradetest " +\ + "--option=\"vfs objects=fake_acls xattr_tdb\"" + prov_cmd = prov_cmd.format(self=self) + self.check_run(prov_cmd, "Provisioning for downgrade") + + private_dir = os.path.join(self.tempdir, "private") + self.sam_path = os.path.join(private_dir, "sam.ldb") + self.ldb = ldb.Ldb(self.sam_path, options=["modules:"]) + + partitions = self.ldb.search(base="@PARTITION", + scope=ldb.SCOPE_BASE, + attrs=["partition"]) + partitions = partitions[0]['partition'] + partitions = [str(p).split(":")[1] for p in partitions] + self.dbs = [os.path.join(private_dir, p) + for p in partitions] + self.dbs.append(self.sam_path) + + def tearDown(self): + shutil.rmtree(os.path.join(self.tempdir, "private")) + shutil.rmtree(os.path.join(self.tempdir, "etc")) + shutil.rmtree(os.path.join(self.tempdir, "state")) + shutil.rmtree(os.path.join(self.tempdir, "bind-dns")) + shutil.rmtree(os.path.join(self.tempdir, "msg.lock")) + os.unlink(os.path.join(self.tempdir, "names.tdb")) + os.unlink(os.path.join(self.tempdir, "gencache.tdb")) + super(DowngradeTest, self).tearDown() + + # Parse out the comments above each record that ldbdump produces + # containing pack format version and KV level key for each record. + # Return all GUID keys and DN keys (without @attrs) + def ldbdump_keys_pack_formats(self): + # Get all comments from all partition dbs + comments = [] + for db in self.dbs: + dump = check_output(["bin/ldbdump", "-i", db]) + dump = dump.decode("utf-8") + dump = dump.split("\n") + comments += [s for s in dump if s.startswith("#")] + + guid_key_tag = "# key: GUID=" + guid_keys = {c[len(guid_key_tag):] for c in comments + if c.startswith(guid_key_tag)} + + dn_key_tag = "# key: DN=" + dn_keys = {c[len(dn_key_tag):] for c in comments + if c.startswith(dn_key_tag)} + + # Ignore @ attributes, they are always DN keyed + dn_keys_no_at_attrs = {d for d in dn_keys if not d.startswith("@")} + + return dn_keys_no_at_attrs, guid_keys + + # Check that sambaundoguididx replaces all GUID keys with DN keys + def test_undo_guid_idx(self): + dn_keys, guid_keys = self.ldbdump_keys_pack_formats() + self.assertGreater(len(guid_keys), 20) + self.assertEqual(len(dn_keys), 0) + + num_guid_keys_before_downgrade = len(guid_keys) + + self.check_run("%s -H %s" % (COMMAND, self.sam_path), + msg="Running sambaundoguididx") + + dn_keys, guid_keys = self.ldbdump_keys_pack_formats() + self.assertEqual(len(guid_keys), 0) + self.assertEqual(len(dn_keys), num_guid_keys_before_downgrade) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 30fedd9..fddbf83 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -857,6 +857,8 @@ for env in ["ad_dc_ntvfs:local", "ad_dc:local", "promoted_dc:local"]: planoldpythontestsuite(env, "samba.tests.blackbox.smbcontrol", py3_compatible=True) +planoldpythontestsuite("none", "samba.tests.blackbox.undoguididx") + plantestsuite_loadlist("samba4.ldap.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.krb5.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '-k', 'yes', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.ntlm.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '-k', 'no', '$LOADLIST', '$LISTOPT']) -- 2.7.4