From 8420a36dc7fe72fb665e065b8673fa44ff1bbf21 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 5 Jul 2011 10:01:32 +1000 Subject: ldb: make ldb a top level library for Samba 4.0 Signed-off-by: Andrew Tridgell --- MAINTAINERS.txt | 2 +- buildtools/testwaf.sh | 4 +- lib/ldb-samba/README | 7 + lib/ldb-samba/ldb_ildap.c | 879 ++++++ lib/ldb-samba/ldb_wrap.c | 365 +++ lib/ldb-samba/ldb_wrap.h | 70 + lib/ldb-samba/ldif_handlers.c | 1416 +++++++++ lib/ldb-samba/ldif_handlers.h | 23 + lib/ldb-samba/pyldb.c | 270 ++ lib/ldb-samba/samba_extensions.c | 119 + lib/ldb-samba/wscript_build | 42 + lib/ldb/ABI/ldb-0.9.10.sigs | 218 ++ lib/ldb/ABI/ldb-0.9.12.sigs | 219 ++ lib/ldb/ABI/ldb-0.9.15.sigs | 226 ++ lib/ldb/ABI/ldb-0.9.16.sigs | 228 ++ lib/ldb/ABI/ldb-0.9.17.sigs | 229 ++ lib/ldb/ABI/ldb-0.9.18.sigs | 240 ++ lib/ldb/ABI/ldb-0.9.19.sigs | 245 ++ lib/ldb/ABI/ldb-0.9.20.sigs | 245 ++ lib/ldb/ABI/ldb-0.9.22.sigs | 245 ++ lib/ldb/ABI/ldb-0.9.23.sigs | 247 ++ lib/ldb/ABI/ldb-0.9.24.sigs | 248 ++ lib/ldb/ABI/ldb-1.0.0.sigs | 248 ++ lib/ldb/ABI/ldb-1.0.1.sigs | 248 ++ lib/ldb/ABI/ldb-1.0.2.sigs | 250 ++ lib/ldb/ABI/ldb-1.1.0.sigs | 253 ++ lib/ldb/ABI/ldb-ildap-0.9.12.sigs | 224 ++ lib/ldb/ABI/ldb-samba4-0.9.10.sigs | 223 ++ lib/ldb/ABI/ldb-samba4-0.9.11.sigs | 224 ++ lib/ldb/Doxyfile | 26 + lib/ldb/Makefile | 51 + lib/ldb/README_gcov.txt | 29 + lib/ldb/common/attrib_handlers.c | 496 +++ lib/ldb/common/ldb.c | 1923 ++++++++++++ lib/ldb/common/ldb_attributes.c | 306 ++ lib/ldb/common/ldb_controls.c | 1043 +++++++ lib/ldb/common/ldb_debug.c | 142 + lib/ldb/common/ldb_dn.c | 2101 +++++++++++++ lib/ldb/common/ldb_ldif.c | 1026 ++++++ lib/ldb/common/ldb_match.c | 570 ++++ lib/ldb/common/ldb_modules.c | 1146 +++++++ lib/ldb/common/ldb_msg.c | 1187 +++++++ lib/ldb/common/ldb_options.c | 72 + lib/ldb/common/ldb_parse.c | 903 ++++++ lib/ldb/common/ldb_utf8.c | 136 + lib/ldb/common/qsort.c | 251 ++ lib/ldb/configure | 21 + lib/ldb/docs/builddocs.sh | 52 + lib/ldb/docs/design.txt | 41 + lib/ldb/docs/installdocs.sh | 17 + lib/ldb/examples.dox | 16 + lib/ldb/examples/ldbreader.c | 122 + lib/ldb/examples/ldifreader.c | 125 + lib/ldb/include/dlinklist.h | 185 ++ lib/ldb/include/ldb.h | 2254 +++++++++++++ lib/ldb/include/ldb_errors.h | 312 ++ lib/ldb/include/ldb_handlers.h | 40 + lib/ldb/include/ldb_module.h | 344 ++ lib/ldb/include/ldb_private.h | 184 ++ lib/ldb/ldb.pc.in | 16 + lib/ldb/ldb_ldap/ldb_ldap.c | 982 ++++++ lib/ldb/ldb_map/ldb_map.c | 1139 +++++++ lib/ldb/ldb_map/ldb_map.h | 173 + lib/ldb/ldb_map/ldb_map_inbound.c | 837 +++++ lib/ldb/ldb_map/ldb_map_outbound.c | 1407 +++++++++ lib/ldb/ldb_map/ldb_map_private.h | 96 + lib/ldb/ldb_sqlite3/README | 7 + lib/ldb/ldb_sqlite3/base160.c | 154 + lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 1940 ++++++++++++ lib/ldb/ldb_sqlite3/schema | 328 ++ lib/ldb/ldb_sqlite3/trees.ps | 1760 +++++++++++ lib/ldb/ldb_tdb/ldb_cache.c | 490 +++ lib/ldb/ldb_tdb/ldb_index.c | 1599 ++++++++++ lib/ldb/ldb_tdb/ldb_pack.c | 292 ++ lib/ldb/ldb_tdb/ldb_search.c | 618 ++++ lib/ldb/ldb_tdb/ldb_tdb.c | 1519 +++++++++ lib/ldb/ldb_tdb/ldb_tdb.h | 139 + lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 165 + lib/ldb/mainpage.dox | 80 + lib/ldb/man/ldb.3.xml | 262 ++ lib/ldb/man/ldbadd.1.xml | 105 + lib/ldb/man/ldbdel.1.xml | 105 + lib/ldb/man/ldbedit.1.xml | 200 ++ lib/ldb/man/ldbmodify.1.xml | 93 + lib/ldb/man/ldbrename.1.xml | 107 + lib/ldb/man/ldbsearch.1.xml | 119 + lib/ldb/modules/asq.c | 416 +++ lib/ldb/modules/paged_results.c | 438 +++ lib/ldb/modules/paged_searches.c | 386 +++ lib/ldb/modules/rdn_name.c | 453 +++ lib/ldb/modules/skel.c | 147 + lib/ldb/modules/sort.c | 360 +++ lib/ldb/nssldb/README.txt | 34 + lib/ldb/nssldb/ldb-grp.c | 429 +++ lib/ldb/nssldb/ldb-nss.c | 395 +++ lib/ldb/nssldb/ldb-nss.h | 84 + lib/ldb/nssldb/ldb-pwd.c | 242 ++ lib/ldb/pyldb-util.pc.in | 13 + lib/ldb/pyldb.c | 3302 ++++++++++++++++++++ lib/ldb/pyldb.h | 105 + lib/ldb/pyldb_util.c | 119 + lib/ldb/tests/init.ldif | 41 + lib/ldb/tests/init_slapd.sh | 41 + lib/ldb/tests/kill_slapd.sh | 12 + lib/ldb/tests/ldapi_url.sh | 11 + lib/ldb/tests/photo.ldif | 5 + lib/ldb/tests/python/api.py | 748 +++++ lib/ldb/tests/samba4.png | Bin 0 -> 6239 bytes lib/ldb/tests/sample_module.c | 71 + lib/ldb/tests/schema-tests/schema-add-test.ldif | 66 + lib/ldb/tests/schema-tests/schema-mod-test-1.ldif | 5 + lib/ldb/tests/schema-tests/schema-mod-test-2.ldif | 5 + lib/ldb/tests/schema-tests/schema-mod-test-3.ldif | 5 + lib/ldb/tests/schema-tests/schema-mod-test-4.ldif | 5 + lib/ldb/tests/schema-tests/schema-mod-test-5.ldif | 5 + lib/ldb/tests/schema-tests/schema.ldif | 100 + lib/ldb/tests/slapd.conf | 26 + lib/ldb/tests/start_slapd.sh | 14 + lib/ldb/tests/test-attribs.ldif | 6 + lib/ldb/tests/test-config.ldif | 67 + lib/ldb/tests/test-controls.sh | 45 + lib/ldb/tests/test-default-config.ldif | 17 + lib/ldb/tests/test-extended.sh | 69 + lib/ldb/tests/test-generic.sh | 128 + lib/ldb/tests/test-index.ldif | 7 + lib/ldb/tests/test-ldap.sh | 54 + lib/ldb/tests/test-modify-modrdn.ldif | 12 + lib/ldb/tests/test-modify.ldif | 23 + lib/ldb/tests/test-schema.sh | 34 + lib/ldb/tests/test-soloading.sh | 32 + lib/ldb/tests/test-sqlite3.sh | 25 + lib/ldb/tests/test-tdb-features.sh | 160 + lib/ldb/tests/test-tdb.sh | 33 + lib/ldb/tests/test-wildcard.ldif | 5 + lib/ldb/tests/test-wrong_attributes.ldif | 3 + lib/ldb/tests/test.ldif | 417 +++ lib/ldb/tests/testdata.txt | 8 + lib/ldb/tests/testsearch.txt | 5 + lib/ldb/tools/cmdline.c | 469 +++ lib/ldb/tools/cmdline.h | 56 + lib/ldb/tools/ldbadd.c | 154 + lib/ldb/tools/ldbdel.c | 135 + lib/ldb/tools/ldbedit.c | 372 +++ lib/ldb/tools/ldbmodify.c | 156 + lib/ldb/tools/ldbrename.c | 84 + lib/ldb/tools/ldbsearch.c | 317 ++ lib/ldb/tools/ldbtest.c | 434 +++ lib/ldb/tools/ldbutil.c | 219 ++ lib/ldb/tools/ldbutil.h | 46 + lib/ldb/web/index.html | 74 + lib/ldb/wscript | 287 ++ script/autobuild.py | 4 +- script/land.py | 2 +- source4/lib/ldb-samba/README | 7 - source4/lib/ldb-samba/ldb_ildap.c | 879 ------ source4/lib/ldb-samba/ldb_wrap.c | 365 --- source4/lib/ldb-samba/ldb_wrap.h | 70 - source4/lib/ldb-samba/ldif_handlers.c | 1416 --------- source4/lib/ldb-samba/ldif_handlers.h | 23 - source4/lib/ldb-samba/pyldb.c | 270 -- source4/lib/ldb-samba/samba_extensions.c | 119 - source4/lib/ldb-samba/wscript_build | 42 - source4/lib/ldb/ABI/ldb-0.9.10.sigs | 218 -- source4/lib/ldb/ABI/ldb-0.9.12.sigs | 219 -- source4/lib/ldb/ABI/ldb-0.9.15.sigs | 226 -- source4/lib/ldb/ABI/ldb-0.9.16.sigs | 228 -- source4/lib/ldb/ABI/ldb-0.9.17.sigs | 229 -- source4/lib/ldb/ABI/ldb-0.9.18.sigs | 240 -- source4/lib/ldb/ABI/ldb-0.9.19.sigs | 245 -- source4/lib/ldb/ABI/ldb-0.9.20.sigs | 245 -- source4/lib/ldb/ABI/ldb-0.9.22.sigs | 245 -- source4/lib/ldb/ABI/ldb-0.9.23.sigs | 247 -- source4/lib/ldb/ABI/ldb-0.9.24.sigs | 248 -- source4/lib/ldb/ABI/ldb-1.0.0.sigs | 248 -- source4/lib/ldb/ABI/ldb-1.0.1.sigs | 248 -- source4/lib/ldb/ABI/ldb-1.0.2.sigs | 250 -- source4/lib/ldb/ABI/ldb-1.1.0.sigs | 253 -- source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs | 224 -- source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs | 223 -- source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs | 224 -- source4/lib/ldb/Doxyfile | 26 - source4/lib/ldb/Makefile | 51 - source4/lib/ldb/README_gcov.txt | 29 - source4/lib/ldb/common/attrib_handlers.c | 496 --- source4/lib/ldb/common/ldb.c | 1923 ------------ source4/lib/ldb/common/ldb_attributes.c | 306 -- source4/lib/ldb/common/ldb_controls.c | 1043 ------- source4/lib/ldb/common/ldb_debug.c | 142 - source4/lib/ldb/common/ldb_dn.c | 2101 ------------- source4/lib/ldb/common/ldb_ldif.c | 1026 ------ source4/lib/ldb/common/ldb_match.c | 570 ---- source4/lib/ldb/common/ldb_modules.c | 1146 ------- source4/lib/ldb/common/ldb_msg.c | 1187 ------- source4/lib/ldb/common/ldb_options.c | 72 - source4/lib/ldb/common/ldb_parse.c | 903 ------ source4/lib/ldb/common/ldb_utf8.c | 136 - source4/lib/ldb/common/qsort.c | 251 -- source4/lib/ldb/configure | 21 - source4/lib/ldb/docs/builddocs.sh | 52 - source4/lib/ldb/docs/design.txt | 41 - source4/lib/ldb/docs/installdocs.sh | 17 - source4/lib/ldb/examples.dox | 16 - source4/lib/ldb/examples/ldbreader.c | 122 - source4/lib/ldb/examples/ldifreader.c | 125 - source4/lib/ldb/include/dlinklist.h | 185 -- source4/lib/ldb/include/ldb.h | 2254 ------------- source4/lib/ldb/include/ldb_errors.h | 312 -- source4/lib/ldb/include/ldb_handlers.h | 40 - source4/lib/ldb/include/ldb_module.h | 344 -- source4/lib/ldb/include/ldb_private.h | 184 -- source4/lib/ldb/ldb.pc.in | 16 - source4/lib/ldb/ldb_ldap/ldb_ldap.c | 982 ------ source4/lib/ldb/ldb_map/ldb_map.c | 1139 ------- source4/lib/ldb/ldb_map/ldb_map.h | 173 - source4/lib/ldb/ldb_map/ldb_map_inbound.c | 837 ----- source4/lib/ldb/ldb_map/ldb_map_outbound.c | 1407 --------- source4/lib/ldb/ldb_map/ldb_map_private.h | 96 - source4/lib/ldb/ldb_sqlite3/README | 7 - source4/lib/ldb/ldb_sqlite3/base160.c | 154 - source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 1940 ------------ source4/lib/ldb/ldb_sqlite3/schema | 328 -- source4/lib/ldb/ldb_sqlite3/trees.ps | 1760 ----------- source4/lib/ldb/ldb_tdb/ldb_cache.c | 490 --- source4/lib/ldb/ldb_tdb/ldb_index.c | 1599 ---------- source4/lib/ldb/ldb_tdb/ldb_pack.c | 292 -- source4/lib/ldb/ldb_tdb/ldb_search.c | 618 ---- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 1519 --------- source4/lib/ldb/ldb_tdb/ldb_tdb.h | 139 - source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 165 - source4/lib/ldb/mainpage.dox | 80 - source4/lib/ldb/man/ldb.3.xml | 262 -- source4/lib/ldb/man/ldbadd.1.xml | 105 - source4/lib/ldb/man/ldbdel.1.xml | 105 - source4/lib/ldb/man/ldbedit.1.xml | 200 -- source4/lib/ldb/man/ldbmodify.1.xml | 93 - source4/lib/ldb/man/ldbrename.1.xml | 107 - source4/lib/ldb/man/ldbsearch.1.xml | 119 - source4/lib/ldb/modules/asq.c | 416 --- source4/lib/ldb/modules/paged_results.c | 438 --- source4/lib/ldb/modules/paged_searches.c | 386 --- source4/lib/ldb/modules/rdn_name.c | 453 --- source4/lib/ldb/modules/skel.c | 147 - source4/lib/ldb/modules/sort.c | 360 --- source4/lib/ldb/nssldb/README.txt | 34 - source4/lib/ldb/nssldb/ldb-grp.c | 429 --- source4/lib/ldb/nssldb/ldb-nss.c | 395 --- source4/lib/ldb/nssldb/ldb-nss.h | 84 - source4/lib/ldb/nssldb/ldb-pwd.c | 242 -- source4/lib/ldb/pyldb-util.pc.in | 13 - source4/lib/ldb/pyldb.c | 3302 -------------------- source4/lib/ldb/pyldb.h | 105 - source4/lib/ldb/pyldb_util.c | 119 - source4/lib/ldb/tests/init.ldif | 41 - source4/lib/ldb/tests/init_slapd.sh | 41 - source4/lib/ldb/tests/kill_slapd.sh | 12 - source4/lib/ldb/tests/ldapi_url.sh | 11 - source4/lib/ldb/tests/photo.ldif | 5 - source4/lib/ldb/tests/python/api.py | 748 ----- source4/lib/ldb/tests/samba4.png | Bin 6239 -> 0 bytes source4/lib/ldb/tests/sample_module.c | 71 - .../ldb/tests/schema-tests/schema-add-test.ldif | 66 - .../ldb/tests/schema-tests/schema-mod-test-1.ldif | 5 - .../ldb/tests/schema-tests/schema-mod-test-2.ldif | 5 - .../ldb/tests/schema-tests/schema-mod-test-3.ldif | 5 - .../ldb/tests/schema-tests/schema-mod-test-4.ldif | 5 - .../ldb/tests/schema-tests/schema-mod-test-5.ldif | 5 - source4/lib/ldb/tests/schema-tests/schema.ldif | 100 - source4/lib/ldb/tests/slapd.conf | 26 - source4/lib/ldb/tests/start_slapd.sh | 14 - source4/lib/ldb/tests/test-attribs.ldif | 6 - source4/lib/ldb/tests/test-config.ldif | 67 - source4/lib/ldb/tests/test-controls.sh | 45 - source4/lib/ldb/tests/test-default-config.ldif | 17 - source4/lib/ldb/tests/test-extended.sh | 69 - source4/lib/ldb/tests/test-generic.sh | 128 - source4/lib/ldb/tests/test-index.ldif | 7 - source4/lib/ldb/tests/test-ldap.sh | 54 - source4/lib/ldb/tests/test-modify-modrdn.ldif | 12 - source4/lib/ldb/tests/test-modify.ldif | 23 - source4/lib/ldb/tests/test-schema.sh | 34 - source4/lib/ldb/tests/test-soloading.sh | 32 - source4/lib/ldb/tests/test-sqlite3.sh | 25 - source4/lib/ldb/tests/test-tdb-features.sh | 160 - source4/lib/ldb/tests/test-tdb.sh | 33 - source4/lib/ldb/tests/test-wildcard.ldif | 5 - source4/lib/ldb/tests/test-wrong_attributes.ldif | 3 - source4/lib/ldb/tests/test.ldif | 417 --- source4/lib/ldb/tests/testdata.txt | 8 - source4/lib/ldb/tests/testsearch.txt | 5 - source4/lib/ldb/tools/cmdline.c | 469 --- source4/lib/ldb/tools/cmdline.h | 56 - source4/lib/ldb/tools/ldbadd.c | 154 - source4/lib/ldb/tools/ldbdel.c | 135 - source4/lib/ldb/tools/ldbedit.c | 372 --- source4/lib/ldb/tools/ldbmodify.c | 156 - source4/lib/ldb/tools/ldbrename.c | 84 - source4/lib/ldb/tools/ldbsearch.c | 317 -- source4/lib/ldb/tools/ldbtest.c | 434 --- source4/lib/ldb/tools/ldbutil.c | 219 -- source4/lib/ldb/tools/ldbutil.h | 46 - source4/lib/ldb/web/index.html | 74 - source4/lib/ldb/wscript | 287 -- source4/selftest/tests.py | 4 +- wscript | 4 +- wscript_build | 4 +- 305 files changed, 49352 insertions(+), 49352 deletions(-) create mode 100644 lib/ldb-samba/README create mode 100644 lib/ldb-samba/ldb_ildap.c create mode 100644 lib/ldb-samba/ldb_wrap.c create mode 100644 lib/ldb-samba/ldb_wrap.h create mode 100644 lib/ldb-samba/ldif_handlers.c create mode 100644 lib/ldb-samba/ldif_handlers.h create mode 100644 lib/ldb-samba/pyldb.c create mode 100644 lib/ldb-samba/samba_extensions.c create mode 100644 lib/ldb-samba/wscript_build create mode 100644 lib/ldb/ABI/ldb-0.9.10.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.12.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.15.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.16.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.17.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.18.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.19.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.20.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.22.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.23.sigs create mode 100644 lib/ldb/ABI/ldb-0.9.24.sigs create mode 100644 lib/ldb/ABI/ldb-1.0.0.sigs create mode 100644 lib/ldb/ABI/ldb-1.0.1.sigs create mode 100644 lib/ldb/ABI/ldb-1.0.2.sigs create mode 100644 lib/ldb/ABI/ldb-1.1.0.sigs create mode 100644 lib/ldb/ABI/ldb-ildap-0.9.12.sigs create mode 100644 lib/ldb/ABI/ldb-samba4-0.9.10.sigs create mode 100644 lib/ldb/ABI/ldb-samba4-0.9.11.sigs create mode 100644 lib/ldb/Doxyfile create mode 100644 lib/ldb/Makefile create mode 100644 lib/ldb/README_gcov.txt create mode 100644 lib/ldb/common/attrib_handlers.c create mode 100644 lib/ldb/common/ldb.c create mode 100644 lib/ldb/common/ldb_attributes.c create mode 100644 lib/ldb/common/ldb_controls.c create mode 100644 lib/ldb/common/ldb_debug.c create mode 100644 lib/ldb/common/ldb_dn.c create mode 100644 lib/ldb/common/ldb_ldif.c create mode 100644 lib/ldb/common/ldb_match.c create mode 100644 lib/ldb/common/ldb_modules.c create mode 100644 lib/ldb/common/ldb_msg.c create mode 100644 lib/ldb/common/ldb_options.c create mode 100644 lib/ldb/common/ldb_parse.c create mode 100644 lib/ldb/common/ldb_utf8.c create mode 100644 lib/ldb/common/qsort.c create mode 100755 lib/ldb/configure create mode 100755 lib/ldb/docs/builddocs.sh create mode 100644 lib/ldb/docs/design.txt create mode 100755 lib/ldb/docs/installdocs.sh create mode 100644 lib/ldb/examples.dox create mode 100644 lib/ldb/examples/ldbreader.c create mode 100644 lib/ldb/examples/ldifreader.c create mode 100644 lib/ldb/include/dlinklist.h create mode 100644 lib/ldb/include/ldb.h create mode 100644 lib/ldb/include/ldb_errors.h create mode 100644 lib/ldb/include/ldb_handlers.h create mode 100644 lib/ldb/include/ldb_module.h create mode 100644 lib/ldb/include/ldb_private.h create mode 100644 lib/ldb/ldb.pc.in create mode 100644 lib/ldb/ldb_ldap/ldb_ldap.c create mode 100644 lib/ldb/ldb_map/ldb_map.c create mode 100644 lib/ldb/ldb_map/ldb_map.h create mode 100644 lib/ldb/ldb_map/ldb_map_inbound.c create mode 100644 lib/ldb/ldb_map/ldb_map_outbound.c create mode 100644 lib/ldb/ldb_map/ldb_map_private.h create mode 100644 lib/ldb/ldb_sqlite3/README create mode 100644 lib/ldb/ldb_sqlite3/base160.c create mode 100644 lib/ldb/ldb_sqlite3/ldb_sqlite3.c create mode 100644 lib/ldb/ldb_sqlite3/schema create mode 100644 lib/ldb/ldb_sqlite3/trees.ps create mode 100644 lib/ldb/ldb_tdb/ldb_cache.c create mode 100644 lib/ldb/ldb_tdb/ldb_index.c create mode 100644 lib/ldb/ldb_tdb/ldb_pack.c create mode 100644 lib/ldb/ldb_tdb/ldb_search.c create mode 100644 lib/ldb/ldb_tdb/ldb_tdb.c create mode 100644 lib/ldb/ldb_tdb/ldb_tdb.h create mode 100644 lib/ldb/ldb_tdb/ldb_tdb_wrap.c create mode 100644 lib/ldb/mainpage.dox create mode 100644 lib/ldb/man/ldb.3.xml create mode 100644 lib/ldb/man/ldbadd.1.xml create mode 100644 lib/ldb/man/ldbdel.1.xml create mode 100644 lib/ldb/man/ldbedit.1.xml create mode 100644 lib/ldb/man/ldbmodify.1.xml create mode 100644 lib/ldb/man/ldbrename.1.xml create mode 100644 lib/ldb/man/ldbsearch.1.xml create mode 100644 lib/ldb/modules/asq.c create mode 100644 lib/ldb/modules/paged_results.c create mode 100644 lib/ldb/modules/paged_searches.c create mode 100644 lib/ldb/modules/rdn_name.c create mode 100644 lib/ldb/modules/skel.c create mode 100644 lib/ldb/modules/sort.c create mode 100644 lib/ldb/nssldb/README.txt create mode 100644 lib/ldb/nssldb/ldb-grp.c create mode 100644 lib/ldb/nssldb/ldb-nss.c create mode 100644 lib/ldb/nssldb/ldb-nss.h create mode 100644 lib/ldb/nssldb/ldb-pwd.c create mode 100644 lib/ldb/pyldb-util.pc.in create mode 100644 lib/ldb/pyldb.c create mode 100644 lib/ldb/pyldb.h create mode 100644 lib/ldb/pyldb_util.c create mode 100644 lib/ldb/tests/init.ldif create mode 100755 lib/ldb/tests/init_slapd.sh create mode 100755 lib/ldb/tests/kill_slapd.sh create mode 100755 lib/ldb/tests/ldapi_url.sh create mode 100644 lib/ldb/tests/photo.ldif create mode 100755 lib/ldb/tests/python/api.py create mode 100644 lib/ldb/tests/samba4.png create mode 100644 lib/ldb/tests/sample_module.c create mode 100644 lib/ldb/tests/schema-tests/schema-add-test.ldif create mode 100644 lib/ldb/tests/schema-tests/schema-mod-test-1.ldif create mode 100644 lib/ldb/tests/schema-tests/schema-mod-test-2.ldif create mode 100644 lib/ldb/tests/schema-tests/schema-mod-test-3.ldif create mode 100644 lib/ldb/tests/schema-tests/schema-mod-test-4.ldif create mode 100644 lib/ldb/tests/schema-tests/schema-mod-test-5.ldif create mode 100644 lib/ldb/tests/schema-tests/schema.ldif create mode 100644 lib/ldb/tests/slapd.conf create mode 100755 lib/ldb/tests/start_slapd.sh create mode 100644 lib/ldb/tests/test-attribs.ldif create mode 100644 lib/ldb/tests/test-config.ldif create mode 100755 lib/ldb/tests/test-controls.sh create mode 100644 lib/ldb/tests/test-default-config.ldif create mode 100755 lib/ldb/tests/test-extended.sh create mode 100755 lib/ldb/tests/test-generic.sh create mode 100644 lib/ldb/tests/test-index.ldif create mode 100755 lib/ldb/tests/test-ldap.sh create mode 100644 lib/ldb/tests/test-modify-modrdn.ldif create mode 100644 lib/ldb/tests/test-modify.ldif create mode 100755 lib/ldb/tests/test-schema.sh create mode 100755 lib/ldb/tests/test-soloading.sh create mode 100755 lib/ldb/tests/test-sqlite3.sh create mode 100644 lib/ldb/tests/test-tdb-features.sh create mode 100755 lib/ldb/tests/test-tdb.sh create mode 100644 lib/ldb/tests/test-wildcard.ldif create mode 100644 lib/ldb/tests/test-wrong_attributes.ldif create mode 100644 lib/ldb/tests/test.ldif create mode 100644 lib/ldb/tests/testdata.txt create mode 100644 lib/ldb/tests/testsearch.txt create mode 100644 lib/ldb/tools/cmdline.c create mode 100644 lib/ldb/tools/cmdline.h create mode 100644 lib/ldb/tools/ldbadd.c create mode 100644 lib/ldb/tools/ldbdel.c create mode 100644 lib/ldb/tools/ldbedit.c create mode 100644 lib/ldb/tools/ldbmodify.c create mode 100644 lib/ldb/tools/ldbrename.c create mode 100644 lib/ldb/tools/ldbsearch.c create mode 100644 lib/ldb/tools/ldbtest.c create mode 100644 lib/ldb/tools/ldbutil.c create mode 100644 lib/ldb/tools/ldbutil.h create mode 100644 lib/ldb/web/index.html create mode 100755 lib/ldb/wscript delete mode 100644 source4/lib/ldb-samba/README delete mode 100644 source4/lib/ldb-samba/ldb_ildap.c delete mode 100644 source4/lib/ldb-samba/ldb_wrap.c delete mode 100644 source4/lib/ldb-samba/ldb_wrap.h delete mode 100644 source4/lib/ldb-samba/ldif_handlers.c delete mode 100644 source4/lib/ldb-samba/ldif_handlers.h delete mode 100644 source4/lib/ldb-samba/pyldb.c delete mode 100644 source4/lib/ldb-samba/samba_extensions.c delete mode 100644 source4/lib/ldb-samba/wscript_build delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.10.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.12.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.15.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.16.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.17.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.18.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.19.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.20.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.22.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.23.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-0.9.24.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-1.0.0.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-1.0.1.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-1.0.2.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-1.1.0.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs delete mode 100644 source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs delete mode 100644 source4/lib/ldb/Doxyfile delete mode 100644 source4/lib/ldb/Makefile delete mode 100644 source4/lib/ldb/README_gcov.txt delete mode 100644 source4/lib/ldb/common/attrib_handlers.c delete mode 100644 source4/lib/ldb/common/ldb.c delete mode 100644 source4/lib/ldb/common/ldb_attributes.c delete mode 100644 source4/lib/ldb/common/ldb_controls.c delete mode 100644 source4/lib/ldb/common/ldb_debug.c delete mode 100644 source4/lib/ldb/common/ldb_dn.c delete mode 100644 source4/lib/ldb/common/ldb_ldif.c delete mode 100644 source4/lib/ldb/common/ldb_match.c delete mode 100644 source4/lib/ldb/common/ldb_modules.c delete mode 100644 source4/lib/ldb/common/ldb_msg.c delete mode 100644 source4/lib/ldb/common/ldb_options.c delete mode 100644 source4/lib/ldb/common/ldb_parse.c delete mode 100644 source4/lib/ldb/common/ldb_utf8.c delete mode 100644 source4/lib/ldb/common/qsort.c delete mode 100755 source4/lib/ldb/configure delete mode 100755 source4/lib/ldb/docs/builddocs.sh delete mode 100644 source4/lib/ldb/docs/design.txt delete mode 100755 source4/lib/ldb/docs/installdocs.sh delete mode 100644 source4/lib/ldb/examples.dox delete mode 100644 source4/lib/ldb/examples/ldbreader.c delete mode 100644 source4/lib/ldb/examples/ldifreader.c delete mode 100644 source4/lib/ldb/include/dlinklist.h delete mode 100644 source4/lib/ldb/include/ldb.h delete mode 100644 source4/lib/ldb/include/ldb_errors.h delete mode 100644 source4/lib/ldb/include/ldb_handlers.h delete mode 100644 source4/lib/ldb/include/ldb_module.h delete mode 100644 source4/lib/ldb/include/ldb_private.h delete mode 100644 source4/lib/ldb/ldb.pc.in delete mode 100644 source4/lib/ldb/ldb_ldap/ldb_ldap.c delete mode 100644 source4/lib/ldb/ldb_map/ldb_map.c delete mode 100644 source4/lib/ldb/ldb_map/ldb_map.h delete mode 100644 source4/lib/ldb/ldb_map/ldb_map_inbound.c delete mode 100644 source4/lib/ldb/ldb_map/ldb_map_outbound.c delete mode 100644 source4/lib/ldb/ldb_map/ldb_map_private.h delete mode 100644 source4/lib/ldb/ldb_sqlite3/README delete mode 100644 source4/lib/ldb/ldb_sqlite3/base160.c delete mode 100644 source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c delete mode 100644 source4/lib/ldb/ldb_sqlite3/schema delete mode 100644 source4/lib/ldb/ldb_sqlite3/trees.ps delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_cache.c delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_index.c delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_pack.c delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_search.c delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_tdb.c delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_tdb.h delete mode 100644 source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c delete mode 100644 source4/lib/ldb/mainpage.dox delete mode 100644 source4/lib/ldb/man/ldb.3.xml delete mode 100644 source4/lib/ldb/man/ldbadd.1.xml delete mode 100644 source4/lib/ldb/man/ldbdel.1.xml delete mode 100644 source4/lib/ldb/man/ldbedit.1.xml delete mode 100644 source4/lib/ldb/man/ldbmodify.1.xml delete mode 100644 source4/lib/ldb/man/ldbrename.1.xml delete mode 100644 source4/lib/ldb/man/ldbsearch.1.xml delete mode 100644 source4/lib/ldb/modules/asq.c delete mode 100644 source4/lib/ldb/modules/paged_results.c delete mode 100644 source4/lib/ldb/modules/paged_searches.c delete mode 100644 source4/lib/ldb/modules/rdn_name.c delete mode 100644 source4/lib/ldb/modules/skel.c delete mode 100644 source4/lib/ldb/modules/sort.c delete mode 100644 source4/lib/ldb/nssldb/README.txt delete mode 100644 source4/lib/ldb/nssldb/ldb-grp.c delete mode 100644 source4/lib/ldb/nssldb/ldb-nss.c delete mode 100644 source4/lib/ldb/nssldb/ldb-nss.h delete mode 100644 source4/lib/ldb/nssldb/ldb-pwd.c delete mode 100644 source4/lib/ldb/pyldb-util.pc.in delete mode 100644 source4/lib/ldb/pyldb.c delete mode 100644 source4/lib/ldb/pyldb.h delete mode 100644 source4/lib/ldb/pyldb_util.c delete mode 100644 source4/lib/ldb/tests/init.ldif delete mode 100755 source4/lib/ldb/tests/init_slapd.sh delete mode 100755 source4/lib/ldb/tests/kill_slapd.sh delete mode 100755 source4/lib/ldb/tests/ldapi_url.sh delete mode 100644 source4/lib/ldb/tests/photo.ldif delete mode 100755 source4/lib/ldb/tests/python/api.py delete mode 100644 source4/lib/ldb/tests/samba4.png delete mode 100644 source4/lib/ldb/tests/sample_module.c delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-add-test.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif delete mode 100644 source4/lib/ldb/tests/schema-tests/schema.ldif delete mode 100644 source4/lib/ldb/tests/slapd.conf delete mode 100755 source4/lib/ldb/tests/start_slapd.sh delete mode 100644 source4/lib/ldb/tests/test-attribs.ldif delete mode 100644 source4/lib/ldb/tests/test-config.ldif delete mode 100755 source4/lib/ldb/tests/test-controls.sh delete mode 100644 source4/lib/ldb/tests/test-default-config.ldif delete mode 100755 source4/lib/ldb/tests/test-extended.sh delete mode 100755 source4/lib/ldb/tests/test-generic.sh delete mode 100644 source4/lib/ldb/tests/test-index.ldif delete mode 100755 source4/lib/ldb/tests/test-ldap.sh delete mode 100644 source4/lib/ldb/tests/test-modify-modrdn.ldif delete mode 100644 source4/lib/ldb/tests/test-modify.ldif delete mode 100755 source4/lib/ldb/tests/test-schema.sh delete mode 100755 source4/lib/ldb/tests/test-soloading.sh delete mode 100755 source4/lib/ldb/tests/test-sqlite3.sh delete mode 100644 source4/lib/ldb/tests/test-tdb-features.sh delete mode 100755 source4/lib/ldb/tests/test-tdb.sh delete mode 100644 source4/lib/ldb/tests/test-wildcard.ldif delete mode 100644 source4/lib/ldb/tests/test-wrong_attributes.ldif delete mode 100644 source4/lib/ldb/tests/test.ldif delete mode 100644 source4/lib/ldb/tests/testdata.txt delete mode 100644 source4/lib/ldb/tests/testsearch.txt delete mode 100644 source4/lib/ldb/tools/cmdline.c delete mode 100644 source4/lib/ldb/tools/cmdline.h delete mode 100644 source4/lib/ldb/tools/ldbadd.c delete mode 100644 source4/lib/ldb/tools/ldbdel.c delete mode 100644 source4/lib/ldb/tools/ldbedit.c delete mode 100644 source4/lib/ldb/tools/ldbmodify.c delete mode 100644 source4/lib/ldb/tools/ldbrename.c delete mode 100644 source4/lib/ldb/tools/ldbsearch.c delete mode 100644 source4/lib/ldb/tools/ldbtest.c delete mode 100644 source4/lib/ldb/tools/ldbutil.c delete mode 100644 source4/lib/ldb/tools/ldbutil.h delete mode 100644 source4/lib/ldb/web/index.html delete mode 100755 source4/lib/ldb/wscript diff --git a/MAINTAINERS.txt b/MAINTAINERS.txt index 466ae54d6a7..36e1840cbfa 100644 --- a/MAINTAINERS.txt +++ b/MAINTAINERS.txt @@ -62,7 +62,7 @@ policy: pass. Larger commits require discussion on samba-technical list and review by the maintainer -files: lib/tevent/py*, lib/talloc/py*, source4/lib/ldb/py*, lib/tdb/py* +files: lib/tevent/py*, lib/talloc/py*, lib/ldb/py*, lib/tdb/py* maintainers: Jelmer Vernooij policy: diff --git a/buildtools/testwaf.sh b/buildtools/testwaf.sh index 8b65af2c10a..127e5258910 100755 --- a/buildtools/testwaf.sh +++ b/buildtools/testwaf.sh @@ -11,7 +11,7 @@ PREFIX=$HOME/testprefix if [ $# -gt 0 ]; then tests="$*" else - tests="lib/replace lib/talloc lib/tevent lib/tdb source4/lib/ldb" + tests="lib/replace lib/talloc lib/tevent lib/tdb lib/ldb" fi echo "testing in dirs $tests" @@ -27,7 +27,7 @@ for d in $tests; do make install make distcheck case $d in - "source4/lib/ldb") + "lib/ldb") ldd bin/ldbadd ;; "lib/replace") diff --git a/lib/ldb-samba/README b/lib/ldb-samba/README new file mode 100644 index 00000000000..3fa47159ca9 --- /dev/null +++ b/lib/ldb-samba/README @@ -0,0 +1,7 @@ +This directory contains Samba specific extensions to ldb. It also +serves as example code on how to extend ldb for your own application. + +The main extension Samba uses is to provide ldif encode/decode +routines for specific attributes, so users can get nice pretty +printing of attributes in ldbedit, while the attributes are stored in +the standard NDR format in the database. diff --git a/lib/ldb-samba/ldb_ildap.c b/lib/ldb-samba/ldb_ildap.c new file mode 100644 index 00000000000..3c28690bd66 --- /dev/null +++ b/lib/ldb-samba/ldb_ildap.c @@ -0,0 +1,879 @@ +/* + ldb database library - ildap backend + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Simo Sorce 2008 + + ** 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_ildap + * + * Component: ldb ildap backend + * + * Description: This is a ldb backend for the internal ldap + * client library in Samba4. By using this backend we are + * independent of a system ldap library + * + * Author: Andrew Tridgell + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * author: Simo Sorce + */ + +#include "includes.h" +#include "ldb_module.h" +#include "util/dlinklist.h" + +#include "libcli/ldap/libcli_ldap.h" +#include "libcli/ldap/ldap_client.h" +#include "auth/auth.h" +#include "auth/credentials/credentials.h" + +struct ildb_private { + struct ldap_connection *ldap; + struct tevent_context *event_ctx; +}; + +struct ildb_context { + struct ldb_module *module; + struct ldb_request *req; + + struct ildb_private *ildb; + struct ldap_request *ireq; + + /* indicate we are already processing + * the ldap_request in ildb_callback() */ + bool in_ildb_callback; + + bool done; + + struct ildb_destructor_ctx *dc; +}; + +static void ildb_request_done(struct ildb_context *ctx, + struct ldb_control **ctrls, int error) +{ + struct ldb_context *ldb; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + + ctx->done = true; + + if (ctx->req == NULL) { + /* if the req has been freed already just return */ + return; + } + + ares = talloc_zero(ctx->req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + ctx->req->callback(ctx->req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->controls = talloc_steal(ares, ctrls); + ares->error = error; + + ctx->req->callback(ctx->req, ares); +} + +static void ildb_auto_done_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct ildb_context *ac; + + ac = talloc_get_type(private_data, struct ildb_context); + ildb_request_done(ac, NULL, LDB_SUCCESS); +} + +/* + convert a ldb_message structure to a list of ldap_mod structures + ready for ildap_add() or ildap_modify() +*/ +static struct ldap_mod **ildb_msg_to_mods(void *mem_ctx, int *num_mods, + const struct ldb_message *msg, + int use_flags) +{ + struct ldap_mod **mods; + unsigned int i; + int n = 0; + + /* allocate maximum number of elements needed */ + mods = talloc_array(mem_ctx, struct ldap_mod *, msg->num_elements+1); + if (!mods) { + errno = ENOMEM; + return NULL; + } + mods[0] = NULL; + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + + mods[n] = talloc(mods, struct ldap_mod); + if (!mods[n]) { + goto failed; + } + mods[n + 1] = NULL; + mods[n]->type = 0; + mods[n]->attrib = *el; + if (use_flags) { + switch (el->flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + mods[n]->type = LDAP_MODIFY_ADD; + break; + case LDB_FLAG_MOD_DELETE: + mods[n]->type = LDAP_MODIFY_DELETE; + break; + case LDB_FLAG_MOD_REPLACE: + mods[n]->type = LDAP_MODIFY_REPLACE; + break; + } + } + n++; + } + + *num_mods = n; + return mods; + +failed: + talloc_free(mods); + return NULL; +} + + +/* + map an ildap NTSTATUS to a ldb error code +*/ +static int ildb_map_error(struct ldb_module *module, NTSTATUS status) +{ + struct ildb_private *ildb; + struct ldb_context *ldb; + TALLOC_CTX *mem_ctx; + + ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); + ldb = ldb_module_get_ctx(module); + + if (NT_STATUS_IS_OK(status)) { + return LDB_SUCCESS; + } + + mem_ctx = talloc_new(ildb); + if (!mem_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ldb_set_errstring(ldb, + ldap_errstr(ildb->ldap, mem_ctx, status)); + talloc_free(mem_ctx); + if (NT_STATUS_IS_LDAP(status)) { + return NT_STATUS_LDAP_CODE(status); + } + return LDB_ERR_OPERATIONS_ERROR; +} + +static void ildb_request_timeout(struct tevent_context *ev, struct tevent_timer *te, + struct timeval t, void *private_data) +{ + struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context); + + if (ac->ireq->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(ac->ireq->conn->pending, ac->ireq); + } + + ildb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void ildb_callback(struct ldap_request *req) +{ + struct ldb_context *ldb; + struct ildb_context *ac; + NTSTATUS status; + struct ldap_SearchResEntry *search; + struct ldap_message *msg; + struct ldb_control **controls; + struct ldb_message *ldbmsg; + char *referral; + bool callback_failed; + bool request_done; + int ret; + int i; + + ac = talloc_get_type(req->async.private_data, struct ildb_context); + ldb = ldb_module_get_ctx(ac->module); + callback_failed = false; + request_done = false; + controls = NULL; + + /* check if we are already processing this request */ + if (ac->in_ildb_callback) { + return; + } + /* mark the request as being in process */ + ac->in_ildb_callback = true; + + if (!NT_STATUS_IS_OK(req->status)) { + ret = ildb_map_error(ac->module, req->status); + ildb_request_done(ac, NULL, ret); + return; + } + + if (req->num_replies < 1) { + ret = LDB_ERR_OPERATIONS_ERROR; + ildb_request_done(ac, NULL, ret); + return; + } + + switch (req->type) { + + case LDAP_TAG_ModifyRequest: + if (req->replies[0]->type != LDAP_TAG_ModifyResponse) { + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); + ret = ildb_map_error(ac->module, status); + request_done = true; + break; + + case LDAP_TAG_AddRequest: + if (req->replies[0]->type != LDAP_TAG_AddResponse) { + ret = LDB_ERR_PROTOCOL_ERROR; + return; + } + status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); + ret = ildb_map_error(ac->module, status); + request_done = true; + break; + + case LDAP_TAG_DelRequest: + if (req->replies[0]->type != LDAP_TAG_DelResponse) { + ret = LDB_ERR_PROTOCOL_ERROR; + return; + } + status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); + ret = ildb_map_error(ac->module, status); + request_done = true; + break; + + case LDAP_TAG_ModifyDNRequest: + if (req->replies[0]->type != LDAP_TAG_ModifyDNResponse) { + ret = LDB_ERR_PROTOCOL_ERROR; + return; + } + status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); + ret = ildb_map_error(ac->module, status); + request_done = true; + break; + + case LDAP_TAG_SearchRequest: + /* loop over all messages */ + for (i = 0; i < req->num_replies; i++) { + + msg = req->replies[i]; + switch (msg->type) { + + case LDAP_TAG_SearchResultDone: + + status = ldap_check_response(ac->ireq->conn, &msg->r.GeneralResult); + if (!NT_STATUS_IS_OK(status)) { + ret = ildb_map_error(ac->module, status); + break; + } + + controls = talloc_steal(ac, msg->controls); + if (msg->r.SearchResultDone.resultcode) { + if (msg->r.SearchResultDone.errormessage) { + ldb_set_errstring(ldb, msg->r.SearchResultDone.errormessage); + } + } + + ret = msg->r.SearchResultDone.resultcode; + request_done = true; + break; + + case LDAP_TAG_SearchResultEntry: + + ldbmsg = ldb_msg_new(ac); + if (!ldbmsg) { + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + + search = &(msg->r.SearchResultEntry); + + ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, search->dn); + if ( ! ldb_dn_validate(ldbmsg->dn)) { + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + ldbmsg->num_elements = search->num_attributes; + ldbmsg->elements = talloc_move(ldbmsg, &search->attributes); + + controls = talloc_steal(ac, msg->controls); + + ret = ldb_module_send_entry(ac->req, ldbmsg, controls); + if (ret != LDB_SUCCESS) { + callback_failed = true; + } + + break; + + case LDAP_TAG_SearchResultReference: + + referral = talloc_strdup(ac, msg->r.SearchResultReference.referral); + + ret = ldb_module_send_referral(ac->req, referral); + if (ret != LDB_SUCCESS) { + callback_failed = true; + } + + break; + + default: + /* TAG not handled, fail ! */ + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + break; + } + } + + talloc_free(req->replies); + req->replies = NULL; + req->num_replies = 0; + + break; + + default: + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + + /* if the callback failed the caller will have freed the + * request. Just return and don't try to use it */ + if ( ! callback_failed) { + request_done = true; + } + } + + /* mark the request as not being in progress */ + ac->in_ildb_callback = false; + + if (request_done) { + ildb_request_done(ac, controls, ret); + } + + return; +} + +static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg) +{ + struct ldb_context *ldb; + struct ldap_request *req; + + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb = ldb_module_get_ctx(ac->module); + + ldb_request_set_state(ac->req, LDB_ASYNC_PENDING); + + req = ldap_request_send(ac->ildb->ldap, msg); + if (req == NULL) { + ldb_set_errstring(ldb, "async send request failed"); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->ireq = talloc_reparent(ac->ildb->ldap, ac, req); + + if (!ac->ireq->conn) { + ldb_set_errstring(ldb, "connection to remote LDAP server dropped?"); + return LDB_ERR_OPERATIONS_ERROR; + } + + talloc_free(req->time_event); + req->time_event = NULL; + if (ac->req->timeout) { + req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, + timeval_current_ofs(ac->req->timeout, 0), + ildb_request_timeout, ac); + } + + req->async.fn = ildb_callback; + req->async.private_data = ac; + + return LDB_SUCCESS; +} + +/* + search for matching records using an asynchronous function + */ +static int ildb_search(struct ildb_context *ac) +{ + struct ldb_context *ldb; + struct ldb_request *req = ac->req; + struct ldap_message *msg; + int n; + + ldb = ldb_module_get_ctx(ac->module); + + if (!req->callback || !req->context) { + ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ldb_set_errstring(ldb, "Invalid expression parse tree"); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = new_ldap_message(req); + if (msg == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->type = LDAP_TAG_SearchRequest; + + if (req->op.search.base == NULL) { + msg->r.SearchRequest.basedn = talloc_strdup(msg, ""); + } else { + msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0); + } + if (msg->r.SearchRequest.basedn == NULL) { + ldb_set_errstring(ldb, "Unable to determine baseDN"); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.scope == LDB_SCOPE_DEFAULT) { + msg->r.SearchRequest.scope = LDB_SCOPE_SUBTREE; + } else { + msg->r.SearchRequest.scope = req->op.search.scope; + } + + msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + msg->r.SearchRequest.timelimit = 0; + msg->r.SearchRequest.sizelimit = 0; + msg->r.SearchRequest.attributesonly = 0; + msg->r.SearchRequest.tree = discard_const(req->op.search.tree); + + for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ; + msg->r.SearchRequest.num_attributes = n; + msg->r.SearchRequest.attributes = req->op.search.attrs; + msg->controls = req->controls; + + return ildb_request_send(ac, msg); +} + +/* + add a record +*/ +static int ildb_add(struct ildb_context *ac) +{ + struct ldb_request *req = ac->req; + struct ldap_message *msg; + struct ldap_mod **mods; + int i,n; + + msg = new_ldap_message(req); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->type = LDAP_TAG_AddRequest; + + msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0); + if (msg->r.AddRequest.dn == NULL) { + talloc_free(msg); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + mods = ildb_msg_to_mods(msg, &n, req->op.add.message, 0); + if (mods == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->r.AddRequest.num_attributes = n; + msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); + if (msg->r.AddRequest.attributes == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < n; i++) { + msg->r.AddRequest.attributes[i] = mods[i]->attrib; + } + msg->controls = req->controls; + + return ildb_request_send(ac, msg); +} + +/* + modify a record +*/ +static int ildb_modify(struct ildb_context *ac) +{ + struct ldb_request *req = ac->req; + struct ldap_message *msg; + struct ldap_mod **mods; + int i,n; + + msg = new_ldap_message(req); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->type = LDAP_TAG_ModifyRequest; + + msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0); + if (msg->r.ModifyRequest.dn == NULL) { + talloc_free(msg); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + mods = ildb_msg_to_mods(msg, &n, req->op.mod.message, 1); + if (mods == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->r.ModifyRequest.num_mods = n; + msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); + if (msg->r.ModifyRequest.mods == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < n; i++) { + msg->r.ModifyRequest.mods[i] = *mods[i]; + } + msg->controls = req->controls; + return ildb_request_send(ac, msg); +} + +/* + delete a record +*/ +static int ildb_delete(struct ildb_context *ac) +{ + struct ldb_request *req = ac->req; + struct ldap_message *msg; + + msg = new_ldap_message(req); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->type = LDAP_TAG_DelRequest; + + msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0); + if (msg->r.DelRequest.dn == NULL) { + talloc_free(msg); + return LDB_ERR_INVALID_DN_SYNTAX; + } + msg->controls = req->controls; + + return ildb_request_send(ac, msg); +} + +/* + rename a record +*/ +static int ildb_rename(struct ildb_context *ac) +{ + struct ldb_request *req = ac->req; + struct ldap_message *msg; + const char *rdn_name; + const struct ldb_val *rdn_val; + + msg = new_ldap_message(req); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->type = LDAP_TAG_ModifyDNRequest; + msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0); + if (msg->r.ModifyDNRequest.dn == NULL) { + talloc_free(msg); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); + rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); + + if ((rdn_name != NULL) && (rdn_val != NULL)) { + msg->r.ModifyDNRequest.newrdn = + talloc_asprintf(msg, "%s=%s", rdn_name, + rdn_val->length > 0 ? ldb_dn_escape_value(msg, *rdn_val) : ""); + } else { + msg->r.ModifyDNRequest.newrdn = talloc_strdup(msg, ""); + } + if (msg->r.ModifyDNRequest.newrdn == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->r.ModifyDNRequest.newsuperior = + ldb_dn_alloc_linearized(msg, ldb_dn_get_parent(msg, req->op.rename.newdn)); + if (msg->r.ModifyDNRequest.newsuperior == NULL) { + talloc_free(msg); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + msg->r.ModifyDNRequest.deleteolddn = true; + msg->controls = req->controls; + + return ildb_request_send(ac, msg); +} + +static int ildb_start_trans(struct ldb_module *module) +{ + /* TODO implement a local locking mechanism here */ + + return LDB_SUCCESS; +} + +static int ildb_end_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static int ildb_del_trans(struct ldb_module *module) +{ + /* TODO implement a local locking mechanism here */ + + return LDB_SUCCESS; +} + +static bool ildb_dn_is_special(struct ldb_request *req) +{ + struct ldb_dn *dn = NULL; + + switch (req->operation) { + case LDB_ADD: + dn = req->op.add.message->dn; + break; + case LDB_MODIFY: + dn = req->op.mod.message->dn; + break; + case LDB_DELETE: + dn = req->op.del.dn; + break; + case LDB_RENAME: + dn = req->op.rename.olddn; + break; + default: + break; + } + + if (dn && ldb_dn_is_special(dn)) { + return true; + } + return false; +} + +static int ildb_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ildb_private *ildb; + struct ildb_context *ac; + struct tevent_timer *te; + int ret; + + ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); + ldb = ldb_module_get_ctx(module); + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ac = talloc_zero(req, struct ildb_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->ildb = ildb; + + if (ildb_dn_is_special(req)) { + + te = tevent_add_timer(ac->ildb->event_ctx, + ac, timeval_zero(), + ildb_auto_done_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; + } + + switch (ac->req->operation) { + case LDB_SEARCH: + ret = ildb_search(ac); + break; + case LDB_ADD: + ret = ildb_add(ac); + break; + case LDB_MODIFY: + ret = ildb_modify(ac); + break; + case LDB_DELETE: + ret = ildb_delete(ac); + break; + case LDB_RENAME: + ret = ildb_rename(ac); + break; + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + return ret; +} + +static const struct ldb_module_ops ildb_ops = { + .name = "ldap", + .search = ildb_handle_request, + .add = ildb_handle_request, + .modify = ildb_handle_request, + .del = ildb_handle_request, + .rename = ildb_handle_request, +/* .request = ildb_handle_request, */ + .start_transaction = ildb_start_trans, + .end_transaction = ildb_end_trans, + .del_transaction = ildb_del_trans, +}; + +/* + connect to the database +*/ +static int ildb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct ildb_private *ildb; + NTSTATUS status; + struct cli_credentials *creds; + struct loadparm_context *lp_ctx; + + module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + ildb = talloc(module, struct ildb_private); + if (!ildb) { + ldb_oom(ldb); + goto failed; + } + ldb_module_set_private(module, ildb); + + ildb->event_ctx = ldb_get_event_context(ldb); + + lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), + struct loadparm_context); + + ildb->ldap = ldap4_new_connection(ildb, lp_ctx, + ildb->event_ctx); + if (!ildb->ldap) { + ldb_oom(ldb); + goto failed; + } + + if (flags & LDB_FLG_RECONNECT) { + ldap_set_reconn_params(ildb->ldap, 10); + } + + status = ldap_connect(ildb->ldap, url); + if (!NT_STATUS_IS_OK(status)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s", + url, ldap_errstr(ildb->ldap, module, status)); + goto failed; + } + + /* caller can optionally setup credentials using the opaque token 'credentials' */ + creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials); + if (creds == NULL) { + struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info); + if (session_info) { + creds = session_info->credentials; + } + } + + if (creds != NULL && cli_credentials_authentication_requested(creds)) { + const char *bind_dn = cli_credentials_get_bind_dn(creds); + if (bind_dn) { + const char *password = cli_credentials_get_password(creds); + status = ldap_bind_simple(ildb->ldap, bind_dn, password); + if (!NT_STATUS_IS_OK(status)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", + ldap_errstr(ildb->ldap, module, status)); + goto failed; + } + } else { + status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", + ldap_errstr(ildb->ldap, module, status)); + goto failed; + } + } + } + + *_module = module; + return LDB_SUCCESS; + +failed: + talloc_free(module); + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + initialise the module + */ +_PUBLIC_ int ldb_ildap_init(const char *ldb_version) +{ + int ret, i; + const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; + for (i=0; names[i]; i++) { + ret = ldb_register_backend(names[i], ildb_connect, true); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} diff --git a/lib/ldb-samba/ldb_wrap.c b/lib/ldb-samba/ldb_wrap.c new file mode 100644 index 00000000000..66213bf2881 --- /dev/null +++ b/lib/ldb-samba/ldb_wrap.c @@ -0,0 +1,365 @@ +/* + Unix SMB/CIFS implementation. + + LDB wrap functions + + Copyright (C) Andrew Tridgell 2004-2009 + + 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 . +*/ + +/* + the stupidity of the unix fcntl locking design forces us to never + allow a database file to be opened twice in the same process. These + wrappers provide convenient access to a tdb or ldb, taking advantage + of talloc destructors to ensure that only a single open is done +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include +#include +#include "lib/ldb-samba/ldif_handlers.h" +#include "ldb_wrap.h" +#include "dsdb/samdb/samdb.h" +#include "param/param.h" +#include "../lib/util/dlinklist.h" +#include "../lib/tdb_compat/tdb_compat.h" + +/* + this is used to catch debug messages from ldb +*/ +static void ldb_wrap_debug(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void ldb_wrap_debug(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + int samba_level = -1; + char *s = NULL; + switch (level) { + case LDB_DEBUG_FATAL: + samba_level = 0; + break; + case LDB_DEBUG_ERROR: + samba_level = 1; + break; + case LDB_DEBUG_WARNING: + samba_level = 2; + break; + case LDB_DEBUG_TRACE: + samba_level = 5; + break; + + }; + vasprintf(&s, fmt, ap); + if (!s) return; + DEBUG(samba_level, ("ldb: %s\n", s)); + free(s); +} + + +/* + connecting to a ldb can be a relatively expensive operation because + of the schema and partition loads. We keep a list of open ldb + contexts here, and try to re-use when possible. + + This means callers of ldb_wrap_connect() must use talloc_unlink() or + the free of a parent to destroy the context + */ +static struct ldb_wrap { + struct ldb_wrap *next, *prev; + struct ldb_wrap_context { + /* the context is what we use to tell if two ldb + * connections are exactly equivalent + */ + const char *url; + struct tevent_context *ev; + struct loadparm_context *lp_ctx; + struct auth_session_info *session_info; + struct cli_credentials *credentials; + unsigned int flags; + } context; + struct ldb_context *ldb; +} *ldb_wrap_list; + +/* + free a ldb_wrap structure + */ +static int ldb_wrap_destructor(struct ldb_wrap *w) +{ + DLIST_REMOVE(ldb_wrap_list, w); + return 0; +} + +/* + * The casefolder for s4's LDB databases - Unicode-safe + */ +char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) +{ + return strupper_talloc_n(mem_ctx, s, n); +} + + + struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_init(mem_ctx, ev); + if (ldb == NULL) { + return NULL; + } + + ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); + + ldb_set_debug(ldb, ldb_wrap_debug, NULL); + + ldb_set_utf8_fns(ldb, NULL, wrap_casefold); + + if (session_info) { + if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { + talloc_free(ldb); + return NULL; + } + } + + if (credentials) { + if (ldb_set_opaque(ldb, "credentials", credentials)) { + talloc_free(ldb); + return NULL; + } + } + + if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) { + talloc_free(ldb); + return NULL; + } + + /* This must be done before we load the schema, as these + * handlers for objectSid and objectGUID etc must take + * precedence over the 'binary attribute' declaration in the + * schema */ + ret = ldb_register_samba_handlers(ldb); + if (ret != LDB_SUCCESS) { + talloc_free(ldb); + return NULL; + } + + /* we usually want Samba databases to be private. If we later + find we need one public, we will need to add a parameter to + ldb_wrap_connect() */ + ldb_set_create_perms(ldb, 0600); + + return ldb; +} + + struct ldb_context *ldb_wrap_find(const char *url, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags) +{ + struct ldb_wrap *w; + /* see if we can re-use an existing ldb */ + for (w=ldb_wrap_list; w; w=w->next) { + if (w->context.ev == ev && + w->context.lp_ctx == lp_ctx && + w->context.session_info == session_info && + w->context.credentials == credentials && + w->context.flags == flags && + (w->context.url == url || strcmp(w->context.url, url) == 0)) + return w->ldb; + } + + return NULL; +} + +int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, + const char *url, unsigned int flags) +{ + int ret; + char *real_url = NULL; + + /* allow admins to force non-sync ldb for all databases */ + if (lpcfg_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) { + flags |= LDB_FLG_NOSYNC; + } + + if (DEBUGLVL(10)) { + flags |= LDB_FLG_ENABLE_TRACING; + } + + real_url = lpcfg_private_path(ldb, lp_ctx, url); + if (real_url == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_connect(ldb, real_url, flags, NULL); + + if (ret != LDB_SUCCESS) { + return ret; + } + + /* setup for leak detection */ + ldb_set_opaque(ldb, "wrap_url", real_url); + + return LDB_SUCCESS; +} + + bool ldb_wrap_add(const char *url, struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags, + struct ldb_context *ldb) +{ + struct ldb_wrap *w; + struct ldb_wrap_context c; + + /* add to the list of open ldb contexts */ + w = talloc(ldb, struct ldb_wrap); + if (w == NULL) { + return false; + } + + c.url = url; + c.ev = ev; + c.lp_ctx = lp_ctx; + c.session_info = session_info; + c.credentials = credentials; + c.flags = flags; + + w->context = c; + w->context.url = talloc_strdup(w, url); + if (w->context.url == NULL) { + return false; + } + + if (session_info) { + /* take a reference to the session_info, as it is + * possible for the ldb to live longer than the + * session_info. This happens when a DRS DsBind call + * reuses a handle, but the original connection is + * shutdown. The token for the new connection is still + * valid, so we need the session_info to remain valid for + * ldb modules to use + */ + if (talloc_reference(w, session_info) == NULL) { + return false; + } + } + + w->ldb = ldb; + + DLIST_ADD(ldb_wrap_list, w); + + talloc_set_destructor(w, ldb_wrap_destructor); + + return true; +} + + +/* + wrapped connection to a ldb database + to close just talloc_free() the returned ldb_context + + TODO: We need an error_string parameter + */ + struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + const char *url, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_wrap_find(url, ev, lp_ctx, session_info, credentials, flags); + if (ldb != NULL) + return talloc_reference(mem_ctx, ldb); + + ldb = samba_ldb_init(mem_ctx, ev, lp_ctx, session_info, credentials); + + if (ldb == NULL) + return NULL; + + ret = samba_ldb_connect(ldb, lp_ctx, url, flags); + if (ret != LDB_SUCCESS) { + talloc_free(ldb); + return NULL; + } + + if (!ldb_wrap_add(url, ev, lp_ctx, session_info, credentials, flags, ldb)) { + talloc_free(ldb); + return NULL; + } + + DEBUG(3,("ldb_wrap open of %s\n", url)); + + return ldb; +} + +/* + when we fork() we need to make sure that any open ldb contexts have + any open transactions cancelled + */ + void ldb_wrap_fork_hook(void) +{ + struct ldb_wrap *w; + + for (w=ldb_wrap_list; w; w=w->next) { + if (ldb_transaction_cancel_noerr(w->ldb) != LDB_SUCCESS) { + smb_panic("Failed to cancel child transactions\n"); + } + } + + if (tdb_reopen_all(1) == -1) { + smb_panic("tdb_reopen_all failed\n"); + } +} + + char *ldb_relative_path(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *name) +{ + const char *base_url = + (const char *)ldb_get_opaque(ldb, "ldb_url"); + char *path, *p, *full_name; + if (name == NULL) { + return NULL; + } + if (strncmp("tdb://", base_url, 6) == 0) { + base_url = base_url+6; + } + path = talloc_strdup(mem_ctx, base_url); + if (path == NULL) { + return NULL; + } + if ( (p = strrchr(path, '/')) != NULL) { + p[0] = '\0'; + full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); + } else { + full_name = talloc_asprintf(mem_ctx, "./%s", name); + } + talloc_free(path); + return full_name; +} diff --git a/lib/ldb-samba/ldb_wrap.h b/lib/ldb-samba/ldb_wrap.h new file mode 100644 index 00000000000..aa7ccb3a234 --- /dev/null +++ b/lib/ldb-samba/ldb_wrap.h @@ -0,0 +1,70 @@ +/* + Unix SMB/CIFS implementation. + + database wrap headers + + Copyright (C) Andrew Tridgell 2004 + + 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 . +*/ + +#ifndef _LDB_WRAP_H_ +#define _LDB_WRAP_H_ + +#include + +struct auth_session_info; +struct ldb_message; +struct ldb_dn; +struct cli_credentials; +struct loadparm_context; +struct tevent_context; + +char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n); + +struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + const char *url, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags); + +void ldb_wrap_fork_hook(void); + +struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); +struct ldb_context *ldb_wrap_find(const char *url, + struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags); +bool ldb_wrap_add(const char *url, struct tevent_context *ev, + struct loadparm_context *lp_ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + unsigned int flags, + struct ldb_context *ldb); +char *ldb_relative_path(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *name); + +int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, + const char *url, unsigned int flags); + +#endif /* _LDB_WRAP_H_ */ diff --git a/lib/ldb-samba/ldif_handlers.c b/lib/ldb-samba/ldif_handlers.c new file mode 100644 index 00000000000..af3c4b46e17 --- /dev/null +++ b/lib/ldb-samba/ldif_handlers.c @@ -0,0 +1,1416 @@ +/* + ldb database library - ldif handlers for Samba + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Bartlett 2006-2009 + Copyright (C) Matthias Dieter Wallnöfer 2009 + ** 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 . +*/ + +#include "includes.h" +#include +#include +#include "ldb_handlers.h" +#include "dsdb/samdb/samdb.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "librpc/gen_ndr/ndr_dnsp.h" +#include "librpc/ndr/libndr.h" +#include "libcli/security/security.h" +#include "param/param.h" +#include "../lib/util/asn1.h" + +/* + use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob + + If mask_errors is true, then function succeeds but out data + is set to "" message + + \return 0 on success; -1 on error +*/ +static int ldif_write_NDR(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out, + size_t struct_size, + ndr_pull_flags_fn_t pull_fn, + ndr_print_fn_t print_fn, + bool mask_errors) +{ + uint8_t *p; + enum ndr_err_code err; + if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) { + return ldb_handler_copy(ldb, mem_ctx, in, out); + } + p = talloc_size(mem_ctx, struct_size); + err = ndr_pull_struct_blob(in, mem_ctx, + p, pull_fn); + if (err != NDR_ERR_SUCCESS) { + /* fail in not in mask_error mode */ + if (!mask_errors) { + return -1; + } + talloc_free(p); + out->data = (uint8_t *)talloc_strdup(mem_ctx, ""); + out->length = strlen((const char *)out->data); + return 0; + } + out->data = (uint8_t *)ndr_print_struct_string(mem_ctx, print_fn, "NDR", p); + talloc_free(p); + if (out->data == NULL) { + return ldb_handler_copy(ldb, mem_ctx, in, out); + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + convert a ldif formatted objectSid to a NDR formatted blob +*/ +static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + enum ndr_err_code ndr_err; + struct dom_sid *sid; + sid = dom_sid_parse_length(mem_ctx, in); + if (sid == NULL) { + return -1; + } + ndr_err = ndr_push_struct_blob(out, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + talloc_free(sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; +} + +/* + convert a NDR formatted blob to a ldif formatted objectSid +*/ +int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct dom_sid *sid; + enum ndr_err_code ndr_err; + + sid = talloc(mem_ctx, struct dom_sid); + if (sid == NULL) { + return -1; + } + ndr_err = ndr_pull_struct_blob_all(in, sid, sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(sid); + return -1; + } + *out = data_blob_string_const(dom_sid_string(mem_ctx, sid)); + talloc_free(sid); + if (out->data == NULL) { + return -1; + } + return 0; +} + +bool ldif_comparision_objectSid_isString(const struct ldb_val *v) +{ + if (v->length < 3) { + return false; + } + + if (strncmp("S-", (const char *)v->data, 2) != 0) return false; + + return true; +} + +/* + compare two objectSids +*/ +static int ldif_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (ldif_comparision_objectSid_isString(v1) && ldif_comparision_objectSid_isString(v2)) { + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } else if (ldif_comparision_objectSid_isString(v1) + && !ldif_comparision_objectSid_isString(v2)) { + struct ldb_val v; + int ret; + if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) { + /* Perhaps not a string after all */ + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } + ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); + talloc_free(v.data); + return ret; + } else if (!ldif_comparision_objectSid_isString(v1) + && ldif_comparision_objectSid_isString(v2)) { + struct ldb_val v; + int ret; + if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) { + /* Perhaps not a string after all */ + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } + ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); + talloc_free(v.data); + return ret; + } + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); +} + +/* + canonicalise a objectSid +*/ +static int ldif_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (ldif_comparision_objectSid_isString(in)) { + if (ldif_read_objectSid(ldb, mem_ctx, in, out) != 0) { + /* Perhaps not a string after all */ + return ldb_handler_copy(ldb, mem_ctx, in, out); + } + return 0; + } + return ldb_handler_copy(ldb, mem_ctx, in, out); +} + +static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct dom_sid sid; + enum ndr_err_code ndr_err; + if (ldif_comparision_objectSid_isString(in)) { + if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) { + return 0; + } + } + + /* Perhaps not a string after all */ + *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); + + if (!out->data) { + return -1; + } + + (*out).length = strhex_to_str((char *)out->data, out->length, + (const char *)in->data, in->length); + + /* Check it looks like a SID */ + ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, &sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; +} + +/* + convert a ldif formatted objectGUID to a NDR formatted blob +*/ +static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct GUID guid; + NTSTATUS status; + + status = GUID_from_data_blob(in, &guid); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + status = GUID_to_ndr_blob(&guid, mem_ctx, out); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + return 0; +} + +/* + convert a NDR formatted blob to a ldif formatted objectGUID +*/ +static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct GUID guid; + NTSTATUS status; + + status = GUID_from_ndr_blob(in, &guid); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + out->data = (uint8_t *)GUID_string(mem_ctx, &guid); + if (out->data == NULL) { + return -1; + } + out->length = strlen((const char *)out->data); + return 0; +} + +static bool ldif_comparision_objectGUID_isString(const struct ldb_val *v) +{ + if (v->length != 36 && v->length != 38) return false; + + /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */ + return true; +} + +static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct GUID guid; + NTSTATUS status; + + if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) { + return 0; + } + + /* Try as 'hex' form */ + if (in->length != 32) { + return -1; + } + + *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); + + if (!out->data) { + return -1; + } + + (*out).length = strhex_to_str((char *)out->data, out->length, + (const char *)in->data, in->length); + + /* Check it looks like a GUID */ + status = GUID_from_ndr_blob(out, &guid); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(out); + return -1; + } + return 0; +} + +/* + compare two objectGUIDs +*/ +static int ldif_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (ldif_comparision_objectGUID_isString(v1) && ldif_comparision_objectGUID_isString(v2)) { + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } else if (ldif_comparision_objectGUID_isString(v1) + && !ldif_comparision_objectGUID_isString(v2)) { + struct ldb_val v; + int ret; + if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) { + /* Perhaps it wasn't a valid string after all */ + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } + ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); + talloc_free(v.data); + return ret; + } else if (!ldif_comparision_objectGUID_isString(v1) + && ldif_comparision_objectGUID_isString(v2)) { + struct ldb_val v; + int ret; + if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) { + /* Perhaps it wasn't a valid string after all */ + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); + } + ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); + talloc_free(v.data); + return ret; + } + return ldb_comparison_binary(ldb, mem_ctx, v1, v2); +} + +/* + canonicalise a objectGUID +*/ +static int ldif_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (ldif_comparision_objectGUID_isString(in)) { + if (ldif_read_objectGUID(ldb, mem_ctx, in, out) != 0) { + /* Perhaps it wasn't a valid string after all */ + return ldb_handler_copy(ldb, mem_ctx, in, out); + } + return 0; + } + return ldb_handler_copy(ldb, mem_ctx, in, out); +} + + +/* + convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob +*/ +static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct security_descriptor *sd; + enum ndr_err_code ndr_err; + + sd = talloc(mem_ctx, struct security_descriptor); + if (sd == NULL) { + return -1; + } + + ndr_err = ndr_pull_struct_blob(in, sd, sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + /* If this does not parse, then it is probably SDDL, and we should try it that way */ + + const struct dom_sid *sid = samdb_domain_sid(ldb); + talloc_free(sd); + sd = sddl_decode(mem_ctx, (const char *)in->data, sid); + if (sd == NULL) { + return -1; + } + } + + ndr_err = ndr_push_struct_blob(out, mem_ctx, sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + talloc_free(sd); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + + return 0; +} + +/* + convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format) +*/ +static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct security_descriptor *sd; + enum ndr_err_code ndr_err; + + if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct security_descriptor), + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor, + (ndr_print_fn_t)ndr_print_security_descriptor, + true); + + } + + sd = talloc(mem_ctx, struct security_descriptor); + if (sd == NULL) { + return -1; + } + /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ + ndr_err = ndr_pull_struct_blob(in, sd, sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(sd); + return -1; + } + out->data = (uint8_t *)sddl_encode(mem_ctx, sd, samdb_domain_sid_cache_only(ldb)); + talloc_free(sd); + if (out->data == NULL) { + return -1; + } + out->length = strlen((const char *)out->data); + return 0; +} + +/* + canonicalise an objectCategory. We use the short form as the canonical form: + cn=Person,cn=Schema,cn=Configuration, becomes 'person' +*/ + +static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct ldb_dn *dn1 = NULL; + const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL); + const struct dsdb_class *sclass; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (!schema) { + talloc_free(tmp_ctx); + *out = data_blob_talloc(mem_ctx, in->data, in->length); + if (in->data && !out->data) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; + } + dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in); + if ( ! ldb_dn_validate(dn1)) { + const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length); + sclass = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName); + if (sclass) { + struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, + sclass->defaultObjectCategory); + *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn)); + talloc_free(tmp_ctx); + + if (!out->data) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; + } else { + *out = data_blob_talloc(mem_ctx, in->data, in->length); + talloc_free(tmp_ctx); + + if (in->data && !out->data) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; + } + } + *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1)); + talloc_free(tmp_ctx); + + if (!out->data) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; +} + +static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, + const struct ldb_val *v2) +{ + return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_objectCategory, + v1, v2); +} + +/* + convert a NDR formatted blob to a ldif formatted schemaInfo +*/ +static int ldif_write_schemaInfo(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct repsFromToBlob), + (ndr_pull_flags_fn_t)ndr_pull_schemaInfoBlob, + (ndr_print_fn_t)ndr_print_schemaInfoBlob, + true); +} + +/* + convert a ldif formatted prefixMap to a NDR formatted blob +*/ +static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; + char *string, *line, *p, *oid; + DATA_BLOB oid_blob; + + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + if (tmp_ctx == NULL) { + return -1; + } + + blob = talloc_zero(tmp_ctx, struct prefixMapBlob); + if (blob == NULL) { + talloc_free(tmp_ctx); + return -1; + } + + /* use the switch value to detect if this is in the binary + * format + */ + if (in->length >= 4 && IVAL(in->data, 0) == PREFIX_MAP_VERSION_DSDB) { + ndr_err = ndr_pull_struct_blob(in, tmp_ctx, blob, + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ndr_err = ndr_push_struct_blob(out, mem_ctx, + blob, + (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); + talloc_free(tmp_ctx); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; + } + } + + /* If this does not parse, then it is probably the text version, and we should try it that way */ + blob->version = PREFIX_MAP_VERSION_DSDB; + + string = talloc_strndup(mem_ctx, (const char *)in->data, in->length); + if (string == NULL) { + talloc_free(blob); + return -1; + } + + line = string; + while (line && line[0]) { + p=strchr(line, ';'); + if (p) { + p[0] = '\0'; + } else { + p=strchr(line, '\n'); + if (p) { + p[0] = '\0'; + } + } + /* allow a trailing separator */ + if (line == p) { + break; + } + + blob->ctr.dsdb.mappings = talloc_realloc(blob, + blob->ctr.dsdb.mappings, + struct drsuapi_DsReplicaOIDMapping, + blob->ctr.dsdb.num_mappings+1); + if (!blob->ctr.dsdb.mappings) { + talloc_free(tmp_ctx); + return -1; + } + + blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10); + + if (oid[0] != ':') { + talloc_free(tmp_ctx); + return -1; + } + + /* we know there must be at least ":" */ + oid++; + + if (!ber_write_partial_OID_String(blob->ctr.dsdb.mappings, &oid_blob, oid)) { + talloc_free(tmp_ctx); + return -1; + } + blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.length = oid_blob.length; + blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.binary_oid = oid_blob.data; + + blob->ctr.dsdb.num_mappings++; + + /* Now look past the terminator we added above */ + if (p) { + line = p + 1; + } else { + line = NULL; + } + } + + ndr_err = ndr_push_struct_blob(out, mem_ctx, + blob, + (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); + talloc_free(tmp_ctx); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; +} + +/* + convert a NDR formatted blob to a ldif formatted prefixMap +*/ +static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; + char *string; + uint32_t i; + + if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { + int err; + /* try to decode the blob as S4 prefixMap */ + err = ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct prefixMapBlob), + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob, + (ndr_print_fn_t)ndr_print_prefixMapBlob, + false); + if (0 == err) { + return err; + } + /* try parsing it as Windows PrefixMap value */ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct drsuapi_MSPrefixMap_Ctr), + (ndr_pull_flags_fn_t)ndr_pull_drsuapi_MSPrefixMap_Ctr, + (ndr_print_fn_t)ndr_print_drsuapi_MSPrefixMap_Ctr, + true); + } + + blob = talloc(mem_ctx, struct prefixMapBlob); + if (blob == NULL) { + return -1; + } + ndr_err = ndr_pull_struct_blob_all(in, blob, + blob, + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto failed; + } + if (blob->version != PREFIX_MAP_VERSION_DSDB) { + goto failed; + } + string = talloc_strdup(mem_ctx, ""); + if (string == NULL) { + goto failed; + } + + for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { + DATA_BLOB oid_blob; + char *partial_oid = NULL; + + if (i > 0) { + string = talloc_asprintf_append(string, ";"); + } + + oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid, + blob->ctr.dsdb.mappings[i].oid.length); + if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) { + DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", + blob->ctr.dsdb.mappings[i].id_prefix)); + goto failed; + } + string = talloc_asprintf_append(string, "%u:%s", + blob->ctr.dsdb.mappings[i].id_prefix, + partial_oid); + talloc_free(discard_const(partial_oid)); + if (string == NULL) { + goto failed; + } + } + + talloc_free(blob); + *out = data_blob_string_const(string); + return 0; + +failed: + talloc_free(blob); + return -1; +} + +static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v) +{ + if (v->length < 4) { + return true; + } + + if (IVAL(v->data, 0) == PREFIX_MAP_VERSION_DSDB) { + return false; + } + + return true; +} + +/* + canonicalise a prefixMap +*/ +static int ldif_canonicalise_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (ldif_comparision_prefixMap_isString(in)) { + return ldif_read_prefixMap(ldb, mem_ctx, in, out); + } + return ldb_handler_copy(ldb, mem_ctx, in, out); +} + +static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, + const struct ldb_val *v2) +{ + return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_prefixMap, + v1, v2); +} + +/* length limited conversion of a ldb_val to a int32_t */ +static int val_to_int32(const struct ldb_val *in, int32_t *v) +{ + char *end; + char buf[64]; + + /* make sure we don't read past the end of the data */ + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (char *)in->data, in->length); + buf[in->length] = 0; + + /* We've to use "strtoll" here to have the intended overflows. + * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ + *v = (int32_t) strtoll(buf, &end, 0); + if (*end != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + return LDB_SUCCESS; +} + +/* length limited conversion of a ldb_val to a int64_t */ +static int val_to_int64(const struct ldb_val *in, int64_t *v) +{ + char *end; + char buf[64]; + + /* make sure we don't read past the end of the data */ + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (char *)in->data, in->length); + buf[in->length] = 0; + + *v = (int64_t) strtoll(buf, &end, 0); + if (*end != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + return LDB_SUCCESS; +} + +/* Canonicalisation of two 32-bit integers */ +static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + int32_t i; + int ret; + + ret = val_to_int32(in, &i); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* Comparison of two 32-bit integers */ +static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + int32_t i1=0, i2=0; + val_to_int32(v1, &i1); + val_to_int32(v2, &i2); + if (i1 == i2) return 0; + return i1 > i2? 1 : -1; +} + +/* Canonicalisation of two 64-bit integers */ +static int ldif_canonicalise_int64(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + int64_t i; + int ret; + + ret = val_to_int64(in, &i); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* Comparison of two 64-bit integers */ +static int ldif_comparison_int64(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + int64_t i1=0, i2=0; + val_to_int64(v1, &i1); + val_to_int64(v2, &i2); + if (i1 == i2) return 0; + return i1 > i2? 1 : -1; +} + +/* + convert a NDR formatted blob to a ldif formatted repsFromTo +*/ +static int ldif_write_repsFromTo(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct repsFromToBlob), + (ndr_pull_flags_fn_t)ndr_pull_repsFromToBlob, + (ndr_print_fn_t)ndr_print_repsFromToBlob, + true); +} + +/* + convert a NDR formatted blob to a ldif formatted replPropertyMetaData +*/ +static int ldif_write_replPropertyMetaData(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct replPropertyMetaDataBlob), + (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob, + (ndr_print_fn_t)ndr_print_replPropertyMetaDataBlob, + true); +} + +/* + convert a NDR formatted blob to a ldif formatted replUpToDateVector +*/ +static int ldif_write_replUpToDateVector(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct replUpToDateVectorBlob), + (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob, + (ndr_print_fn_t)ndr_print_replUpToDateVectorBlob, + true); +} + + +/* + convert a NDR formatted blob to a ldif formatted dnsRecord +*/ +static int ldif_write_dnsRecord(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct dnsp_DnssrvRpcRecord), + (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord, + (ndr_print_fn_t)ndr_print_dnsp_DnssrvRpcRecord, + true); +} + +/* + convert a NDR formatted blob of a supplementalCredentials into text +*/ +static int ldif_write_supplementalCredentialsBlob(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + return ldif_write_NDR(ldb, mem_ctx, in, out, + sizeof(struct supplementalCredentialsBlob), + (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob, + (ndr_print_fn_t)ndr_print_supplementalCredentialsBlob, + true); +} + + +static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + *out = data_blob_string_const(data_blob_hex_string_lower(mem_ctx, in)); + if (!out->data) { + return -1; + } + return 0; +} + +/* + compare two dns +*/ +static int samba_ldb_dn_link_comparison(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + struct ldb_dn *dn1 = NULL, *dn2 = NULL; + int ret; + + if (dsdb_dn_is_deleted_val(v1)) { + /* If the DN is deleted, then we can't search for it */ + return -1; + } + + if (dsdb_dn_is_deleted_val(v2)) { + /* If the DN is deleted, then we can't search for it */ + return -1; + } + + dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); + if ( ! ldb_dn_validate(dn1)) return -1; + + dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); + if ( ! ldb_dn_validate(dn2)) { + talloc_free(dn1); + return -1; + } + + ret = ldb_dn_compare(dn1, dn2); + + talloc_free(dn1); + talloc_free(dn2); + return ret; +} + +static int samba_ldb_dn_link_canonicalise(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct ldb_dn *dn; + int ret = -1; + + out->length = 0; + out->data = NULL; + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_INVALID_DN_SYNTAX; + } + + /* By including the RMD_FLAGS of a deleted DN, we ensure it + * does not casually match a not deleted DN */ + if (dsdb_dn_is_deleted_val(in)) { + out->data = (uint8_t *)talloc_asprintf(mem_ctx, + "%s", + dsdb_dn_val_rmd_flags(in), + ldb_dn_get_casefold(dn)); + } else { + out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); + } + + if (out->data == NULL) { + goto done; + } + out->length = strlen((char *)out->data); + + ret = 0; + +done: + talloc_free(dn); + + return ret; +} + + +/* + write a 64 bit 2-part range +*/ +static int ldif_write_range64(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + int64_t v; + int ret; + ret = val_to_int64(in, &v); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lu-%lu", + (unsigned long)(v&0xFFFFFFFF), + (unsigned long)(v>>32)); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return LDB_SUCCESS; +} + +/* + read a 64 bit 2-part range +*/ +static int ldif_read_range64(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + unsigned long high, low; + char buf[64]; + + if (memchr(in->data, '-', in->length) == NULL) { + return ldb_handler_copy(ldb, mem_ctx, in, out); + } + + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (const char *)in->data, in->length); + buf[in->length] = 0; + + if (sscanf(buf, "%lu-%lu", &low, &high) != 2) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%llu", + (unsigned long long)(((uint64_t)high)<<32) | (low)); + + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return LDB_SUCCESS; +} + +/* + when this operator_fn is set for a syntax, the backend calls is in + preference to the comparison function. We are told the exact + comparison operation that is needed, and we can return errors + */ +static int samba_syntax_operator_fn(struct ldb_context *ldb, enum ldb_parse_op operation, + const struct ldb_schema_attribute *a, + const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) +{ + switch (operation) { + case LDB_OP_AND: + case LDB_OP_OR: + case LDB_OP_NOT: + case LDB_OP_SUBSTRING: + case LDB_OP_APPROX: + case LDB_OP_EXTENDED: + /* handled in the backends */ + return LDB_ERR_INAPPROPRIATE_MATCHING; + + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_EQUALITY: + { + TALLOC_CTX *tmp_ctx = talloc_new(ldb); + int ret; + if (tmp_ctx == NULL) { + return ldb_oom(ldb); + } + ret = a->syntax->comparison_fn(ldb, tmp_ctx, v1, v2); + talloc_free(tmp_ctx); + if (operation == LDB_OP_GREATER) { + *matched = (ret > 0); + } else if (operation == LDB_OP_LESS) { + *matched = (ret < 0); + } else { + *matched = (ret == 0); + } + return LDB_SUCCESS; + } + + case LDB_OP_PRESENT: + *matched = true; + return LDB_SUCCESS; + } + + /* we shouldn't get here */ + return LDB_ERR_INAPPROPRIATE_MATCHING; +} + +/* + special operation for DNs, to take account of the RMD_FLAGS deleted bit + */ +static int samba_syntax_operator_dn(struct ldb_context *ldb, enum ldb_parse_op operation, + const struct ldb_schema_attribute *a, + const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) +{ + if (operation == LDB_OP_PRESENT && dsdb_dn_is_deleted_val(v1)) { + /* If the DN is deleted, then we can't search for it */ + *matched = false; + return LDB_SUCCESS; + } + return samba_syntax_operator_fn(ldb, operation, a, v1, v2, matched); +} + + +static const struct ldb_schema_syntax samba_syntaxes[] = { + { + .name = LDB_SYNTAX_SAMBA_SID, + .ldif_read_fn = ldif_read_objectSid, + .ldif_write_fn = ldif_write_objectSid, + .canonicalise_fn = ldif_canonicalise_objectSid, + .comparison_fn = ldif_comparison_objectSid, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR, + .ldif_read_fn = ldif_read_ntSecurityDescriptor, + .ldif_write_fn = ldif_write_ntSecurityDescriptor, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_GUID, + .ldif_read_fn = ldif_read_objectGUID, + .ldif_write_fn = ldif_write_objectGUID, + .canonicalise_fn = ldif_canonicalise_objectGUID, + .comparison_fn = ldif_comparison_objectGUID, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldif_canonicalise_objectCategory, + .comparison_fn = ldif_comparison_objectCategory, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_SCHEMAINFO, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_schemaInfo, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, + .ldif_read_fn = ldif_read_prefixMap, + .ldif_write_fn = ldif_write_prefixMap, + .canonicalise_fn = ldif_canonicalise_prefixMap, + .comparison_fn = ldif_comparison_prefixMap, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_INT32, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldif_canonicalise_int32, + .comparison_fn = ldif_comparison_int32, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_REPSFROMTO, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_repsFromTo, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_replPropertyMetaData, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_replUpToDateVector, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = DSDB_SYNTAX_BINARY_DN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = dsdb_dn_binary_canonicalise, + .comparison_fn = dsdb_dn_binary_comparison, + .operator_fn = samba_syntax_operator_fn + },{ + .name = DSDB_SYNTAX_STRING_DN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = dsdb_dn_string_canonicalise, + .comparison_fn = dsdb_dn_string_comparison, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_DN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = samba_ldb_dn_link_canonicalise, + .comparison_fn = samba_ldb_dn_link_comparison, + .operator_fn = samba_syntax_operator_dn + },{ + .name = LDB_SYNTAX_SAMBA_RANGE64, + .ldif_read_fn = ldif_read_range64, + .ldif_write_fn = ldif_write_range64, + .canonicalise_fn = ldif_canonicalise_int64, + .comparison_fn = ldif_comparison_int64, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_DNSRECORD, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_dnsRecord, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + },{ + .name = LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldif_write_supplementalCredentialsBlob, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary, + .operator_fn = samba_syntax_operator_fn + } +}; + +static const struct ldb_dn_extended_syntax samba_dn_syntax[] = { + { + .name = "SID", + .read_fn = extended_dn_read_SID, + .write_clear_fn = ldif_write_objectSid, + .write_hex_fn = extended_dn_write_hex + },{ + .name = "GUID", + .read_fn = extended_dn_read_GUID, + .write_clear_fn = ldif_write_objectGUID, + .write_hex_fn = extended_dn_write_hex + },{ + .name = "WKGUID", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_INVOCID", + .read_fn = extended_dn_read_GUID, + .write_clear_fn = ldif_write_objectGUID, + .write_hex_fn = extended_dn_write_hex + },{ + .name = "RMD_FLAGS", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_ADDTIME", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_CHANGETIME", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_LOCAL_USN", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_ORIGINATING_USN", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + },{ + .name = "RMD_VERSION", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy + } +}; + +/* TODO: Should be dynamic at some point */ +static const struct { + const char *name; + const char *syntax; +} samba_attributes[] = { + { "objectSid", LDB_SYNTAX_SAMBA_SID }, + { "securityIdentifier", LDB_SYNTAX_SAMBA_SID }, + { "tokenGroups", LDB_SYNTAX_SAMBA_SID }, + { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR }, + { "oMSyntax", LDB_SYNTAX_SAMBA_INT32 }, + { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY }, + { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO }, + { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP }, + { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO }, + { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO }, + { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA }, + { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR }, + { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, + { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, + { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64 }, + + /* + * these are extracted by searching + * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4)) + */ + { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID }, + { "categoryId", LDB_SYNTAX_SAMBA_GUID }, + { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID }, + { "currMachineId", LDB_SYNTAX_SAMBA_GUID }, + { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID }, + { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID }, + { "implementedCategories", LDB_SYNTAX_SAMBA_GUID }, + { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID }, + { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID }, + { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID }, + { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID }, + { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID }, + { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID }, + { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID }, + { "mSMQSites", LDB_SYNTAX_SAMBA_GUID }, + { "netbootGUID", LDB_SYNTAX_SAMBA_GUID }, + { "objectGUID", LDB_SYNTAX_SAMBA_GUID }, + { "pKTGuid", LDB_SYNTAX_SAMBA_GUID }, + { "requiredCategories", LDB_SYNTAX_SAMBA_GUID }, + { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID }, + { "siteGUID", LDB_SYNTAX_SAMBA_GUID }, + { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID }, + { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, + { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, + + /* + * these are known to be GUIDs + */ + { "invocationId", LDB_SYNTAX_SAMBA_GUID }, + { "parentGUID", LDB_SYNTAX_SAMBA_GUID }, + { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID }, + + /* These NDR encoded things we want to be able to read with --show-binary */ + { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD }, + { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS} +}; + +const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb, const char *name) +{ + unsigned int j; + const struct ldb_schema_syntax *s = NULL; + + for (j=0; j < ARRAY_SIZE(samba_syntaxes); j++) { + if (strcmp(name, samba_syntaxes[j].name) == 0) { + s = &samba_syntaxes[j]; + break; + } + } + return s; +} + +const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context *ldb, const char *name) +{ + unsigned int j; + const struct ldb_schema_syntax *s = NULL; + + for (j=0; j < ARRAY_SIZE(samba_attributes); j++) { + if (strcmp(samba_attributes[j].name, name) == 0) { + s = ldb_samba_syntax_by_name(ldb, samba_attributes[j].syntax); + break; + } + } + + return s; +} + +/* + register the samba ldif handlers +*/ +int ldb_register_samba_handlers(struct ldb_context *ldb) +{ + unsigned int i; + int ret; + + if (ldb_get_opaque(ldb, "SAMBA_HANDLERS_REGISTERED") != NULL) { + return LDB_SUCCESS; + } + + for (i=0; i < ARRAY_SIZE(samba_attributes); i++) { + const struct ldb_schema_syntax *s = NULL; + + s = ldb_samba_syntax_by_name(ldb, samba_attributes[i].syntax); + + if (!s) { + s = ldb_standard_syntax_by_name(ldb, samba_attributes[i].syntax); + } + + if (!s) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_schema_attribute_add_with_syntax(ldb, samba_attributes[i].name, LDB_ATTR_FLAG_FIXED, s); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) { + ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]); + if (ret != LDB_SUCCESS) { + return ret; + } + + } + + ret = ldb_set_opaque(ldb, "SAMBA_HANDLERS_REGISTERED", (void*)1); + if (ret != LDB_SUCCESS) { + return ret; + } + + return LDB_SUCCESS; +} diff --git a/lib/ldb-samba/ldif_handlers.h b/lib/ldb-samba/ldif_handlers.h new file mode 100644 index 00000000000..62903c4a964 --- /dev/null +++ b/lib/ldb-samba/ldif_handlers.h @@ -0,0 +1,23 @@ +#ifndef __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ +#define __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ + +#define LDB_SYNTAX_SAMBA_SID "LDB_SYNTAX_SAMBA_SID" +#define LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR "1.2.840.113556.1.4.907" +#define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID" +#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY" +#define LDB_SYNTAX_SAMBA_SCHEMAINFO "LDB_SYNTAX_SAMBA_SCHEMAINFO" +#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP" +#define LDB_SYNTAX_SAMBA_INT32 "LDB_SYNTAX_SAMBA_INT32" +#define LDB_SYNTAX_SAMBA_REPSFROMTO "LDB_SYNTAX_SAMBA_REPSFROMTO" +#define LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA "LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA" +#define LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR "LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR" +#define LDB_SYNTAX_SAMBA_RANGE64 "LDB_SYNTAX_SAMBA_RANGE64" +#define LDB_SYNTAX_SAMBA_DNSRECORD "LDB_SYNTAX_SAMBA_DNSRECORD" +#define LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS "LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS" +#include "lib/ldb-samba/ldif_handlers_proto.h" + +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) + +#endif /* __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ */ + diff --git a/lib/ldb-samba/pyldb.c b/lib/ldb-samba/pyldb.c new file mode 100644 index 00000000000..ff48a3bb040 --- /dev/null +++ b/lib/ldb-samba/pyldb.c @@ -0,0 +1,270 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb, Samba-specific functions + + Copyright (C) 2007-2010 Jelmer Vernooij + + 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 +#include "includes.h" +#include +#include +#include "param/pyparam.h" +#include "auth/credentials/pycredentials.h" +#include "ldb_wrap.h" +#include "lib/ldb-samba/ldif_handlers.h" +#include "auth/pyauth.h" + +void init_ldb(void); + +static PyObject *pyldb_module; +static PyObject *py_ldb_error; +staticforward PyTypeObject PySambaLdb; + +static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) +{ + if (ret == LDB_ERR_PYTHON_EXCEPTION) + return; /* Python exception should already be set, just keep that */ + + PyErr_SetObject(error, + Py_BuildValue(discard_const_p(char, "(i,s)"), ret, + ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); +} + +static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args) +{ + PyObject *py_lp_ctx; + struct loadparm_context *lp_ctx; + struct ldb_context *ldb; + + if (!PyArg_ParseTuple(args, "O", &py_lp_ctx)) + return NULL; + + ldb = PyLdb_AsLdbContext(self); + + lp_ctx = lpcfg_from_py_object(ldb, py_lp_ctx); + if (lp_ctx == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected loadparm object"); + return NULL; + } + + ldb_set_opaque(ldb, "loadparm", lp_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args) +{ + PyObject *py_creds; + struct cli_credentials *creds; + struct ldb_context *ldb; + + if (!PyArg_ParseTuple(args, "O", &py_creds)) + return NULL; + + creds = cli_credentials_from_py_object(py_creds); + if (creds == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials object"); + return NULL; + } + + ldb = PyLdb_AsLdbContext(self); + + ldb_set_opaque(ldb, "credentials", creds); + + Py_RETURN_NONE; +} + +/* XXX: This function really should be in libldb's pyldb.c */ +static PyObject *py_ldb_set_opaque_integer(PyObject *self, PyObject *args) +{ + int value; + int *old_val, *new_val; + char *py_opaque_name, *opaque_name_talloc; + struct ldb_context *ldb; + int ret; + TALLOC_CTX *tmp_ctx; + + if (!PyArg_ParseTuple(args, "si", &py_opaque_name, &value)) + return NULL; + + ldb = PyLdb_AsLdbContext(self); + + /* see if we have a cached copy */ + old_val = (int *)ldb_get_opaque(ldb, py_opaque_name); + /* XXX: We shouldn't just blindly assume that the value that is + * already present has the size of an int and is not shared + * with other code that may rely on it not changing. + * JRV 20100403 */ + + if (old_val) { + *old_val = value; + Py_RETURN_NONE; + } + + tmp_ctx = talloc_new(ldb); + if (tmp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + new_val = talloc(tmp_ctx, int); + if (new_val == NULL) { + talloc_free(tmp_ctx); + PyErr_NoMemory(); + return NULL; + } + + opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name); + if (opaque_name_talloc == NULL) { + talloc_free(tmp_ctx); + PyErr_NoMemory(); + return NULL; + } + + *new_val = value; + + /* cache the domain_sid in the ldb */ + ret = ldb_set_opaque(ldb, opaque_name_talloc, new_val); + + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + PyErr_SetLdbError(py_ldb_error, ret, ldb); + return NULL; + } + + talloc_steal(ldb, new_val); + talloc_steal(ldb, opaque_name_talloc); + talloc_free(tmp_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_utf8_casefold(PyObject *self) +{ + struct ldb_context *ldb; + + ldb = PyLdb_AsLdbContext(self); + + ldb_set_utf8_fns(ldb, NULL, wrap_casefold); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args) +{ + PyObject *py_session_info; + struct auth_session_info *info; + struct ldb_context *ldb; + PyObject *mod_samba_auth; + PyObject *PyAuthSession_Type; + bool ret; + + mod_samba_auth = PyImport_ImportModule("samba.dcerpc.auth"); + if (mod_samba_auth == NULL) + return NULL; + + PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "session_info"); + if (PyAuthSession_Type == NULL) + return NULL; + + ret = PyArg_ParseTuple(args, "O!", PyAuthSession_Type, &py_session_info); + + Py_DECREF(PyAuthSession_Type); + Py_DECREF(mod_samba_auth); + + if (!ret) + return NULL; + + ldb = PyLdb_AsLdbContext(self); + + info = PyAuthSession_AsSession(py_session_info); + + ldb_set_opaque(ldb, "sessionInfo", info); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_register_samba_handlers(PyObject *self) +{ + struct ldb_context *ldb; + int ret; + + /* XXX: Perhaps call this from PySambaLdb's init function ? */ + + ldb = PyLdb_AsLdbContext(self); + ret = ldb_register_samba_handlers(ldb); + + PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb); + + Py_RETURN_NONE; +} + +static PyMethodDef py_samba_ldb_methods[] = { + { "set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS, + "ldb_set_loadparm(session_info)\n" + "Set loadparm context to use when connecting." }, + { "set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS, + "ldb_set_credentials(credentials)\n" + "Set credentials to use when connecting." }, + { "set_opaque_integer", (PyCFunction)py_ldb_set_opaque_integer, + METH_VARARGS, NULL }, + { "set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, + METH_NOARGS, + "ldb_set_utf8_casefold()\n" + "Set the right Samba casefolding function for UTF8 charset." }, + { "register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, + METH_NOARGS, + "register_samba_handlers()\n" + "Register Samba-specific LDB modules and schemas." }, + { "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS, + "set_session_info(session_info)\n" + "Set session info to use when connecting." }, + { NULL }, +}; + +static PyTypeObject PySambaLdb = { + .tp_name = "samba._ldb.Ldb", + .tp_doc = "Connection to a LDB database.", + .tp_methods = py_samba_ldb_methods, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +void init_ldb(void) +{ + PyObject *m; + + pyldb_module = PyImport_ImportModule("ldb"); + if (pyldb_module == NULL) + return; + + PySambaLdb.tp_base = (PyTypeObject *)PyObject_GetAttrString(pyldb_module, "Ldb"); + if (PySambaLdb.tp_base == NULL) + return; + + py_ldb_error = PyObject_GetAttrString(pyldb_module, "LdbError"); + + if (PyType_Ready(&PySambaLdb) < 0) + return; + + m = Py_InitModule3("_ldb", NULL, "Samba-specific LDB python bindings"); + if (m == NULL) + return; + + Py_INCREF(&PySambaLdb); + PyModule_AddObject(m, "Ldb", (PyObject *)&PySambaLdb); +} diff --git a/lib/ldb-samba/samba_extensions.c b/lib/ldb-samba/samba_extensions.c new file mode 100644 index 00000000000..be9f36a5a7d --- /dev/null +++ b/lib/ldb-samba/samba_extensions.c @@ -0,0 +1,119 @@ +/* + ldb database library - samba extensions + + Copyright (C) Andrew Tridgell 2010 + + ** 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 . +*/ + + +#include "includes.h" +#include "ldb_module.h" +#include "lib/cmdline/popt_common.h" +#include "auth/gensec/gensec.h" +#include "auth/auth.h" +#include "param/param.h" +#include "dsdb/samdb/samdb.h" +#include "ldb_wrap.h" +#include "popt.h" + + + +/* + work out the length of a popt array + */ +static unsigned calculate_popt_array_length(struct poptOption *opts) +{ + unsigned i; + struct poptOption zero_opt = { NULL }; + for (i=0; memcmp(&zero_opt, &opts[i], sizeof(zero_opt)) != 0; i++) ; + return i; +} + +static struct poptOption cmdline_extensions[] = { + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS + POPT_COMMON_CONNECTION + POPT_COMMON_VERSION + { NULL } +}; + +/* + called to register additional command line options + */ +static int extensions_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) +{ + switch (t) { + case LDB_MODULE_HOOK_CMDLINE_OPTIONS: { + unsigned len1, len2; + struct poptOption **popt_options = ldb_module_popt_options(ldb); + struct poptOption *new_array; + + len1 = calculate_popt_array_length(*popt_options); + len2 = calculate_popt_array_length(cmdline_extensions); + new_array = talloc_array(NULL, struct poptOption, len1+len2+1); + if (NULL == new_array) { + return ldb_oom(ldb); + } + + memcpy(new_array, *popt_options, len1*sizeof(struct poptOption)); + memcpy(new_array+len1, cmdline_extensions, (1+len2)*sizeof(struct poptOption)); + (*popt_options) = new_array; + return LDB_SUCCESS; + } + + case LDB_MODULE_HOOK_CMDLINE_PRECONNECT: { + int r = ldb_register_samba_handlers(ldb); + if (r != LDB_SUCCESS) { + return ldb_operr(ldb); + } + gensec_init(); + + if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) { + return ldb_operr(ldb); + } + if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { + return ldb_operr(ldb); + } + if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) { + return ldb_operr(ldb); + } + + ldb_set_utf8_fns(ldb, NULL, wrap_casefold); + break; + } + + case LDB_MODULE_HOOK_CMDLINE_POSTCONNECT: + /* get the domain SID into the cache for SDDL processing */ + samdb_domain_sid(ldb); + break; + } + + return LDB_SUCCESS; +} + + +/* + initialise the module + */ +_PUBLIC_ int ldb_samba_extensions_init(const char *ldb_version) +{ + ldb_register_hook(extensions_hook); + + return LDB_SUCCESS; +} diff --git a/lib/ldb-samba/wscript_build b/lib/ldb-samba/wscript_build new file mode 100644 index 00000000000..2e1cacba649 --- /dev/null +++ b/lib/ldb-samba/wscript_build @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# LDBSAMBA gets included in the ldb build when we are building ldb_ildap +# as a built-in module and this delutes the symbols in the ldb library with +# the symbols of all of ldb_ildap's dependencies. + +bld.SAMBA_LIBRARY('ldbsamba', + source='ldif_handlers.c', + autoproto='ldif_handlers_proto.h', + public_deps='ldb', + deps='security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb_compat pyldb-util errors', + private_library=True + ) + +bld.SAMBA_SUBSYSTEM('ldbwrap', + source='ldb_wrap.c', + public_headers='ldb_wrap.h', + deps='ldb samba-util ldbsamba samba-hostconfig' + ) + + +bld.SAMBA_PYTHON('python_samba__ldb', 'pyldb.c', + deps='ldbsamba pyparam_util ldbwrap', + realname='samba/_ldb.so') + +bld.SAMBA_MODULE('ldbsamba_extensions', + source='samba_extensions.c', + init_function='ldb_samba_extensions_init', + module_init_name='ldb_init_module', + subsystem='ldb', + deps='ldb ldbsamba POPT_SAMBA POPT_CREDENTIALS cmdline-credentials gensec', + internal_module=False) + + +# the s4-internal ldap backend +bld.SAMBA_MODULE('ldb_ildap', + source='ldb_ildap.c', + init_function='ldb_ildap_init', + module_init_name='ldb_init_module', + deps='talloc cli-ldap credentials auth_system_session', + internal_module=False, + subsystem='ldb') diff --git a/lib/ldb/ABI/ldb-0.9.10.sigs b/lib/ldb/ABI/ldb-0.9.10.sigs new file mode 100644 index 00000000000..012ac65bb78 --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.10.sigs @@ -0,0 +1,218 @@ +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 *(void *, 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 *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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 *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) +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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.12.sigs b/lib/ldb/ABI/ldb-0.9.12.sigs new file mode 100644 index 00000000000..2206e790fc1 --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.12.sigs @@ -0,0 +1,219 @@ +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 *(void *, 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 *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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 *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) +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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.15.sigs b/lib/ldb/ABI/ldb-0.9.15.sigs new file mode 100644 index 00000000000..39d2f3eac49 --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.15.sigs @@ -0,0 +1,226 @@ +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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_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_location: const char *(struct ldb_request *) +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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.16.sigs b/lib/ldb/ABI/ldb-0.9.16.sigs new file mode 100644 index 00000000000..610a0a4a754 --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.16.sigs @@ -0,0 +1,228 @@ +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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.17.sigs b/lib/ldb/ABI/ldb-0.9.17.sigs new file mode 100644 index 00000000000..d0f56991d2c --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.17.sigs @@ -0,0 +1,229 @@ +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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.18.sigs b/lib/ldb/ABI/ldb-0.9.18.sigs new file mode 100644 index 00000000000..15913c93853 --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.18.sigs @@ -0,0 +1,240 @@ +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_asq_init: int (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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_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_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_paged_results_init: int (const char *) +ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_sample_init: int (const char *) +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_server_sort_init: int (const char *) +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_skel_init: int (const char *) +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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.19.sigs b/lib/ldb/ABI/ldb-0.9.19.sigs new file mode 100644 index 00000000000..62738709e4e --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.19.sigs @@ -0,0 +1,245 @@ +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_asq_init: int (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_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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +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_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_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_paged_results_init: int (const char *) +ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_sample_init: int (const char *) +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_server_sort_init: int (const char *) +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_skel_init: int (const char *) +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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.20.sigs b/lib/ldb/ABI/ldb-0.9.20.sigs new file mode 100644 index 00000000000..62738709e4e --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.20.sigs @@ -0,0 +1,245 @@ +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_asq_init: int (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_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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +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_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_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_paged_results_init: int (const char *) +ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_sample_init: int (const char *) +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_server_sort_init: int (const char *) +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_skel_init: int (const char *) +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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.22.sigs b/lib/ldb/ABI/ldb-0.9.22.sigs new file mode 100644 index 00000000000..b5a69c14a9b --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.22.sigs @@ -0,0 +1,245 @@ +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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.23.sigs b/lib/ldb/ABI/ldb-0.9.23.sigs new file mode 100644 index 00000000000..73e5caa896d --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.23.sigs @@ -0,0 +1,247 @@ +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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-0.9.24.sigs b/lib/ldb/ABI/ldb-0.9.24.sigs new file mode 100644 index 00000000000..5cb32f7c46b --- /dev/null +++ b/lib/ldb/ABI/ldb-0.9.24.sigs @@ -0,0 +1,248 @@ +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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-1.0.0.sigs b/lib/ldb/ABI/ldb-1.0.0.sigs new file mode 100644 index 00000000000..5cb32f7c46b --- /dev/null +++ b/lib/ldb/ABI/ldb-1.0.0.sigs @@ -0,0 +1,248 @@ +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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-1.0.1.sigs b/lib/ldb/ABI/ldb-1.0.1.sigs new file mode 100644 index 00000000000..5cb32f7c46b --- /dev/null +++ b/lib/ldb/ABI/ldb-1.0.1.sigs @@ -0,0 +1,248 @@ +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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-1.0.2.sigs b/lib/ldb/ABI/ldb-1.0.2.sigs new file mode 100644 index 00000000000..c13ac873d21 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.0.2.sigs @@ -0,0 +1,250 @@ +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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-1.1.0.sigs b/lib/ldb/ABI/ldb-1.1.0.sigs new file mode 100644 index 00000000000..149d4bc0ae8 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.1.0.sigs @@ -0,0 +1,253 @@ +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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/ldb-ildap-0.9.12.sigs b/lib/ldb/ABI/ldb-ildap-0.9.12.sigs new file mode 100644 index 00000000000..46392207599 --- /dev/null +++ b/lib/ldb/ABI/ldb-ildap-0.9.12.sigs @@ -0,0 +1,224 @@ +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 *(void *, 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 *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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 *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) +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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +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_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_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/lib/ldb/ABI/ldb-samba4-0.9.10.sigs b/lib/ldb/ABI/ldb-samba4-0.9.10.sigs new file mode 100644 index 00000000000..7f9dbb5297c --- /dev/null +++ b/lib/ldb/ABI/ldb-samba4-0.9.10.sigs @@ -0,0 +1,223 @@ +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 *(void *, 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 *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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 *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) +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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +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_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_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/lib/ldb/ABI/ldb-samba4-0.9.11.sigs b/lib/ldb/ABI/ldb-samba4-0.9.11.sigs new file mode 100644 index 00000000000..46392207599 --- /dev/null +++ b/lib/ldb/ABI/ldb-samba4-0.9.11.sigs @@ -0,0 +1,224 @@ +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 *(void *, 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 *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +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 *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +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_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) +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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +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_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_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/lib/ldb/Doxyfile b/lib/ldb/Doxyfile new file mode 100644 index 00000000000..07b12b516a8 --- /dev/null +++ b/lib/ldb/Doxyfile @@ -0,0 +1,26 @@ +PROJECT_NAME = LDB +OUTPUT_DIRECTORY = apidocs +REPEAT_BRIEF = YES +OPTIMIZE_OUTPUT_FOR_C = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +GENERATE_TODOLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +INPUT = include . +FILE_PATTERNS = *.h *.dox +EXCLUDE = include/config.h include/dlinklist.h \ + include/includes.h +EXAMPLE_PATH = examples +GENERATE_HTML = YES +HTML_OUTPUT = html +GENERATE_MAN = YES +ALWAYS_DETAILED_SEC = YES +JAVADOC_AUTOBRIEF = YES diff --git a/lib/ldb/Makefile b/lib/ldb/Makefile new file mode 100644 index 00000000000..5acfcbce58e --- /dev/null +++ b/lib/ldb/Makefile @@ -0,0 +1,51 @@ +# simple makefile wrapper to run waf + +WAF=WAF_MAKE=1 PATH=buildtools/bin:../../buildtools/bin:$$PATH waf + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags diff --git a/lib/ldb/README_gcov.txt b/lib/ldb/README_gcov.txt new file mode 100644 index 00000000000..2abd9378f43 --- /dev/null +++ b/lib/ldb/README_gcov.txt @@ -0,0 +1,29 @@ +Here is how to use gcov to test code coverage in ldb. + +Step 1: build ldb with gcov enabled + + make clean all WITH_GCOV=1 + +Step 3: run the test suite + make test-tdb + +Step 4: produce the gcov report + make gcov + +Step 5: read the summary reports + less *.report.gcov + +Step 6: examine the per-file reports + less ldb_tdb\#ldb_tdb.c.gcov + +You can also combine steps 2 to 4 like this: + + make clean all test-tdb gcov WITH_GCOV=1 + +Note that you should not expect 100% coverage, as some error paths +(such as memory allocation failures) are very hard to trigger. There +are ways of working around this, but they are quite tricky (they +involve allocation wrappers that "fork and fail on malloc"). + +The lines to look for in the per-file reports are the ones starting +with "#####". Those are lines that are never executed. diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c new file mode 100644 index 00000000000..2f4454c7b41 --- /dev/null +++ b/lib/ldb/common/attrib_handlers.c @@ -0,0 +1,496 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Bartlett 2006-2009 + + ** 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 . +*/ +/* + attribute handlers for well known attribute types, selected by syntax OID + see rfc2252 +*/ + +#include "ldb_private.h" +#include "system/locale.h" +#include "ldb_handlers.h" + +/* + default handler that just copies a ldb_val. +*/ +int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + *out = ldb_val_dup(mem_ctx, in); + if (in->length > 0 && out->data == NULL) { + ldb_oom(ldb); + return -1; + } + return 0; +} + +/* + a case folding copy handler, removing leading and trailing spaces and + multiple internal spaces + + We exploit the fact that utf8 never uses the space octet except for + the space itself +*/ +int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + char *s, *t; + size_t l; + + if (!in || !out || !(in->data)) { + return -1; + } + + out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length); + if (out->data == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data); + return -1; + } + + s = (char *)(out->data); + + /* remove trailing spaces if any */ + l = strlen(s); + while (l > 0 && s[l - 1] == ' ') l--; + s[l] = '\0'; + + /* remove leading spaces if any */ + if (*s == ' ') { + for (t = s; *s == ' '; s++) ; + + /* remove leading spaces by moving down the string */ + memmove(t, s, l); + + s = t; + } + + /* check middle spaces */ + while ((t = strchr(s, ' ')) != NULL) { + for (s = t; *s == ' '; s++) ; + + if ((s - t) > 1) { + l = strlen(s); + + /* remove all spaces but one by moving down the string */ + memmove(t + 1, s, l); + } + } + + out->length = strlen((char *)out->data); + return 0; +} + +/* length limited conversion of a ldb_val to a int32_t */ +static int val_to_int64(const struct ldb_val *in, int64_t *v) +{ + char *end; + char buf[64]; + + /* make sure we don't read past the end of the data */ + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (char *)in->data, in->length); + buf[in->length] = 0; + + /* We've to use "strtoll" here to have the intended overflows. + * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ + *v = (int64_t) strtoll(buf, &end, 0); + if (*end != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + return LDB_SUCCESS; +} + + +/* + canonicalise a ldap Integer + rfc2252 specifies it should be in decimal form +*/ +static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + int64_t i; + int ret; + + ret = val_to_int64(in, &i); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + compare two Integers +*/ +static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + int64_t i1=0, i2=0; + val_to_int64(v1, &i1); + val_to_int64(v2, &i2); + if (i1 == i2) return 0; + return i1 > i2? 1 : -1; +} + +/* + canonicalise a ldap Boolean + rfc2252 specifies it should be either "TRUE" or "FALSE" +*/ +static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (strncasecmp((char *)in->data, "TRUE", in->length) == 0) { + out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE"); + out->length = 4; + } else if (strncasecmp((char *)in->data, "FALSE", in->length) == 0) { + out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE"); + out->length = 4; + } else { + return -1; + } + return 0; +} + +/* + compare two Booleans +*/ +static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) { + return v1->length - v2->length; + } + return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); +} + + +/* + compare two binary blobs +*/ +int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) { + return v1->length - v2->length; + } + return memcmp(v1->data, v2->data, v1->length); +} + +/* + compare two case insensitive strings, ignoring multiple whitespaces + and leading and trailing whitespaces + see rfc2252 section 8.1 + + try to optimize for the ascii case, + but if we find out an utf8 codepoint revert to slower but correct function +*/ +int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; + size_t n1 = v1->length, n2 = v2->length; + char *b1, *b2; + const char *u1, *u2; + int ret; + while (n1 && *s1 == ' ') { s1++; n1--; }; + while (n2 && *s2 == ' ') { s2++; n2--; }; + + while (n1 && n2 && *s1 && *s2) { + /* the first 127 (0x7F) chars are ascii and utf8 guarantes they + * never appear in multibyte sequences */ + if (((unsigned char)s1[0]) & 0x80) goto utf8str; + if (((unsigned char)s2[0]) & 0x80) goto utf8str; + if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) + break; + if (*s1 == ' ') { + while (n1 && s1[0] == s1[1]) { s1++; n1--; } + while (n2 && s2[0] == s2[1]) { s2++; n2--; } + } + s1++; s2++; + n1--; n2--; + } + + /* check for trailing spaces only if the other pointers has + * reached the end of the strings otherwise we can + * mistakenly match. ex. "domain users" <-> + * "domainUpdates" + */ + if (n1 && *s1 == ' ' && (!n2 || !*s2)) { + while (n1 && *s1 == ' ') { s1++; n1--; } + } + if (n2 && *s2 == ' ' && (!n1 || !*s1)) { + while (n2 && *s2 == ' ') { s2++; n2--; } + } + if (n1 == 0 && n2 != 0) { + return -(int)toupper(*s2); + } + if (n2 == 0 && n1 != 0) { + return (int)toupper(*s1); + } + if (n2 == 0 && n2 == 0) { + return 0; + } + return (int)toupper(*s1) - (int)toupper(*s2); + +utf8str: + /* no need to recheck from the start, just from the first utf8 char found */ + b1 = ldb_casefold(ldb, mem_ctx, s1, n1); + b2 = ldb_casefold(ldb, mem_ctx, s2, n2); + + if (!b1 || !b2) { + /* One of the strings was not UTF8, so we have no + * options but to do a binary compare */ + talloc_free(b1); + talloc_free(b2); + ret = memcmp(s1, s2, MIN(n1, n2)); + if (ret == 0) { + if (n1 == n2) return 0; + if (n1 > n2) { + return (int)toupper(s1[n2]); + } else { + return -(int)toupper(s2[n1]); + } + } + return ret; + } + + u1 = b1; + u2 = b2; + + while (*u1 & *u2) { + if (*u1 != *u2) + break; + if (*u1 == ' ') { + while (u1[0] == u1[1]) u1++; + while (u2[0] == u2[1]) u2++; + } + u1++; u2++; + } + if (! (*u1 && *u2)) { + while (*u1 == ' ') u1++; + while (*u2 == ' ') u2++; + } + ret = (int)(*u1 - *u2); + + talloc_free(b1); + talloc_free(b2); + + return ret; +} + + +/* + canonicalise a attribute in DN format +*/ +static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct ldb_dn *dn; + int ret = -1; + + out->length = 0; + out->data = NULL; + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_INVALID_DN_SYNTAX; + } + + out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); + if (out->data == NULL) { + goto done; + } + out->length = strlen((char *)out->data); + + ret = 0; + +done: + talloc_free(dn); + + return ret; +} + +/* + compare two dns +*/ +static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + struct ldb_dn *dn1 = NULL, *dn2 = NULL; + int ret; + + dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); + if ( ! ldb_dn_validate(dn1)) return -1; + + dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); + if ( ! ldb_dn_validate(dn2)) { + talloc_free(dn1); + return -1; + } + + ret = ldb_dn_compare(dn1, dn2); + + talloc_free(dn1); + talloc_free(dn2); + return ret; +} + +/* + compare two utc time values. 1 second resolution +*/ +static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + time_t t1=0, t2=0; + ldb_val_to_time(v1, &t1); + ldb_val_to_time(v2, &t2); + if (t1 == t2) return 0; + return t1 > t2? 1 : -1; +} + +/* + canonicalise a utc time +*/ +static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + time_t t; + int ret; + ret = ldb_val_to_time(in, &t); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *)ldb_timestring(mem_ctx, t); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + table of standard attribute handlers +*/ +static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { + { + .name = LDB_SYNTAX_INTEGER, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_Integer, + .comparison_fn = ldb_comparison_Integer + }, + { + .name = LDB_SYNTAX_OCTET_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary + }, + { + .name = LDB_SYNTAX_DIRECTORY_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_fold, + .comparison_fn = ldb_comparison_fold + }, + { + .name = LDB_SYNTAX_DN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_dn, + .comparison_fn = ldb_comparison_dn + }, + { + .name = LDB_SYNTAX_OBJECTCLASS, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_fold, + .comparison_fn = ldb_comparison_fold + }, + { + .name = LDB_SYNTAX_UTC_TIME, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_utctime, + .comparison_fn = ldb_comparison_utctime + }, + { + .name = LDB_SYNTAX_BOOLEAN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_Boolean, + .comparison_fn = ldb_comparison_Boolean + }, +}; + + +/* + return the attribute handlers for a given syntax name +*/ +const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, + const char *syntax) +{ + unsigned int i; + unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); + /* TODO: should be replaced with a binary search */ + for (i=0;i. +*/ + +/* + * Name: ldb + * + * Component: ldb core API + * + * Description: core API routines interfacing to ldb backends + * + * Author: Andrew Tridgell + */ + +#define TEVENT_DEPRECATED 1 +#include "ldb_private.h" +#include "ldb.h" + +static int ldb_context_destructor(void *ptr) +{ + struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); + + if (ldb->transaction_active) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "A transaction is still active in ldb context [%p] on %s", + ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); + } + + return 0; +} + +/* + this is used to catch debug messages from events +*/ +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); + enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; + char *s = NULL; + + switch (level) { + case TEVENT_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TEVENT_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TEVENT_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TEVENT_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + }; + + vasprintf(&s, fmt, ap); + if (!s) return; + ldb_debug(ldb, ldb_level, "tevent: %s", s); + free(s); +} + +/* + initialise a ldb context + The mem_ctx is required + The event_ctx is required +*/ +struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) +{ + struct ldb_context *ldb; + int ret; + const char *modules_path = getenv("LDB_MODULES_PATH"); + + if (modules_path == NULL) { + modules_path = LDB_MODULESDIR; + } + + ret = ldb_modules_load(modules_path, LDB_VERSION); + if (ret != LDB_SUCCESS) { + return NULL; + } + + ldb = talloc_zero(mem_ctx, struct ldb_context); + if (ldb == NULL) { + return NULL; + } + + /* A new event context so that callers who don't want ldb + * operating on thier global event context can work without + * having to provide their own private one explicitly */ + if (ev_ctx == NULL) { + ev_ctx = tevent_context_init(ldb); + tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); + tevent_loop_allow_nesting(ev_ctx); + } + + ret = ldb_setup_wellknown_attributes(ldb); + if (ret != LDB_SUCCESS) { + talloc_free(ldb); + return NULL; + } + + ldb_set_utf8_default(ldb); + ldb_set_create_perms(ldb, 0666); + ldb_set_modules_dir(ldb, LDB_MODULESDIR); + ldb_set_event_context(ldb, ev_ctx); + + /* TODO: get timeout from options if available there */ + ldb->default_timeout = 300; /* set default to 5 minutes */ + + talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); + + return ldb; +} + +/* + try to autodetect a basedn if none specified. This fixes one of my + pet hates about ldapsearch, which is that you have to get a long, + complex basedn right to make any use of it. +*/ +void ldb_set_default_dns(struct ldb_context *ldb) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_result *res; + struct ldb_dn *tmp_dn=NULL; + static const char *attrs[] = { + "rootDomainNamingContext", + "configurationNamingContext", + "schemaNamingContext", + "defaultNamingContext", + NULL + }; + + tmp_ctx = talloc_new(ldb); + ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL), + LDB_SCOPE_BASE, attrs, "(objectClass=*)"); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return; + } + + if (res->count != 1) { + talloc_free(tmp_ctx); + return; + } + + if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "rootDomainNamingContext"); + ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "configurationNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "configurationNamingContext"); + ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "schemaNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "schemaNamingContext"); + ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "defaultNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "defaultNamingContext"); + ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn); + } + + talloc_free(tmp_ctx); +} + +struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "configurationNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "schemaNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "defaultNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +/* + connect to a database. The URL can either be one of the following forms + ldb://path + ldapi://path + + flags is made up of LDB_FLG_* + + the options are passed uninterpreted to the backend, and are + backend specific +*/ +int ldb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[]) +{ + int ret; + char *url2; + /* We seem to need to do this here, or else some utilities don't + * get ldb backends */ + + ldb->flags = flags; + + url2 = talloc_strdup(ldb, url); + if (!url2) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_set_opaque(ldb, "ldb_url", url2); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (ldb_load_modules(ldb, options) != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Unable to load modules for %s: %s", + url, ldb_errstring(ldb)); + return LDB_ERR_OTHER; + } + + /* set the default base dn */ + ldb_set_default_dns(ldb); + + return LDB_SUCCESS; +} + +void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) +{ + if (ldb->err_string) { + talloc_free(ldb->err_string); + } + ldb->err_string = talloc_strdup(ldb, err_string); + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_set_errstring: %s", ldb->err_string); + } +} + +void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) +{ + va_list ap; + char *old_string = NULL; + + if (ldb->err_string) { + old_string = ldb->err_string; + } + + va_start(ap, format); + ldb->err_string = talloc_vasprintf(ldb, format, ap); + va_end(ap); + talloc_free(old_string); +} + +void ldb_reset_err_string(struct ldb_context *ldb) +{ + if (ldb->err_string) { + talloc_free(ldb->err_string); + ldb->err_string = NULL; + } +} + + + +/* + set an ldb error based on file:line +*/ +int ldb_error_at(struct ldb_context *ldb, int ecode, + const char *reason, const char *file, int line) +{ + if (reason == NULL) { + reason = ldb_strerror(ecode); + } + ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); + return ecode; +} + + +#define FIRST_OP_NOERR(ldb, op) do { \ + module = ldb->modules; \ + while (module && module->ops->op == NULL) module = module->next; \ + if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \ + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ + module->ops->name); \ + } \ +} while (0) + +#define FIRST_OP(ldb, op) do { \ + FIRST_OP_NOERR(ldb, op); \ + if (module == NULL) { \ + ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ + return LDB_ERR_OPERATIONS_ERROR; \ + } \ +} while (0) + + +/* + start a transaction +*/ +int ldb_transaction_start(struct ldb_context *ldb) +{ + struct ldb_module *module; + int status; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "start ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* explicit transaction active, count nested requests */ + if (ldb->transaction_active) { + ldb->transaction_active++; + return LDB_SUCCESS; + } + + /* start a new transaction */ + ldb->transaction_active++; + ldb->prepare_commit_done = false; + + FIRST_OP(ldb, start_transaction); + + ldb_reset_err_string(ldb); + + status = module->ops->start_transaction(module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction start: %s (%d)", + ldb_strerror(status), + status); + } + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", + ldb_errstring(module->ldb)); + } + return status; +} + +/* + prepare for transaction commit (first phase of two phase commit) +*/ +int ldb_transaction_prepare_commit(struct ldb_context *ldb) +{ + struct ldb_module *module; + int status; + + if (ldb->prepare_commit_done) { + return LDB_SUCCESS; + } + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 1) { + return LDB_SUCCESS; + } + + ldb->prepare_commit_done = true; + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "prepare commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + /* call prepare transaction if available */ + FIRST_OP_NOERR(ldb, prepare_commit); + if (module == NULL) { + return LDB_SUCCESS; + } + + status = module->ops->prepare_commit(module); + if (status != LDB_SUCCESS) { + /* if a module fails the prepare then we need + to call the end transaction for everyone */ + FIRST_OP(ldb, del_transaction); + module->ops->del_transaction(module); + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction prepare commit: %s (%d)", + ldb_strerror(status), + status); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", + ldb_errstring(module->ldb)); + } + } + + return status; +} + + +/* + commit a transaction +*/ +int ldb_transaction_commit(struct ldb_context *ldb) +{ + struct ldb_module *module; + int status; + + status = ldb_transaction_prepare_commit(ldb); + if (status != LDB_SUCCESS) { + return status; + } + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "commit ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_reset_err_string(ldb); + + FIRST_OP(ldb, end_transaction); + status = module->ops->end_transaction(module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction commit: %s (%d)", + ldb_strerror(status), + status); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", + ldb_errstring(module->ldb)); + } + /* cancel the transaction */ + FIRST_OP(ldb, del_transaction); + module->ops->del_transaction(module); + } + return status; +} + + +/* + cancel a transaction +*/ +int ldb_transaction_cancel(struct ldb_context *ldb) +{ + struct ldb_module *module; + int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "cancel ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* really cancel only if all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "cancel called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + FIRST_OP(ldb, del_transaction); + + status = module->ops->del_transaction(module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction cancel: %s (%d)", + ldb_strerror(status), + status); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", + ldb_errstring(module->ldb)); + } + } + return status; +} + +/* + cancel a transaction with no error if no transaction is pending + used when we fork() to clear any parent transactions +*/ +int ldb_transaction_cancel_noerr(struct ldb_context *ldb) +{ + if (ldb->transaction_active > 0) { + return ldb_transaction_cancel(ldb); + } + return LDB_SUCCESS; +} + + +/* autostarts a transacion if none active */ +static int ldb_autotransaction_request(struct ldb_context *ldb, + struct ldb_request *req) +{ + int ret; + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request(ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + return ldb_transaction_commit(ldb); + } + ldb_transaction_cancel(ldb); + + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); + } + + return ret; +} + +int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) +{ + struct tevent_context *ev; + int ret; + + if (!handle) { + return LDB_ERR_UNAVAILABLE; + } + + if (handle->state == LDB_ASYNC_DONE) { + return handle->status; + } + + ev = ldb_get_event_context(handle->ldb); + if (NULL == ev) { + return LDB_ERR_OPERATIONS_ERROR; + } + + switch (type) { + case LDB_WAIT_NONE: + ret = tevent_loop_once(ev); + if (ret != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (handle->state == LDB_ASYNC_DONE || + handle->status != LDB_SUCCESS) { + return handle->status; + } + break; + + case LDB_WAIT_ALL: + while (handle->state != LDB_ASYNC_DONE) { + ret = tevent_loop_once(ev); + if (ret != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (handle->status != LDB_SUCCESS) { + return handle->status; + } + } + return handle->status; + } + + return LDB_SUCCESS; +} + +/* set the specified timeout or, if timeout is 0 set the default timeout */ +int ldb_set_timeout(struct ldb_context *ldb, + struct ldb_request *req, + int timeout) +{ + if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; + + if (timeout != 0) { + req->timeout = timeout; + } else { + req->timeout = ldb->default_timeout; + } + req->starttime = time(NULL); + + return LDB_SUCCESS; +} + +/* calculates the new timeout based on the previous starttime and timeout */ +int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, + struct ldb_request *oldreq, + struct ldb_request *newreq) +{ + if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; + + if (oldreq == NULL) { + return ldb_set_timeout(ldb, newreq, 0); + } + + newreq->starttime = oldreq->starttime; + newreq->timeout = oldreq->timeout; + + return LDB_SUCCESS; +} + + +/* + set the permissions for new files to be passed to open() in + backends that use local files + */ +void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) +{ + ldb->create_perms = perms; +} + +unsigned int ldb_get_create_perms(struct ldb_context *ldb) +{ + return ldb->create_perms; +} + +void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev) +{ + ldb->ev_ctx = ev; +} + +struct tevent_context * ldb_get_event_context(struct ldb_context *ldb) +{ + return ldb->ev_ctx; +} + +void ldb_request_set_state(struct ldb_request *req, int state) +{ + req->handle->state = state; +} + +int ldb_request_get_status(struct ldb_request *req) +{ + return req->handle->status; +} + + +/* + trace a ldb request +*/ +static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req) +{ + TALLOC_CTX *tmp_ctx = talloc_new(req); + unsigned int i; + + switch (req->operation) { + case LDB_SEARCH: + ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n"); + ldb_debug_add(ldb, " dn: %s\n", + ldb_dn_is_null(req->op.search.base)?"": + ldb_dn_get_linearized(req->op.search.base)); + ldb_debug_add(ldb, " scope: %s\n", + req->op.search.scope==LDB_SCOPE_BASE?"base": + req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": + req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN"); + ldb_debug_add(ldb, " expr: %s\n", + ldb_filter_from_tree(tmp_ctx, req->op.search.tree)); + if (req->op.search.attrs == NULL) { + ldb_debug_add(ldb, " attr: \n"); + } else { + for (i=0; req->op.search.attrs[i]; i++) { + ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]); + } + } + break; + case LDB_DELETE: + ldb_debug_add(ldb, "ldb_trace_request: DELETE\n"); + ldb_debug_add(ldb, " dn: %s\n", + ldb_dn_get_linearized(req->op.del.dn)); + break; + case LDB_RENAME: + ldb_debug_add(ldb, "ldb_trace_request: RENAME\n"); + ldb_debug_add(ldb, " olddn: %s\n", + ldb_dn_get_linearized(req->op.rename.olddn)); + ldb_debug_add(ldb, " newdn: %s\n", + ldb_dn_get_linearized(req->op.rename.newdn)); + break; + case LDB_EXTENDED: + ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n"); + ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid); + ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no"); + break; + case LDB_ADD: + ldb_debug_add(ldb, "ldb_trace_request: ADD\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_ldif_message_string(req->handle->ldb, tmp_ctx, + LDB_CHANGETYPE_ADD, + req->op.add.message)); + break; + case LDB_MODIFY: + ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_ldif_message_string(req->handle->ldb, tmp_ctx, + LDB_CHANGETYPE_ADD, + req->op.mod.message)); + break; + case LDB_REQ_REGISTER_CONTROL: + ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + req->op.reg_control.oid); + break; + case LDB_REQ_REGISTER_PARTITION: + ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_dn_get_linearized(req->op.reg_partition.dn)); + break; + default: + ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n", + req->operation); + break; + } + + if (req->controls == NULL) { + ldb_debug_add(ldb, " control: \n"); + } else { + for (i=0; req->controls && req->controls[i]; i++) { + if (req->controls[i]->oid) { + ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", + req->controls[i]->oid, + req->controls[i]->critical, + req->controls[i]->data?"yes":"no"); + } + } + } + + ldb_debug_end(ldb, LDB_DEBUG_TRACE); + + talloc_free(tmp_ctx); +} + +/* + check that the element flags don't have any internal bits set + */ +static int ldb_msg_check_element_flags(struct ldb_context *ldb, + const struct ldb_message *message) +{ + unsigned i; + for (i=0; inum_elements; i++) { + if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { + ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", + message->elements[i].flags, message->elements[i].name, + ldb_dn_get_linearized(message->dn)); + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + return LDB_SUCCESS; +} + + +/* + start an ldb request + NOTE: the request must be a talloc context. + returns LDB_ERR_* on errors. +*/ +int ldb_request(struct ldb_context *ldb, struct ldb_request *req) +{ + struct ldb_module *module; + int ret; + + if (req->callback == NULL) { + ldb_set_errstring(ldb, "Requests MUST define callbacks"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ldb_reset_err_string(ldb); + + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_trace_request(ldb, req); + } + + /* call the first module in the chain */ + switch (req->operation) { + case LDB_SEARCH: + /* due to "ldb_build_search_req" base DN always != NULL */ + if (!ldb_dn_validate(req->op.search.base)) { + ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", + ldb_dn_get_linearized(req->op.search.base)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, search); + ret = module->ops->search(module, req); + break; + case LDB_ADD: + if (!ldb_dn_validate(req->op.add.message->dn)) { + ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", + ldb_dn_get_linearized(req->op.add.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + /* + * we have to normalize here, as so many places + * in modules and backends assume we don't have two + * elements with the same name + */ + ret = ldb_msg_normalize(ldb, req, req->op.add.message, + discard_const(&req->op.add.message)); + if (ret != LDB_SUCCESS) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, add); + ret = ldb_msg_check_element_flags(ldb, req->op.add.message); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = module->ops->add(module, req); + break; + case LDB_MODIFY: + if (!ldb_dn_validate(req->op.mod.message->dn)) { + ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, modify); + ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = module->ops->modify(module, req); + break; + case LDB_DELETE: + if (!ldb_dn_validate(req->op.del.dn)) { + ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", + ldb_dn_get_linearized(req->op.del.dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, del); + ret = module->ops->del(module, req); + break; + case LDB_RENAME: + if (!ldb_dn_validate(req->op.rename.olddn)) { + ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", + ldb_dn_get_linearized(req->op.rename.olddn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + if (!ldb_dn_validate(req->op.rename.newdn)) { + ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", + ldb_dn_get_linearized(req->op.rename.newdn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, rename); + ret = module->ops->rename(module, req); + break; + case LDB_EXTENDED: + FIRST_OP(ldb, extended); + ret = module->ops->extended(module, req); + break; + default: + FIRST_OP(ldb, request); + ret = module->ops->request(module, req); + break; + } + + return ret; +} + +int ldb_request_done(struct ldb_request *req, int status) +{ + req->handle->state = LDB_ASYNC_DONE; + req->handle->status = status; + return status; +} + +/* + search the database given a LDAP-like search expression + + returns an LDB error code + + Use talloc_free to free the ldb_message returned in 'res', if successful + +*/ +int ldb_search_default_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_result *res; + unsigned int n; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + res->msgs = talloc_realloc(res, res->msgs, + struct ldb_message *, res->count + 2); + if (! res->msgs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->msgs[res->count + 1] = NULL; + + res->msgs[res->count] = talloc_move(res->msgs, &ares->message); + res->count++; + break; + + case LDB_REPLY_REFERRAL: + if (res->refs) { + for (n = 0; res->refs[n]; n++) /*noop*/ ; + } else { + n = 0; + } + + res->refs = talloc_realloc(res, res->refs, char *, n + 2); + if (! res->refs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->refs[n] = talloc_move(res->refs, &ares->referral); + res->refs[n + 1] = NULL; + break; + + case LDB_REPLY_DONE: + /* TODO: we should really support controls on entries + * and referrals too! */ + res->controls = talloc_move(res, &ares->controls); + + /* this is the last message, and means the request is done */ + /* we have to signal and eventual ldb_wait() waiting that the + * async request operation was completed */ + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + + return LDB_SUCCESS; +} + +int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_result *res; + unsigned int n; + int ret; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + ret = ares->error; + talloc_free(ares); + return ldb_request_done(req, ret); + } + + switch (ares->type) { + case LDB_REPLY_REFERRAL: + if (res->refs) { + for (n = 0; res->refs[n]; n++) /*noop*/ ; + } else { + n = 0; + } + + res->refs = talloc_realloc(res, res->refs, char *, n + 2); + if (! res->refs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->refs[n] = talloc_move(res->refs, &ares->referral); + res->refs[n + 1] = NULL; + break; + + case LDB_REPLY_DONE: + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + default: + talloc_free(ares); + ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); +} + +int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + int ret; + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + ret = ares->error; + talloc_free(ares); + return ldb_request_done(req, ret); + } + + if (ares->type != LDB_REPLY_DONE) { + talloc_free(ares); + ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); +} + +int ldb_build_search_req_ex(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_SEARCH; + if (base == NULL) { + req->op.search.base = ldb_dn_new(req, ldb, NULL); + } else { + req->op.search.base = base; + } + req->op.search.scope = scope; + + req->op.search.tree = tree; + if (req->op.search.tree == NULL) { + ldb_set_errstring(ldb, "'tree' can't be NULL"); + talloc_free(req); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->op.search.attrs = attrs; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_build_search_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + const char *expression, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_parse_tree *tree; + int ret; + + tree = ldb_parse_tree(mem_ctx, expression); + if (tree == NULL) { + ldb_set_errstring(ldb, "Unable to parse search expression"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base, + scope, tree, attrs, controls, + context, callback, parent); + if (ret == LDB_SUCCESS) { + talloc_steal(*ret_req, tree); + } + return ret; +} + +int ldb_build_add_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_ADD; + req->op.add.message = message; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_build_mod_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_MODIFY; + req->op.mod.message = message; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_build_del_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_DELETE; + req->op.del.dn = dn; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_build_rename_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_RENAME; + req->op.rename.olddn = olddn; + req->op.rename.newdn = newdn; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_extended_default_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_result *res; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + if (ares->type == LDB_REPLY_DONE) { + + /* TODO: we should really support controls on entries and referrals too! */ + res->extended = talloc_move(res, &ares->response); + res->controls = talloc_move(res, &ares->controls); + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); +} + +int ldb_build_extended_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *oid, + void *data, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_EXTENDED; + req->op.extended.oid = oid; + req->op.extended.data = data; + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (parent) { + req->handle->nesting++; + req->handle->parent = parent; + req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; + } + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_extended(struct ldb_context *ldb, + const char *oid, + void *data, + struct ldb_result **_res) +{ + struct ldb_request *req; + int ret; + struct ldb_result *res; + + *_res = NULL; + + res = talloc_zero(ldb, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_extended_req(&req, ldb, ldb, + oid, data, NULL, + res, ldb_extended_default_callback, + NULL); + if (ret != LDB_SUCCESS) goto done; + + ldb_set_timeout(ldb, req, 0); /* use default timeout */ + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(req); + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + } + + *_res = res; + return ret; +} + +/* + note that ldb_search() will automatically replace a NULL 'base' value + with the defaultNamingContext from the rootDSE if available. +*/ +int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + const char *exp_fmt, ...) +{ + struct ldb_request *req; + struct ldb_result *res; + char *expression; + va_list ap; + int ret; + + expression = NULL; + *result = NULL; + req = NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (exp_fmt) { + va_start(ap, exp_fmt); + expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); + va_end(ap); + + if (!expression) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ldb_build_search_req(&req, ldb, mem_ctx, + base?base:ldb_get_default_basedn(ldb), + scope, + expression, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + ldb_req_set_location(req, "ldb_search"); + + if (ret != LDB_SUCCESS) goto done; + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + res = NULL; + } + + talloc_free(expression); + talloc_free(req); + + *result = res; + return ret; +} + +/* + add a record to the database. Will fail if a record with the given class + and key already exists +*/ +int ldb_add(struct ldb_context *ldb, + const struct ldb_message *message) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&req, ldb, ldb, + message, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_add"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + +/* + modify the specified attributes of a record +*/ +int ldb_modify(struct ldb_context *ldb, + const struct ldb_message *message) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_mod_req(&req, ldb, ldb, + message, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_modify"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + delete a record from the database +*/ +int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_del_req(&req, ldb, ldb, + dn, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_delete"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + +/* + rename a record in the database +*/ +int ldb_rename(struct ldb_context *ldb, + struct ldb_dn *olddn, struct ldb_dn *newdn) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_rename_req(&req, ldb, ldb, + olddn, + newdn, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_rename"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + return the global sequence number +*/ +int ldb_sequence_number(struct ldb_context *ldb, + enum ldb_sequence_type type, uint64_t *seq_num) +{ + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *seqr; + struct ldb_result *res; + TALLOC_CTX *tmp_ctx; + int ret; + + *seq_num = 0; + + tmp_ctx = talloc_zero(ldb, struct ldb_request); + if (tmp_ctx == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request); + if (seq == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + seq->type = type; + + ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res); + if (ret != LDB_SUCCESS) { + goto done; + } + talloc_steal(tmp_ctx, res); + + if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) { + ldb_set_errstring(ldb, "Invalid OID in reply"); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + seqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + *seq_num = seqr->seq_num; + +done: + talloc_free(tmp_ctx); + return ret; +} + +/* + return extended error information +*/ +const char *ldb_errstring(struct ldb_context *ldb) +{ + if (ldb->err_string) { + return ldb->err_string; + } + + return NULL; +} + +/* + return a string explaining what a ldb error constant meancs +*/ +const char *ldb_strerror(int ldb_err) +{ + switch (ldb_err) { + case LDB_SUCCESS: + return "Success"; + case LDB_ERR_OPERATIONS_ERROR: + return "Operations error"; + case LDB_ERR_PROTOCOL_ERROR: + return "Protocol error"; + case LDB_ERR_TIME_LIMIT_EXCEEDED: + return "Time limit exceeded"; + case LDB_ERR_SIZE_LIMIT_EXCEEDED: + return "Size limit exceeded"; + case LDB_ERR_COMPARE_FALSE: + return "Compare false"; + case LDB_ERR_COMPARE_TRUE: + return "Compare true"; + case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: + return "Auth method not supported"; + case LDB_ERR_STRONG_AUTH_REQUIRED: + return "Strong auth required"; +/* 9 RESERVED */ + case LDB_ERR_REFERRAL: + return "Referral error"; + case LDB_ERR_ADMIN_LIMIT_EXCEEDED: + return "Admin limit exceeded"; + case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: + return "Unsupported critical extension"; + case LDB_ERR_CONFIDENTIALITY_REQUIRED: + return "Confidentiality required"; + case LDB_ERR_SASL_BIND_IN_PROGRESS: + return "SASL bind in progress"; + case LDB_ERR_NO_SUCH_ATTRIBUTE: + return "No such attribute"; + case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: + return "Undefined attribute type"; + case LDB_ERR_INAPPROPRIATE_MATCHING: + return "Inappropriate matching"; + case LDB_ERR_CONSTRAINT_VIOLATION: + return "Constraint violation"; + case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: + return "Attribute or value exists"; + case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: + return "Invalid attribute syntax"; +/* 22-31 unused */ + case LDB_ERR_NO_SUCH_OBJECT: + return "No such object"; + case LDB_ERR_ALIAS_PROBLEM: + return "Alias problem"; + case LDB_ERR_INVALID_DN_SYNTAX: + return "Invalid DN syntax"; +/* 35 RESERVED */ + case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: + return "Alias dereferencing problem"; +/* 37-47 unused */ + case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: + return "Inappropriate authentication"; + case LDB_ERR_INVALID_CREDENTIALS: + return "Invalid credentials"; + case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: + return "insufficient access rights"; + case LDB_ERR_BUSY: + return "Busy"; + case LDB_ERR_UNAVAILABLE: + return "Unavailable"; + case LDB_ERR_UNWILLING_TO_PERFORM: + return "Unwilling to perform"; + case LDB_ERR_LOOP_DETECT: + return "Loop detect"; +/* 55-63 unused */ + case LDB_ERR_NAMING_VIOLATION: + return "Naming violation"; + case LDB_ERR_OBJECT_CLASS_VIOLATION: + return "Object class violation"; + case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: + return "Not allowed on non-leaf"; + case LDB_ERR_NOT_ALLOWED_ON_RDN: + return "Not allowed on RDN"; + case LDB_ERR_ENTRY_ALREADY_EXISTS: + return "Entry already exists"; + case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: + return "Object class mods prohibited"; +/* 70 RESERVED FOR CLDAP */ + case LDB_ERR_AFFECTS_MULTIPLE_DSAS: + return "Affects multiple DSAs"; +/* 72-79 unused */ + case LDB_ERR_OTHER: + return "Other"; + } + + return "Unknown error"; +} + +/* + set backend specific opaque parameters +*/ +int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) +{ + struct ldb_opaque *o; + + /* allow updating an existing value */ + for (o=ldb->opaque;o;o=o->next) { + if (strcmp(o->name, name) == 0) { + o->value = value; + return LDB_SUCCESS; + } + } + + o = talloc(ldb, struct ldb_opaque); + if (o == NULL) { + ldb_oom(ldb); + return LDB_ERR_OTHER; + } + o->next = ldb->opaque; + o->name = name; + o->value = value; + ldb->opaque = o; + return LDB_SUCCESS; +} + +/* + get a previously set opaque value +*/ +void *ldb_get_opaque(struct ldb_context *ldb, const char *name) +{ + struct ldb_opaque *o; + for (o=ldb->opaque;o;o=o->next) { + if (strcmp(o->name, name) == 0) { + return o->value; + } + } + return NULL; +} + +int ldb_global_init(void) +{ + /* Provided for compatibility with some older versions of ldb */ + return 0; +} + +/* return the ldb flags */ +unsigned int ldb_get_flags(struct ldb_context *ldb) +{ + return ldb->flags; +} + +/* set the ldb flags */ +void ldb_set_flags(struct ldb_context *ldb, unsigned flags) +{ + ldb->flags = flags; +} + + +/* + set the location in a ldb request. Used for debugging + */ +void ldb_req_set_location(struct ldb_request *req, const char *location) +{ + if (req && req->handle) { + req->handle->location = location; + } +} + +/* + return the location set with dsdb_req_set_location + */ +const char *ldb_req_location(struct ldb_request *req) +{ + return req->handle->location; +} + +/** + mark a request as untrusted. This tells the rootdse module to remove + unregistered controls + */ +void ldb_req_mark_untrusted(struct ldb_request *req) +{ + req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; +} + +/** + mark a request as trusted. + */ +void ldb_req_mark_trusted(struct ldb_request *req) +{ + req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; +} + +/** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) +{ + if (req != NULL && req->handle != NULL) { + req->handle->custom_flags = flags; + } +} + + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req) +{ + if (req != NULL && req->handle != NULL) { + return req->handle->custom_flags; + } + + /* + * 0 is not something any better or worse than + * anything else as req or the handle is NULL + */ + return 0; +} + + +/** + return true is a request is untrusted + */ +bool ldb_req_is_untrusted(struct ldb_request *req) +{ + return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; +} diff --git a/lib/ldb/common/ldb_attributes.c b/lib/ldb/common/ldb_attributes.c new file mode 100644 index 00000000000..21a3e6eb93b --- /dev/null +++ b/lib/ldb/common/ldb_attributes.c @@ -0,0 +1,306 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** 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 . +*/ +/* + register handlers for specific attributes and objectclass relationships + + this allows a backend to store its schema information in any format + it likes (or to not have any schema information at all) while keeping the + message matching logic generic +*/ + +#include "ldb_private.h" +#include "ldb_handlers.h" + +/* + add a attribute to the ldb_schema + + if flags contains LDB_ATTR_FLAG_ALLOCATED + the attribute name string will be copied using + talloc_strdup(), otherwise it needs to be a static const + string at least with a lifetime longer than the ldb struct! + + the ldb_schema_syntax structure should be a pointer + to a static const struct or at least it needs to be + a struct with a longer lifetime than the ldb context! + +*/ +int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, + const char *attribute, + unsigned flags, + const struct ldb_schema_syntax *syntax) +{ + unsigned int i, n; + struct ldb_schema_attribute *a; + + if (!syntax) { + return LDB_ERR_OPERATIONS_ERROR; + } + + n = ldb->schema.num_attributes + 1; + + a = talloc_realloc(ldb, ldb->schema.attributes, + struct ldb_schema_attribute, n); + if (a == NULL) { + ldb_oom(ldb); + return -1; + } + ldb->schema.attributes = a; + + for (i = 0; i < ldb->schema.num_attributes; i++) { + int cmp = ldb_attr_cmp(attribute, a[i].name); + if (cmp == 0) { + /* silently ignore attempts to overwrite fixed attributes */ + if (a[i].flags & LDB_ATTR_FLAG_FIXED) { + return 0; + } + if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { + talloc_free(discard_const_p(char, a[i].name)); + } + /* To cancel out increment below */ + ldb->schema.num_attributes--; + break; + } else if (cmp < 0) { + memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i)); + break; + } + } + ldb->schema.num_attributes++; + + a[i].name = attribute; + a[i].flags = flags; + a[i].syntax = syntax; + + if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { + a[i].name = talloc_strdup(a, a[i].name); + if (a[i].name == NULL) { + ldb_oom(ldb); + return -1; + } + } + + return 0; +} + +static const struct ldb_schema_syntax ldb_syntax_default = { + .name = LDB_SYNTAX_OCTET_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary +}; + +static const struct ldb_schema_attribute ldb_attribute_default = { + .name = NULL, + .flags = 0, + .syntax = &ldb_syntax_default +}; + +/* + return the attribute handlers for a given attribute +*/ +static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal( + struct ldb_context *ldb, + const char *name) +{ + /* for binary search we need signed variables */ + unsigned int i, e, b = 0; + int r; + const struct ldb_schema_attribute *def = &ldb_attribute_default; + + /* as handlers are sorted, '*' must be the first if present */ + if (strcmp(ldb->schema.attributes[0].name, "*") == 0) { + def = &ldb->schema.attributes[0]; + b = 1; + } + + /* do a binary search on the array */ + e = ldb->schema.num_attributes - 1; + + while ((b <= e) && (e != (unsigned int) -1)) { + i = (b + e) / 2; + + r = ldb_attr_cmp(name, ldb->schema.attributes[i].name); + if (r == 0) { + return &ldb->schema.attributes[i]; + } + if (r < 0) { + e = i - 1; + } else { + b = i + 1; + } + } + + return def; +} + +/* + return the attribute handlers for a given attribute +*/ +const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, + const char *name) +{ + if (ldb->schema.attribute_handler_override) { + const struct ldb_schema_attribute *ret = + ldb->schema.attribute_handler_override(ldb, + ldb->schema.attribute_handler_override_private, + name); + if (ret) { + return ret; + } + } + + return ldb_schema_attribute_by_name_internal(ldb, name); +} + + +/* + add to the list of ldif handlers for this ldb context +*/ +void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name) +{ + const struct ldb_schema_attribute *a; + ptrdiff_t i; + + a = ldb_schema_attribute_by_name_internal(ldb, name); + if (a == NULL || a->name == NULL) { + return; + } + + /* FIXED attributes are never removed */ + if (a->flags & LDB_ATTR_FLAG_FIXED) { + return; + } + + if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { + talloc_free(discard_const_p(char, a->name)); + } + + i = a - ldb->schema.attributes; + if (i < ldb->schema.num_attributes - 1) { + memmove(&ldb->schema.attributes[i], + a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); + } + + ldb->schema.num_attributes--; +} + +/* + setup a attribute handler using a standard syntax +*/ +int ldb_schema_attribute_add(struct ldb_context *ldb, + const char *attribute, + unsigned flags, + const char *syntax) +{ + const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax); + return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s); +} + +/* + setup the attribute handles for well known attributes +*/ +int ldb_setup_wellknown_attributes(struct ldb_context *ldb) +{ + const struct { + const char *attr; + const char *syntax; + } wellknown[] = { + { "dn", LDB_SYNTAX_DN }, + { "distinguishedName", LDB_SYNTAX_DN }, + { "cn", LDB_SYNTAX_DIRECTORY_STRING }, + { "dc", LDB_SYNTAX_DIRECTORY_STRING }, + { "ou", LDB_SYNTAX_DIRECTORY_STRING }, + { "objectClass", LDB_SYNTAX_OBJECTCLASS } + }; + unsigned int i; + int ret; + + for (i=0;ischema.num_dn_extended_syntax + 1; + + a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, + struct ldb_dn_extended_syntax, n); + + if (!a) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a[ldb->schema.num_dn_extended_syntax] = *syntax; + ldb->schema.dn_extended_syntax = a; + + ldb->schema.num_dn_extended_syntax = n; + + return LDB_SUCCESS; +} + +/* + return the extended dn syntax for a given name +*/ +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name) +{ + unsigned int i; + for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { + if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { + return &ldb->schema.dn_extended_syntax[i]; + } + } + return NULL; +} + +/* + set an attribute handler override function - used to delegate schema handling + to external code + */ +void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, + ldb_attribute_handler_override_fn_t override, + void *private_data) +{ + ldb->schema.attribute_handler_override_private = private_data; + ldb->schema.attribute_handler_override = override; +} diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c new file mode 100644 index 00000000000..b3ef2434932 --- /dev/null +++ b/lib/ldb/common/ldb_controls.c @@ -0,0 +1,1043 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** 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_controls.c + * + * Component: ldb controls utility functions + * + * Description: helper functions for control modules + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" + +/* check if a control with the specified "oid" exist and return it */ +/* returns NULL if not found */ +struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) +{ + unsigned int i; + + if (req->controls != NULL) { + for (i = 0; req->controls[i]; i++) { + if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { + break; + } + } + + return req->controls[i]; + } + + return NULL; +} + +/* check if a control with the specified "oid" exist and return it */ +/* returns NULL if not found */ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) +{ + unsigned int i; + + if (rep->controls != NULL) { + for (i = 0; rep->controls[i]; i++) { + if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { + break; + } + } + + return rep->controls[i]; + } + + return NULL; +} + +/* + * Saves the current controls list into the "saver" (can also be NULL) and + * replace the one in "req" with a new one excluding the "exclude" control + * (if it is NULL then the list remains the same) + * + * Returns 0 on error. + */ +int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) +{ + struct ldb_control **lcs, **lcs_old; + unsigned int i, j; + + lcs_old = req->controls; + if (saver != NULL) { + *saver = lcs_old; + } + + for (i = 0; req->controls && req->controls[i]; i++); + if (i == 0) { + req->controls = NULL; + return 1; + } + + lcs = talloc_array(req, struct ldb_control *, i + 1); + if (!lcs) { + return 0; + } + + for (i = 0, j = 0; lcs_old[i]; i++) { + if (exclude == lcs_old[i]) continue; + lcs[j] = lcs_old[i]; + j++; + } + lcs[j] = NULL; + + req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); + if (req->controls == NULL) { + return 0; + } + return 1; +} + +/* + * Returns a list of controls, except the one specified with "exclude" (can + * also be NULL). Included controls become a child of returned list if they + * were children of "controls_in". + * + * Returns NULL on error (OOM) or an empty control list. + */ +struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, + TALLOC_CTX *mem_ctx, + struct ldb_control *exclude) +{ + struct ldb_control **lcs = NULL; + unsigned int i, j, n; + + for (i = 0; controls_in && controls_in[i]; i++); + if (i == 0) { + return NULL; + } + n = i; + + for (i = 0, j = 0; controls_in && controls_in[i]; i++) { + if (exclude == controls_in[i]) continue; + + if (!lcs) { + /* Allocate here so if we remove the only + * control, or there were no controls, we + * don't allocate at all, and just return + * NULL */ + lcs = talloc_array(mem_ctx, struct ldb_control *, + n + 1); + if (!lcs) { + return NULL; + } + } + + lcs[j] = controls_in[i]; + talloc_reparent(controls_in, lcs, lcs[j]); + j++; + } + if (lcs) { + lcs[j] = NULL; + + lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); + } + + return lcs; +} + +/* check if there's any control marked as critical in the list */ +/* return True if any, False if none */ +int ldb_check_critical_controls(struct ldb_control **controls) +{ + unsigned int i; + + if (controls == NULL) { + return 0; + } + + for (i = 0; controls[i]; i++) { + if (controls[i]->critical) { + return 1; + } + } + + return 0; +} + +int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) +{ + unsigned int i, n; + struct ldb_control **ctrls; + struct ldb_control *ctrl; + + for (n=0; req->controls && req->controls[n];n++) { + /* having two controls of the same OID makes no sense */ + if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + } + + ctrls = talloc_array(req, + struct ldb_control *, + n + 2); + if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; + + for (i=0; icontrols[i]; + } + + req->controls = ctrls; + ctrls[n] = NULL; + ctrls[n+1] = NULL; + + ctrl = talloc(ctrls, struct ldb_control); + if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; + ctrl->critical = critical; + ctrl->data = data; + + ctrls[n] = ctrl; + return LDB_SUCCESS; +} + +int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) +{ + unsigned n; + struct ldb_control **ctrls; + struct ldb_control *ctrl; + + for (n=0; ares->controls && ares->controls[n];) { + /* having two controls of the same OID makes no sense */ + if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + n++; + } + + ctrls = talloc_realloc(ares, ares->controls, + struct ldb_control *, + n + 2); + if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; + ares->controls = ctrls; + ctrls[n] = NULL; + ctrls[n+1] = NULL; + + ctrl = talloc(ctrls, struct ldb_control); + if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; + ctrl->critical = critical; + ctrl->data = data; + + ctrls[n] = ctrl; + return LDB_SUCCESS; +} + +/* Add a control to the request, replacing the old one if it is already in the request */ +int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) +{ + unsigned int n; + int ret; + + ret = ldb_request_add_control(req, oid, critical, data); + if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { + return ret; + } + + for (n=0; req->controls[n];n++) { + if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { + req->controls[n]->critical = critical; + req->controls[n]->data = data; + return LDB_SUCCESS; + } + } + + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + * Return a control as string + * the project (ie. name:value1:value2:...:valuen + * The string didn't include the criticity of the critical flag + */ +char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) +{ + char *res = NULL; + + if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { + struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); + char *cookie; + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + if (cookie[0] != '\0') { + res = talloc_asprintf(mem_ctx, "%s:%d:%s", + LDB_CONTROL_PAGED_RESULTS_NAME, + control->critical, + cookie); + + talloc_free(cookie); + } else { + res = talloc_asprintf(mem_ctx, "%s:%d", + LDB_CONTROL_PAGED_RESULTS_NAME, + control->critical); + } + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { + struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, + struct ldb_vlv_resp_control); + + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%d:%s", + LDB_CONTROL_VLV_RESP_NAME, + control->critical, + rep_control->targetPosition, + rep_control->contentCount, + rep_control->vlv_result, + rep_control->ctxid_len, + rep_control->contextId); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { + struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, + struct ldb_sort_resp_control); + + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", + LDB_CONTROL_SORT_RESP_NAME, + control->critical, + rep_control->result, + rep_control->attr_desc); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { + struct ldb_asq_control *rep_control = talloc_get_type(control->data, + struct ldb_asq_control); + + res = talloc_asprintf(mem_ctx, "%s:%d:%d", + LDB_CONTROL_SORT_RESP_NAME, + control->critical, + rep_control->result); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { + char *cookie; + struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, + struct ldb_dirsync_control); + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, + rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", + LDB_CONTROL_DIRSYNC_NAME, + control->critical, + rep_control->flags, + rep_control->max_attributes, + cookie); + + talloc_free(cookie); + return res; + } + + /* + * From here we don't know the control + */ + if (control->data == NULL) { + /* + * We don't know the control but there is no real data attached to it + * so we can represent it with local_oid:oid:criticity + */ + res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", + control->oid, + control->critical); + return res; + } + + res = talloc_asprintf(mem_ctx, "unknown oid:%s", + control->oid); + return res; +} + + +/* + * A little trick to allow to use constants defined in headers rather than + * hardwritten in the file hardwritten in the file + * sizeof will return the \0 char as well so it will take the place of ":" in the + * length of the string + */ +#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) + +/* Parse one string and return associated control if parsing is successful*/ +struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) +{ + struct ldb_control *ctrl; + char *error_string = NULL; + + if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { + ldb_oom(ldb); + return NULL; + } + + if (LDB_CONTROL_CMP(control_strings, + LDB_CONTROL_VLV_REQ_NAME) == 0) { + struct ldb_vlv_req_control *control; + const char *p; + char attr[1024]; + char ctxid[1024]; + int crit, bc, ac, os, cc, ret; + + attr[0] = '\0'; + ctxid[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); + ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); + if (ret < 5) { + ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); + } + + if ((ret < 4) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):[:ctxid(o)]\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, s = string, o = b64 binary blob"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + ctrl->oid = LDB_CONTROL_VLV_REQ_OID; + ctrl->critical = crit; + if (!(control = talloc(ctrl, + struct ldb_vlv_req_control))) { + ldb_oom(ldb); + return NULL; + } + control->beforeCount = bc; + control->afterCount = ac; + if (attr[0]) { + control->type = 1; + control->match.gtOrEq.value = talloc_strdup(control, attr); + control->match.gtOrEq.value_len = strlen(attr); + } else { + control->type = 0; + control->match.byOffset.offset = os; + control->match.byOffset.contentCount = cc; + } + if (ctxid[0]) { + control->ctxid_len = ldb_base64_decode(ctxid); + control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len); + } else { + control->ctxid_len = 0; + control->contextId = NULL; + } + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { + struct ldb_dirsync_control *control; + const char *p; + char cookie[1024]; + int crit, max_attrs, ret; + uint32_t flags; + + cookie[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); + ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); + + if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) { + error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + /* w2k3 seems to ignore the parameter, + * but w2k sends a wrong cookie when this value is to small + * this would cause looping forever, while getting + * the same data and same cookie forever + */ + if (max_attrs == 0) max_attrs = 0x0FFFFFFF; + + ctrl->oid = LDB_CONTROL_DIRSYNC_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_dirsync_control); + control->flags = flags; + control->max_attributes = max_attrs; + if (*cookie) { + control->cookie_len = ldb_base64_decode(cookie); + control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); + } else { + control->cookie = NULL; + control->cookie_len = 0; + } + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { + struct ldb_asq_control *control; + const char *p; + char attr[256]; + int crit, ret; + + attr[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); + ret = sscanf(p, "%d:%255[^$]", &crit, attr); + if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { + error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_ASQ_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_asq_control); + control->request = 1; + control->source_attribute = talloc_strdup(control, attr); + control->src_attr_len = strlen(attr); + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { + struct ldb_extended_dn_control *control; + const char *p; + int crit, type, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); + ret = sscanf(p, "%d:%d", &crit, &type); + if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean\n"); + error_string = talloc_asprintf_append(error_string, " i = integer\n"); + error_string = talloc_asprintf_append(error_string, " valid values are: 0 - hexadecimal representation\n"); + error_string = talloc_asprintf_append(error_string, " 1 - normal string representation"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + control = NULL; + } else { + control = talloc(ctrl, struct ldb_extended_dn_control); + control->type = type; + } + + ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; + ctrl->critical = crit; + ctrl->data = talloc_steal(ctrl, control); + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { + struct ldb_sd_flags_control *control; + const char *p; + int crit, ret; + unsigned secinfo_flags; + + p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); + ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); + if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) { + error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_sd_flags_control); + control->secinfo_flags = secinfo_flags; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { + struct ldb_search_options_control *control; + const char *p; + int crit, ret; + unsigned search_options; + + p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); + ret = sscanf(p, "%d:%u", &crit, &search_options); + if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) { + error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_search_options_control); + control->search_options = search_options; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid bypassopreational control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid relax control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RELAX_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid recalculate_sd control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { + struct ldb_paged_control *control; + const char *p; + int crit, size, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); + ret = sscanf(p, "%d:%d", &crit, &size); + if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) { + error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_paged_control); + control->size = size; + control->cookie = NULL; + control->cookie_len = 0; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { + struct ldb_server_sort_control **control; + const char *p; + char attr[256]; + char rule[128]; + int crit, rev, ret; + + attr[0] = '\0'; + rule[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); + ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); + if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { + error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; + ctrl->critical = crit; + control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); + control[0] = talloc(control, struct ldb_server_sort_control); + control[0]->attributeName = talloc_strdup(control, attr); + if (rule[0]) + control[0]->orderingRule = talloc_strdup(control, rule); + else + control[0]->orderingRule = NULL; + control[0]->reverse = rev; + control[1] = NULL; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid tree_delete control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid reveal_internals control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (strncmp(control_strings, "local_oid:", 10) == 0) { + const char *p; + int crit = 0, ret = 0; + char oid[256]; + + oid[0] = '\0'; + p = &(control_strings[10]); + ret = sscanf(p, "%64[^:]:%d", oid, &crit); + + if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid local_oid control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: oid(s):crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) { + ldb_oom(ldb); + return NULL; + } + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid rodc_join control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + error_string = talloc_asprintf(mem_ctx, "invalid provision control syntax\n"); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PROVISION_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + /* + * When no matching control has been found. + */ + return NULL; +} + +/* + * A little trick to allow to use constants defined in headers rather than + * hardwritten in the file hardwritten in the file + * sizeof will return the \0 char as well so it will take the place of ":" in the + * length of the string + */ +#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) + +/* Parse controls from the format used on the command line and in ejs */ +struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) +{ + unsigned int i; + struct ldb_control **ctrl; + + if (control_strings == NULL || control_strings[0] == NULL) + return NULL; + + for (i = 0; control_strings[i]; i++); + + ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); + + ldb_reset_err_string(ldb); + for (i = 0; control_strings[i]; i++) { + ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); + if (ctrl[i] == NULL) { + if( ldb_errstring == NULL ) { + /* no controls matched, throw an error */ + ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); + } + talloc_free(ctrl); + return NULL; + } + } + + ctrl[i] = NULL; + + return ctrl; +} + + diff --git a/lib/ldb/common/ldb_debug.c b/lib/ldb/common/ldb_debug.c new file mode 100644 index 00000000000..6aa58ccf71f --- /dev/null +++ b/lib/ldb/common/ldb_debug.c @@ -0,0 +1,142 @@ +/* + 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 debug + * + * Description: functions for printing debug messages + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + this allows the user to choose their own debug function +*/ +int ldb_set_debug(struct ldb_context *ldb, + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap), + void *context) +{ + ldb->debug_ops.debug = debug; + ldb->debug_ops.context = context; + return 0; +} + +/* + debug function for ldb_set_debug_stderr +*/ +static void ldb_debug_stderr(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); +static void ldb_debug_stderr(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + if (level <= LDB_DEBUG_WARNING) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } +} + +static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); +static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); +} + +/* + convenience function to setup debug messages on stderr + messages of level LDB_DEBUG_WARNING and higher are printed +*/ +int ldb_set_debug_stderr(struct ldb_context *ldb) +{ + return ldb_set_debug(ldb, ldb_debug_stderr, ldb); +} + +/* + log a message +*/ +void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) +{ + va_list ap; + if (ldb->debug_ops.debug == NULL) { + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_set_debug(ldb, ldb_debug_stderr_all, ldb); + } else { + ldb_set_debug_stderr(ldb); + } + } + va_start(ap, fmt); + ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); + va_end(ap); +} + +/* + add to an accumulated log message + */ +void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (ldb->partial_debug == NULL) { + ldb->partial_debug = talloc_vasprintf(ldb, fmt, ap); + } else { + ldb->partial_debug = talloc_vasprintf_append(ldb->partial_debug, + fmt, ap); + } + va_end(ap); +} + +/* + send the accumulated log message, and free it + */ +void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level) +{ + ldb_debug(ldb, level, "%s", ldb->partial_debug); + talloc_free(ldb->partial_debug); + ldb->partial_debug = NULL; +} + +/* + log a message, and set the ldb error string to the same message +*/ +void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char *msg; + va_start(ap, fmt); + msg = talloc_vasprintf(ldb, fmt, ap); + va_end(ap); + if (msg != NULL) { + ldb_set_errstring(ldb, msg); + ldb_debug(ldb, level, "%s", msg); + } + talloc_free(msg); +} + diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c new file mode 100644 index 00000000000..cd9055da928 --- /dev/null +++ b/lib/ldb/common/ldb_dn.c @@ -0,0 +1,2101 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** 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 dn creation and manipulation utility functions + * + * Description: - explode a dn into it's own basic elements + * and put them in a structure (only if necessary) + * - manipulate ldb_dn structures + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" +#include + +#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed + +#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0) + +/** + internal ldb exploded dn structures +*/ +struct ldb_dn_component { + + char *name; + struct ldb_val value; + + char *cf_name; + struct ldb_val cf_value; +}; + +struct ldb_dn_ext_component { + + char *name; + struct ldb_val value; +}; + +struct ldb_dn { + + struct ldb_context *ldb; + + /* Special DNs are always linearized */ + bool special; + bool invalid; + + bool valid_case; + + char *linearized; + char *ext_linearized; + char *casefold; + + unsigned int comp_num; + struct ldb_dn_component *components; + + unsigned int ext_comp_num; + struct ldb_dn_ext_component *ext_components; +}; + +/* it is helpful to be able to break on this in gdb */ +static void ldb_dn_mark_invalid(struct ldb_dn *dn) +{ + dn->invalid = true; +} + +/* strdn may be NULL */ +struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const struct ldb_val *strdn) +{ + struct ldb_dn *dn; + + if (! ldb) return NULL; + + if (strdn && strdn->data + && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { + /* The RDN must not contain a character with value 0x0 */ + return NULL; + } + + dn = talloc_zero(mem_ctx, struct ldb_dn); + LDB_DN_NULL_FAILED(dn); + + dn->ldb = talloc_get_type(ldb, struct ldb_context); + if (dn->ldb == NULL) { + /* the caller probably got the arguments to + ldb_dn_new() mixed up */ + talloc_free(dn); + return NULL; + } + + if (strdn->data && strdn->length) { + const char *data = (const char *)strdn->data; + size_t length = strdn->length; + + if (data[0] == '@') { + dn->special = true; + } + dn->ext_linearized = talloc_strndup(dn, data, length); + LDB_DN_NULL_FAILED(dn->ext_linearized); + + if (data[0] == '<') { + const char *p_save, *p = dn->ext_linearized; + do { + p_save = p; + p = strstr(p, ">;"); + if (p) { + p = p + 2; + } + } while (p); + + if (p_save == dn->ext_linearized) { + dn->linearized = talloc_strdup(dn, ""); + } else { + dn->linearized = talloc_strdup(dn, p_save); + } + LDB_DN_NULL_FAILED(dn->linearized); + } else { + dn->linearized = dn->ext_linearized; + dn->ext_linearized = NULL; + } + } else { + dn->linearized = talloc_strdup(dn, ""); + LDB_DN_NULL_FAILED(dn->linearized); + } + + return dn; + +failed: + talloc_free(dn); + return NULL; +} + +/* strdn may be NULL */ +struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *strdn) +{ + struct ldb_val blob; + blob.data = discard_const_p(uint8_t, strdn); + blob.length = strdn ? strlen(strdn) : 0; + return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); +} + +struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *new_fmt, ...) +{ + char *strdn; + va_list ap; + + if ( (! mem_ctx) || (! ldb)) return NULL; + + va_start(ap, new_fmt); + strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); + va_end(ap); + + if (strdn) { + struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); + talloc_free(strdn); + return dn; + } + + return NULL; +} + +/* see RFC2253 section 2.4 */ +static int ldb_dn_escape_internal(char *dst, const char *src, int len) +{ + const char *p, *s; + char *d; + size_t l; + + p = s = src; + d = dst; + + while (p - src < len) { + p += strcspn(p, ",=\n\r+<>#;\\\" "); + + if (p - src == len) /* found no escapable chars */ + break; + + /* copy the part of the string before the stop */ + memcpy(d, s, p - s); + d += (p - s); /* move to current position */ + + switch (*p) { + case ' ': + if (p == src || (p-src)==(len-1)) { + /* if at the beginning or end + * of the string then escape */ + *d++ = '\\'; + *d++ = *p++; + } else { + /* otherwise don't escape */ + *d++ = *p++; + } + break; + + case '#': + /* despite the RFC, windows escapes a # + anywhere in the string */ + case ',': + case '+': + case '"': + case '\\': + case '<': + case '>': + case '?': + /* these must be escaped using \c form */ + *d++ = '\\'; + *d++ = *p++; + break; + + default: { + /* any others get \XX form */ + unsigned char v; + const char *hexbytes = "0123456789ABCDEF"; + v = *(const unsigned char *)p; + *d++ = '\\'; + *d++ = hexbytes[v>>4]; + *d++ = hexbytes[v&0xF]; + p++; + break; + } + } + s = p; /* move forward */ + } + + /* copy the last part (with zero) and return */ + l = len - (s - src); + memcpy(d, s, l + 1); + + /* return the length of the resulting string */ + return (l + (d - dst)); +} + +char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) +{ + char *dst; + + if (!value.length) + return NULL; + + /* allocate destination string, it will be at most 3 times the source */ + dst = talloc_array(mem_ctx, char, value.length * 3 + 1); + if ( ! dst) { + talloc_free(dst); + return NULL; + } + + ldb_dn_escape_internal(dst, (const char *)value.data, value.length); + + dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1); + + return dst; +} + +/* + explode a DN string into a ldb_dn structure + based on RFC4514 except that we don't support multiple valued RDNs + + TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints + DN must be compliant with RFC2253 +*/ +static bool ldb_dn_explode(struct ldb_dn *dn) +{ + char *p, *ex_name, *ex_value, *data, *d, *dt, *t; + bool trim = true; + bool in_extended = true; + bool in_ex_name = false; + bool in_ex_value = false; + bool in_attr = false; + bool in_value = false; + bool in_quote = false; + bool is_oid = false; + bool escape = false; + unsigned int x; + size_t l; + int ret; + char *parse_dn; + bool is_index; + + if ( ! dn || dn->invalid) return false; + + if (dn->components) { + return true; + } + + if (dn->ext_linearized) { + parse_dn = dn->ext_linearized; + } else { + parse_dn = dn->linearized; + } + + if ( ! parse_dn ) { + return false; + } + + is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); + + /* Empty DNs */ + if (parse_dn[0] == '\0') { + return true; + } + + /* Special DNs case */ + if (dn->special) { + return true; + } + + /* make sure we free this if allocated previously before replacing */ + LDB_FREE(dn->components); + dn->comp_num = 0; + + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + /* in the common case we have 3 or more components */ + /* make sure all components are zeroed, other functions depend on it */ + dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); + if ( ! dn->components) { + return false; + } + + /* Components data space is allocated here once */ + data = talloc_array(dn->components, char, strlen(parse_dn) + 1); + if (!data) { + return false; + } + + p = parse_dn; + t = NULL; + d = dt = data; + + while (*p) { + if (in_extended) { + + if (!in_ex_name && !in_ex_value) { + + if (p[0] == '<') { + p++; + ex_name = d; + in_ex_name = true; + continue; + } else if (p[0] == '\0') { + p++; + continue; + } else { + in_extended = false; + in_attr = true; + dt = d; + + continue; + } + } + + if (in_ex_name && *p == '=') { + *d++ = '\0'; + p++; + ex_value = d; + in_ex_name = false; + in_ex_value = true; + continue; + } + + if (in_ex_value && *p == '>') { + const struct ldb_dn_extended_syntax *ext_syntax; + struct ldb_val ex_val = { + .data = (uint8_t *)ex_value, + .length = d - ex_value + }; + + *d++ = '\0'; + p++; + in_ex_value = false; + + /* Process name and ex_value */ + + dn->ext_components = talloc_realloc(dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num + 1); + if ( ! dn->ext_components) { + /* ouch ! */ + goto failed; + } + + ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); + if (!ext_syntax) { + /* We don't know about this type of extended DN */ + goto failed; + } + + dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name); + if (!dn->ext_components[dn->ext_comp_num].name) { + /* ouch */ + goto failed; + } + ret = ext_syntax->read_fn(dn->ldb, dn->ext_components, + &ex_val, &dn->ext_components[dn->ext_comp_num].value); + if (ret != LDB_SUCCESS) { + ldb_dn_mark_invalid(dn); + goto failed; + } + + dn->ext_comp_num++; + + if (*p == '\0') { + /* We have reached the end (extended component only)! */ + talloc_free(data); + return true; + + } else if (*p == ';') { + p++; + continue; + } else { + ldb_dn_mark_invalid(dn); + goto failed; + } + } + + *d++ = *p++; + continue; + } + if (in_attr) { + if (trim) { + if (*p == ' ') { + p++; + continue; + } + + /* first char */ + trim = false; + + if (!isascii(*p)) { + /* attr names must be ascii only */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (isdigit(*p)) { + is_oid = true; + } else + if ( ! isalpha(*p)) { + /* not a digit nor an alpha, + * invalid attribute name */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + /* Copy this character across from parse_dn, + * now we have trimmed out spaces */ + *d++ = *p++; + continue; + } + + if (*p == ' ') { + p++; + /* valid only if we are at the end */ + trim = true; + continue; + } + + if (trim && (*p != '=')) { + /* spaces/tabs are not allowed */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (*p == '=') { + /* attribute terminated */ + in_attr = false; + in_value = true; + trim = true; + l = 0; + + /* Terminate this string in d + * (which is a copy of parse_dn + * with spaces trimmed) */ + *d++ = '\0'; + dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); + if ( ! dn->components[dn->comp_num].name) { + /* ouch */ + goto failed; + } + + dt = d; + + p++; + continue; + } + + if (!isascii(*p)) { + /* attr names must be ascii only */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) { + /* not a digit nor a dot, + * invalid attribute oid */ + ldb_dn_mark_invalid(dn); + goto failed; + } else + if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { + /* not ALPHA, DIGIT or HYPHEN */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + *d++ = *p++; + continue; + } + + if (in_value) { + if (in_quote) { + if (*p == '\"') { + if (p[-1] != '\\') { + p++; + in_quote = false; + continue; + } + } + *d++ = *p++; + l++; + continue; + } + + if (trim) { + if (*p == ' ') { + p++; + continue; + } + + /* first char */ + trim = false; + + if (*p == '\"') { + in_quote = true; + p++; + continue; + } + } + + switch (*p) { + + /* TODO: support ber encoded values + case '#': + */ + + case ',': + if (escape) { + *d++ = *p++; + l++; + escape = false; + continue; + } + /* ok found value terminator */ + + if ( t ) { + /* trim back */ + d -= (p - t); + l -= (p - t); + } + + in_attr = true; + in_value = false; + trim = true; + + p++; + *d++ = '\0'; + dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt); + dn->components[dn->comp_num].value.length = l; + if ( ! dn->components[dn->comp_num].value.data) { + /* ouch ! */ + goto failed; + } + + dt = d; + + dn->comp_num++; + if (dn->comp_num > 2) { + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + dn->comp_num + 1); + if ( ! dn->components) { + /* ouch ! */ + goto failed; + } + /* make sure all components are zeroed, other functions depend on this */ + memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component)); + } + + continue; + + case '+': + case '=': + /* to main compatibility with earlier + versions of ldb indexing, we have to + accept the base64 encoded binary index + values, which contain a '+' or '=' + which should normally be escaped */ + if (is_index) { + if ( t ) t = NULL; + *d++ = *p++; + l++; + break; + } + /* fall through */ + case '\"': + case '<': + case '>': + case ';': + /* a string with not escaped specials is invalid (tested) */ + if ( ! escape) { + ldb_dn_mark_invalid(dn); + goto failed; + } + escape = false; + + *d++ = *p++; + l++; + + if ( t ) t = NULL; + break; + + case '\\': + if ( ! escape) { + escape = true; + p++; + continue; + } + escape = false; + + *d++ = *p++; + l++; + + if ( t ) t = NULL; + break; + + default: + if (escape) { + if (isxdigit(p[0]) && isxdigit(p[1])) { + if (sscanf(p, "%02x", &x) != 1) { + /* invalid escaping sequence */ + ldb_dn_mark_invalid(dn); + goto failed; + } + p += 2; + *d++ = (unsigned char)x; + } else { + *d++ = *p++; + } + + escape = false; + l++; + if ( t ) t = NULL; + break; + } + + if (*p == ' ') { + if ( ! t) t = p; + } else { + if ( t ) t = NULL; + } + + *d++ = *p++; + l++; + + break; + } + + } + } + + if (in_attr || in_quote) { + /* invalid dn */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + /* save last element */ + if ( t ) { + /* trim back */ + d -= (p - t); + l -= (p - t); + } + + *d++ = '\0'; + dn->components[dn->comp_num].value.length = l; + dn->components[dn->comp_num].value.data = + (uint8_t *)talloc_strdup(dn->components, dt); + if ( ! dn->components[dn->comp_num].value.data) { + /* ouch */ + goto failed; + } + + dn->comp_num++; + + talloc_free(data); + return true; + +failed: + LDB_FREE(dn->components); /* "data" is implicitly free'd */ + dn->comp_num = 0; + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return false; +} + +bool ldb_dn_validate(struct ldb_dn *dn) +{ + return ldb_dn_explode(dn); +} + +const char *ldb_dn_get_linearized(struct ldb_dn *dn) +{ + unsigned int i; + size_t len; + char *d, *n; + + if ( ! dn || ( dn->invalid)) return NULL; + + if (dn->linearized) return dn->linearized; + + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return NULL; + } + + if (dn->comp_num == 0) { + dn->linearized = talloc_strdup(dn, ""); + if ( ! dn->linearized) return NULL; + return dn->linearized; + } + + /* calculate maximum possible length of DN */ + for (len = 0, i = 0; i < dn->comp_num; i++) { + /* name len */ + len += strlen(dn->components[i].name); + /* max escaped data len */ + len += (dn->components[i].value.length * 3); + len += 2; /* '=' and ',' */ + } + dn->linearized = talloc_array(dn, char, len); + if ( ! dn->linearized) return NULL; + + d = dn->linearized; + + for (i = 0; i < dn->comp_num; i++) { + + /* copy the name */ + n = dn->components[i].name; + while (*n) *d++ = *n++; + + *d++ = '='; + + /* and the value */ + d += ldb_dn_escape_internal( d, + (char *)dn->components[i].value.data, + dn->components[i].value.length); + *d++ = ','; + } + + *(--d) = '\0'; + + /* don't waste more memory than necessary */ + dn->linearized = talloc_realloc(dn, dn->linearized, + char, (d - dn->linearized + 1)); + + return dn->linearized; +} + +static int ldb_dn_extended_component_compare(const void *p1, const void *p2) +{ + const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; + const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; + return strcmp(ec1->name, ec2->name); +} + +char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) +{ + const char *linearized = ldb_dn_get_linearized(dn); + char *p = NULL; + unsigned int i; + + if (!linearized) { + return NULL; + } + + if (!ldb_dn_has_extended(dn)) { + return talloc_strdup(mem_ctx, linearized); + } + + if (!ldb_dn_validate(dn)) { + return NULL; + } + + /* sort the extended components by name. The idea is to make + * the resulting DNs consistent, plus to ensure that we put + * 'DELETED' first, so it can be very quickly recognised + */ + TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, + ldb_dn_extended_component_compare); + + for (i = 0; i < dn->ext_comp_num; i++) { + const struct ldb_dn_extended_syntax *ext_syntax; + const char *name = dn->ext_components[i].name; + struct ldb_val ec_val = dn->ext_components[i].value; + struct ldb_val val; + int ret; + + ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); + if (!ext_syntax) { + return NULL; + } + + if (mode == 1) { + ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx, + &ec_val, &val); + } else if (mode == 0) { + ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx, + &ec_val, &val); + } else { + ret = -1; + } + + if (ret != LDB_SUCCESS) { + return NULL; + } + + if (i == 0) { + p = talloc_asprintf(mem_ctx, "<%s=%s>", + name, val.data); + } else { + p = talloc_asprintf_append_buffer(p, ";<%s=%s>", + name, val.data); + } + + talloc_free(val.data); + + if (!p) { + return NULL; + } + } + + if (dn->ext_comp_num && *linearized) { + p = talloc_asprintf_append_buffer(p, ";%s", linearized); + } + + if (!p) { + return NULL; + } + + return p; +} + +/* + filter out all but an acceptable list of extended DN components + */ +void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) +{ + unsigned int i; + for (i=0; iext_comp_num; i++) { + if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { + memmove(&dn->ext_components[i], + &dn->ext_components[i+1], + (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); + dn->ext_comp_num--; + i--; + } + } + LDB_FREE(dn->ext_linearized); +} + + +char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); +} + +/* + casefold a dn. We need to casefold the attribute names, and canonicalize + attribute values of case insensitive attributes. +*/ + +static bool ldb_dn_casefold_internal(struct ldb_dn *dn) +{ + unsigned int i; + int ret; + + if ( ! dn || dn->invalid) return false; + + if (dn->valid_case) return true; + + if (( ! dn->components) && ( ! ldb_dn_explode(dn))) { + return false; + } + + for (i = 0; i < dn->comp_num; i++) { + const struct ldb_schema_attribute *a; + + dn->components[i].cf_name = + ldb_attr_casefold(dn->components, + dn->components[i].name); + if (!dn->components[i].cf_name) { + goto failed; + } + + a = ldb_schema_attribute_by_name(dn->ldb, + dn->components[i].cf_name); + + ret = a->syntax->canonicalise_fn(dn->ldb, dn->components, + &(dn->components[i].value), + &(dn->components[i].cf_value)); + if (ret != 0) { + goto failed; + } + } + + dn->valid_case = true; + + return true; + +failed: + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + return false; +} + +const char *ldb_dn_get_casefold(struct ldb_dn *dn) +{ + unsigned int i; + size_t len; + char *d, *n; + + if (dn->casefold) return dn->casefold; + + if (dn->special) { + dn->casefold = talloc_strdup(dn, dn->linearized); + if (!dn->casefold) return NULL; + dn->valid_case = true; + return dn->casefold; + } + + if ( ! ldb_dn_casefold_internal(dn)) { + return NULL; + } + + if (dn->comp_num == 0) { + dn->casefold = talloc_strdup(dn, ""); + return dn->casefold; + } + + /* calculate maximum possible length of DN */ + for (len = 0, i = 0; i < dn->comp_num; i++) { + /* name len */ + len += strlen(dn->components[i].cf_name); + /* max escaped data len */ + len += (dn->components[i].cf_value.length * 3); + len += 2; /* '=' and ',' */ + } + dn->casefold = talloc_array(dn, char, len); + if ( ! dn->casefold) return NULL; + + d = dn->casefold; + + for (i = 0; i < dn->comp_num; i++) { + + /* copy the name */ + n = dn->components[i].cf_name; + while (*n) *d++ = *n++; + + *d++ = '='; + + /* and the value */ + d += ldb_dn_escape_internal( d, + (char *)dn->components[i].cf_value.data, + dn->components[i].cf_value.length); + *d++ = ','; + } + *(--d) = '\0'; + + /* don't waste more memory than necessary */ + dn->casefold = talloc_realloc(dn, dn->casefold, + char, strlen(dn->casefold) + 1); + + return dn->casefold; +} + +char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); +} + +/* Determine if dn is below base, in the ldap tree. Used for + * evaluating a subtree search. + * 0 if they match, otherwise non-zero + */ + +int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn) +{ + int ret; + unsigned int n_base, n_dn; + + if ( ! base || base->invalid) return 1; + if ( ! dn || dn->invalid) return -1; + + if (( ! base->valid_case) || ( ! dn->valid_case)) { + if (base->linearized && dn->linearized) { + /* try with a normal compare first, if we are lucky + * we will avoid exploding and casfolding */ + int dif; + dif = strlen(dn->linearized) - strlen(base->linearized); + if (dif < 0) { + return dif; + } + if (strcmp(base->linearized, + &dn->linearized[dif]) == 0) { + return 0; + } + } + + if ( ! ldb_dn_casefold_internal(base)) { + return 1; + } + + if ( ! ldb_dn_casefold_internal(dn)) { + return -1; + } + + } + + /* if base has more components, + * they don't have the same base */ + if (base->comp_num > dn->comp_num) { + return (dn->comp_num - base->comp_num); + } + + if ((dn->comp_num == 0) || (base->comp_num == 0)) { + if (dn->special && base->special) { + return strcmp(base->linearized, dn->linearized); + } else if (dn->special) { + return -1; + } else if (base->special) { + return 1; + } else { + return 0; + } + } + + n_base = base->comp_num - 1; + n_dn = dn->comp_num - 1; + + while (n_base != (unsigned int) -1) { + char *b_name = base->components[n_base].cf_name; + char *dn_name = dn->components[n_dn].cf_name; + + char *b_vdata = (char *)base->components[n_base].cf_value.data; + char *dn_vdata = (char *)dn->components[n_dn].cf_value.data; + + size_t b_vlen = base->components[n_base].cf_value.length; + size_t dn_vlen = dn->components[n_dn].cf_value.length; + + /* compare attr names */ + ret = strcmp(b_name, dn_name); + if (ret != 0) return ret; + + /* compare attr.cf_value. */ + if (b_vlen != dn_vlen) { + return b_vlen - dn_vlen; + } + ret = strcmp(b_vdata, dn_vdata); + if (ret != 0) return ret; + + n_base--; + n_dn--; + } + + return 0; +} + +/* compare DNs using casefolding compare functions. + + If they match, then return 0 + */ + +int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) +{ + unsigned int i; + int ret; + + if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { + return -1; + } + + if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { + if (dn0->linearized && dn1->linearized) { + /* try with a normal compare first, if we are lucky + * we will avoid exploding and casfolding */ + if (strcmp(dn0->linearized, dn1->linearized) == 0) { + return 0; + } + } + + if ( ! ldb_dn_casefold_internal(dn0)) { + return 1; + } + + if ( ! ldb_dn_casefold_internal(dn1)) { + return -1; + } + + } + + if (dn0->comp_num != dn1->comp_num) { + return (dn1->comp_num - dn0->comp_num); + } + + if (dn0->comp_num == 0) { + if (dn0->special && dn1->special) { + return strcmp(dn0->linearized, dn1->linearized); + } else if (dn0->special) { + return 1; + } else if (dn1->special) { + return -1; + } else { + return 0; + } + } + + for (i = 0; i < dn0->comp_num; i++) { + char *dn0_name = dn0->components[i].cf_name; + char *dn1_name = dn1->components[i].cf_name; + + char *dn0_vdata = (char *)dn0->components[i].cf_value.data; + char *dn1_vdata = (char *)dn1->components[i].cf_value.data; + + size_t dn0_vlen = dn0->components[i].cf_value.length; + size_t dn1_vlen = dn1->components[i].cf_value.length; + + /* compare attr names */ + ret = strcmp(dn0_name, dn1_name); + if (ret != 0) { + return ret; + } + + /* compare attr.cf_value. */ + if (dn0_vlen != dn1_vlen) { + return dn0_vlen - dn1_vlen; + } + ret = strcmp(dn0_vdata, dn1_vdata); + if (ret != 0) { + return ret; + } + } + + return 0; +} + +static struct ldb_dn_component ldb_dn_copy_component( + TALLOC_CTX *mem_ctx, + struct ldb_dn_component *src) +{ + struct ldb_dn_component dst; + + memset(&dst, 0, sizeof(dst)); + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + LDB_FREE(dst.value.data); + return dst; + } + + if (src->cf_value.data) { + dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); + if (dst.cf_value.data == NULL) { + LDB_FREE(dst.value.data); + LDB_FREE(dst.name); + return dst; + } + + dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); + if (dst.cf_name == NULL) { + LDB_FREE(dst.cf_name); + LDB_FREE(dst.value.data); + LDB_FREE(dst.name); + return dst; + } + } else { + dst.cf_value.data = NULL; + dst.cf_name = NULL; + } + + return dst; +} + +static struct ldb_dn_ext_component ldb_dn_ext_copy_component( + TALLOC_CTX *mem_ctx, + struct ldb_dn_ext_component *src) +{ + struct ldb_dn_ext_component dst; + + memset(&dst, 0, sizeof(dst)); + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + LDB_FREE(dst.value.data); + return dst; + } + + return dst; +} + +struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + if (!dn || dn->invalid) { + return NULL; + } + + new_dn = talloc_zero(mem_ctx, struct ldb_dn); + if ( !new_dn) { + return NULL; + } + + *new_dn = *dn; + + if (dn->components) { + unsigned int i; + + new_dn->components = + talloc_zero_array(new_dn, + struct ldb_dn_component, + dn->comp_num); + if ( ! new_dn->components) { + talloc_free(new_dn); + return NULL; + } + + for (i = 0; i < dn->comp_num; i++) { + new_dn->components[i] = + ldb_dn_copy_component(new_dn->components, + &dn->components[i]); + if ( ! new_dn->components[i].value.data) { + talloc_free(new_dn); + return NULL; + } + } + } + + if (dn->ext_components) { + unsigned int i; + + new_dn->ext_components = + talloc_zero_array(new_dn, + struct ldb_dn_ext_component, + dn->ext_comp_num); + if ( ! new_dn->ext_components) { + talloc_free(new_dn); + return NULL; + } + + for (i = 0; i < dn->ext_comp_num; i++) { + new_dn->ext_components[i] = + ldb_dn_ext_copy_component( + new_dn->ext_components, + &dn->ext_components[i]); + if ( ! new_dn->ext_components[i].value.data) { + talloc_free(new_dn); + return NULL; + } + } + } + + if (dn->casefold) { + new_dn->casefold = talloc_strdup(new_dn, dn->casefold); + if ( ! new_dn->casefold) { + talloc_free(new_dn); + return NULL; + } + } + + if (dn->linearized) { + new_dn->linearized = talloc_strdup(new_dn, dn->linearized); + if ( ! new_dn->linearized) { + talloc_free(new_dn); + return NULL; + } + } + + if (dn->ext_linearized) { + new_dn->ext_linearized = talloc_strdup(new_dn, + dn->ext_linearized); + if ( ! new_dn->ext_linearized) { + talloc_free(new_dn); + return NULL; + } + } + + return new_dn; +} + +/* modify the given dn by adding a base. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) +{ + const char *s; + char *t; + + if ( !base || base->invalid || !dn || dn->invalid) { + return false; + } + + if (dn->components) { + unsigned int i; + + if ( ! ldb_dn_validate(base)) { + return false; + } + + s = NULL; + if (dn->valid_case) { + if ( ! (s = ldb_dn_get_casefold(base))) { + return false; + } + } + + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + dn->comp_num + base->comp_num); + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return false; + } + + for (i = 0; i < base->comp_num; dn->comp_num++, i++) { + dn->components[dn->comp_num] = + ldb_dn_copy_component(dn->components, + &base->components[i]); + if (dn->components[dn->comp_num].value.data == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + + if (dn->casefold && s) { + if (*dn->casefold) { + t = talloc_asprintf(dn, "%s,%s", + dn->casefold, s); + } else { + t = talloc_strdup(dn, s); + } + LDB_FREE(dn->casefold); + dn->casefold = t; + } + } + + if (dn->linearized) { + + s = ldb_dn_get_linearized(base); + if ( ! s) { + return false; + } + + if (*dn->linearized) { + t = talloc_asprintf(dn, "%s,%s", + dn->linearized, s); + } else { + t = talloc_strdup(dn, s); + } + if ( ! t) { + ldb_dn_mark_invalid(dn); + return false; + } + LDB_FREE(dn->linearized); + dn->linearized = t; + } + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +/* modify the given dn by adding a base. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) +{ + struct ldb_dn *base; + char *base_str; + va_list ap; + bool ret; + + if ( !dn || dn->invalid) { + return false; + } + + va_start(ap, base_fmt); + base_str = talloc_vasprintf(dn, base_fmt, ap); + va_end(ap); + + if (base_str == NULL) { + return false; + } + + base = ldb_dn_new(base_str, dn->ldb, base_str); + + ret = ldb_dn_add_base(dn, base); + + talloc_free(base_str); + + return ret; +} + +/* modify the given dn by adding children elements. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) +{ + const char *s; + char *t; + + if ( !child || child->invalid || !dn || dn->invalid) { + return false; + } + + if (dn->components) { + unsigned int n; + unsigned int i, j; + + if (dn->comp_num == 0) { + return false; + } + + if ( ! ldb_dn_validate(child)) { + return false; + } + + s = NULL; + if (dn->valid_case) { + if ( ! (s = ldb_dn_get_casefold(child))) { + return false; + } + } + + n = dn->comp_num + child->comp_num; + + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + n); + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return false; + } + + for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; + i--, j--) { + dn->components[j] = dn->components[i]; + } + + for (i = 0; i < child->comp_num; i++) { + dn->components[i] = + ldb_dn_copy_component(dn->components, + &child->components[i]); + if (dn->components[i].value.data == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + + dn->comp_num = n; + + if (dn->casefold && s) { + t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); + LDB_FREE(dn->casefold); + dn->casefold = t; + } + } + + if (dn->linearized) { + if (dn->linearized[0] == '\0') { + return false; + } + + s = ldb_dn_get_linearized(child); + if ( ! s) { + return false; + } + + t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); + if ( ! t) { + ldb_dn_mark_invalid(dn); + return false; + } + LDB_FREE(dn->linearized); + dn->linearized = t; + } + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +/* modify the given dn by adding children elements. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) +{ + struct ldb_dn *child; + char *child_str; + va_list ap; + bool ret; + + if ( !dn || dn->invalid) { + return false; + } + + va_start(ap, child_fmt); + child_str = talloc_vasprintf(dn, child_fmt, ap); + va_end(ap); + + if (child_str == NULL) { + return false; + } + + child = ldb_dn_new(child_str, dn->ldb, child_str); + + ret = ldb_dn_add_child(dn, child); + + talloc_free(child_str); + + return ret; +} + +bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) +{ + unsigned int i; + + if ( ! ldb_dn_validate(dn)) { + return false; + } + + if (dn->comp_num < num) { + return false; + } + + /* free components */ + for (i = dn->comp_num - num; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + + dn->comp_num -= num; + + if (dn->valid_case) { + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) +{ + unsigned int i, j; + + if ( ! ldb_dn_validate(dn)) { + return false; + } + + if (dn->comp_num < num) { + return false; + } + + for (i = 0, j = num; j < dn->comp_num; i++, j++) { + if (i < num) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->components[i] = dn->components[j]; + } + + dn->comp_num -= num; + + if (dn->valid_case) { + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( !new_dn ) { + return NULL; + } + + if ( ! ldb_dn_remove_child_components(new_dn, 1)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Create a 'canonical name' string from a DN: + + ie dc=samba,dc=org -> samba.org/ + uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator + + There are two formats, + the EX format has the last '/' replaced with a newline (\n). + +*/ +static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { + unsigned int i; + TALLOC_CTX *tmpctx; + char *cracked = NULL; + const char *format = (ex_format ? "\n" : "/" ); + + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + + tmpctx = talloc_new(mem_ctx); + + /* Walk backwards down the DN, grabbing 'dc' components at first */ + for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { + if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { + break; + } + if (cracked) { + cracked = talloc_asprintf(tmpctx, "%s.%s", + ldb_dn_escape_value(tmpctx, + dn->components[i].value), + cracked); + } else { + cracked = ldb_dn_escape_value(tmpctx, + dn->components[i].value); + } + if (!cracked) { + goto done; + } + } + + /* Only domain components? Finish here */ + if (i == (unsigned int) -1) { + cracked = talloc_strdup_append_buffer(cracked, format); + talloc_steal(mem_ctx, cracked); + goto done; + } + + /* Now walk backwards appending remaining components */ + for (; i > 0; i--) { + cracked = talloc_asprintf_append_buffer(cracked, "/%s", + ldb_dn_escape_value(tmpctx, + dn->components[i].value)); + if (!cracked) { + goto done; + } + } + + /* Last one, possibly a newline for the 'ex' format */ + cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, + ldb_dn_escape_value(tmpctx, + dn->components[i].value)); + + talloc_steal(mem_ctx, cracked); +done: + talloc_free(tmpctx); + return cracked; +} + +/* Wrapper functions for the above, for the two different string formats */ +char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { + return ldb_dn_canonical(mem_ctx, dn, 0); + +} + +char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { + return ldb_dn_canonical(mem_ctx, dn, 1); +} + +int ldb_dn_get_comp_num(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return -1; + } + return dn->comp_num; +} + +int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return -1; + } + return dn->ext_comp_num; +} + +const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (num >= dn->comp_num) return NULL; + return dn->components[num].name; +} + +const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, + unsigned int num) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (num >= dn->comp_num) return NULL; + return &dn->components[num].value; +} + +const char *ldb_dn_get_rdn_name(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (dn->comp_num == 0) return NULL; + return dn->components[0].name; +} + +const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (dn->comp_num == 0) return NULL; + return &dn->components[0].value; +} + +int ldb_dn_set_component(struct ldb_dn *dn, int num, + const char *name, const struct ldb_val val) +{ + char *n; + struct ldb_val v; + + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_OTHER; + } + + if (num >= dn->comp_num) { + return LDB_ERR_OTHER; + } + + n = talloc_strdup(dn, name); + if ( ! n) { + return LDB_ERR_OTHER; + } + + v.length = val.length; + v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1); + if ( ! v.data) { + talloc_free(n); + return LDB_ERR_OTHER; + } + + talloc_free(dn->components[num].name); + talloc_free(dn->components[num].value.data); + dn->components[num].name = n; + dn->components[num].value = v; + + if (dn->valid_case) { + unsigned int i; + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return LDB_SUCCESS; +} + +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, + const char *name) +{ + unsigned int i; + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + for (i=0; i < dn->ext_comp_num; i++) { + if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { + return &dn->ext_components[i].value; + } + } + return NULL; +} + +int ldb_dn_set_extended_component(struct ldb_dn *dn, + const char *name, const struct ldb_val *val) +{ + struct ldb_dn_ext_component *p; + unsigned int i; + struct ldb_val v2; + + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_OTHER; + } + + if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) { + /* We don't know how to handle this type of thing */ + return LDB_ERR_INVALID_DN_SYNTAX; + } + + for (i=0; i < dn->ext_comp_num; i++) { + if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { + if (val) { + dn->ext_components[i].value = + ldb_val_dup(dn->ext_components, val); + + dn->ext_components[i].name = + talloc_strdup(dn->ext_components, name); + if (!dn->ext_components[i].name || + !dn->ext_components[i].value.data) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + if (i != (dn->ext_comp_num - 1)) { + memmove(&dn->ext_components[i], + &dn->ext_components[i+1], + ((dn->ext_comp_num-1) - i) * + sizeof(*dn->ext_components)); + } + dn->ext_comp_num--; + + dn->ext_components = talloc_realloc(dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num); + if (!dn->ext_components) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + } + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; + } + } + + if (val == NULL) { + /* removing a value that doesn't exist is not an error */ + return LDB_SUCCESS; + } + + v2 = *val; + + p = dn->ext_components + = talloc_realloc(dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num + 1); + if (!dn->ext_components) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + + p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); + p[dn->ext_comp_num].name = talloc_strdup(p, name); + + if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + dn->ext_components = p; + dn->ext_comp_num++; + + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; +} + +void ldb_dn_remove_extended_components(struct ldb_dn *dn) +{ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; +} + +bool ldb_dn_is_valid(struct ldb_dn *dn) +{ + if ( ! dn) return false; + return ! dn->invalid; +} + +bool ldb_dn_is_special(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + return dn->special; +} + +bool ldb_dn_has_extended(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true; + return dn->ext_comp_num != 0; +} + +bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) +{ + if ( ! dn || dn->invalid) return false; + return ! strcmp(dn->linearized, check); +} + +bool ldb_dn_is_null(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + if (ldb_dn_has_extended(dn)) return false; + if (dn->linearized && (dn->linearized[0] == '\0')) return true; + return false; +} + +/* + this updates dn->components, taking the components from ref_dn. + This is used by code that wants to update the DN path of a DN + while not impacting on the extended DN components + */ +int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) +{ + dn->components = talloc_realloc(dn, dn->components, + struct ldb_dn_component, ref_dn->comp_num); + if (!dn->components) { + return LDB_ERR_OPERATIONS_ERROR; + } + memcpy(dn->components, ref_dn->components, + sizeof(struct ldb_dn_component)*ref_dn->comp_num); + dn->comp_num = ref_dn->comp_num; + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; +} + +/* + minimise a DN. The caller must pass in a validated DN. + + If the DN has an extended component then only the first extended + component is kept, the DN string is stripped. + + The existing dn is modified + */ +bool ldb_dn_minimise(struct ldb_dn *dn) +{ + unsigned int i; + + if (!ldb_dn_validate(dn)) { + return false; + } + if (dn->ext_comp_num == 0) { + return true; + } + + /* free components */ + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->comp_num = 0; + dn->valid_case = false; + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* note that we don't free dn->components as this there are + * several places in ldb_dn.c that rely on it being non-NULL + * for an exploded DN + */ + + for (i = 1; i < dn->ext_comp_num; i++) { + LDB_FREE(dn->ext_components[i].name); + LDB_FREE(dn->ext_components[i].value.data); + } + dn->ext_comp_num = 1; + + dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); + if (dn->ext_components == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + + LDB_FREE(dn->ext_linearized); + + return true; +} diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c new file mode 100644 index 00000000000..63b797c4f3d --- /dev/null +++ b/lib/ldb/common/ldb_ldif.c @@ -0,0 +1,1026 @@ +/* + 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: ldif routines + * + * Description: ldif pack/unpack routines + * + * Author: Andrew Tridgell + */ + +/* + see RFC2849 for the LDIF format definition +*/ + +#include "ldb_private.h" +#include "system/locale.h" + +/* + +*/ +static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) +{ + struct stat statbuf; + char *buf; + int count, size, bytes; + int ret; + int f; + const char *fname = (const char *)value->data; + + if (strncmp(fname, "file://", 7) != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + fname += 7; + + f = open(fname, O_RDONLY); + if (f == -1) { + return -1; + } + + if (fstat(f, &statbuf) != 0) { + ret = -1; + goto done; + } + + if (statbuf.st_size == 0) { + ret = -1; + goto done; + } + + value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); + if (value->data == NULL) { + ret = -1; + goto done; + } + value->data[statbuf.st_size] = 0; + + count = 0; + size = statbuf.st_size; + buf = (char *)value->data; + while (count < statbuf.st_size) { + bytes = read(f, buf, size); + if (bytes == -1) { + talloc_free(value->data); + ret = -1; + goto done; + } + count += bytes; + buf += bytes; + size -= bytes; + } + + value->length = statbuf.st_size; + ret = statbuf.st_size; + +done: + close(f); + return ret; +} + +/* + this base64 decoder was taken from jitterbug (written by tridge). + we might need to replace it with a new version +*/ +int ldb_base64_decode(char *s) +{ + const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int bit_offset=0, byte_offset, idx, i, n; + uint8_t *d = (uint8_t *)s; + char *p=NULL; + + n=i=0; + + while (*s && (p=strchr(b64,*s))) { + idx = (int)(p - b64); + byte_offset = (i*6)/8; + bit_offset = (i*6)%8; + d[byte_offset] &= ~((1<<(8-bit_offset))-1); + if (bit_offset < 3) { + d[byte_offset] |= (idx << (2-bit_offset)); + n = byte_offset+1; + } else { + d[byte_offset] |= (idx >> (bit_offset-2)); + d[byte_offset+1] = 0; + d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; + n = byte_offset+2; + } + s++; i++; + } + if (bit_offset >= 3) { + n--; + } + + if (*s && !p) { + /* the only termination allowed */ + if (*s != '=') { + return -1; + } + } + + /* null terminate */ + d[n] = 0; + return n; +} + + +/* + encode as base64 + caller frees +*/ +char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) +{ + const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int bit_offset, byte_offset, idx, i; + const uint8_t *d = (const uint8_t *)buf; + int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; + char *out; + + out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); + if (!out) return NULL; + + for (i=0;i> (2-bit_offset)) & 0x3F; + } else { + idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; + if (byte_offset+1 < len) { + idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); + } + } + out[i] = b64[idx]; + } + + for (;idata; + + if (val->length == 0) { + return 0; + } + + if (p[0] == ' ' || p[0] == ':') { + return 1; + } + + for (i=0; ilength; i++) { + if (!isprint(p[i]) || p[i] == '\n') { + return 1; + } + } + return 0; +} + +/* this macro is used to handle the return checking on fprintf_fn() */ +#define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) + +/* + write a line folded string onto a file +*/ +static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, + const char *buf, size_t length, int start_pos) +{ + size_t i; + int total=0, ret; + + for (i=0;imsg; + p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); + ret = fprintf_fn(private_data, "dn: %s\n", p); + talloc_free(p); + CHECK_RET; + + if (ldif->changetype != LDB_CHANGETYPE_NONE) { + for (i=0;ldb_changetypes[i].name;i++) { + if (ldb_changetypes[i].changetype == ldif->changetype) { + break; + } + } + if (!ldb_changetypes[i].name) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", + ldif->changetype); + talloc_free(mem_ctx); + return -1; + } + ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); + CHECK_RET; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + + if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + fprintf_fn(private_data, "add: %s\n", + msg->elements[i].name); + break; + case LDB_FLAG_MOD_DELETE: + fprintf_fn(private_data, "delete: %s\n", + msg->elements[i].name); + break; + case LDB_FLAG_MOD_REPLACE: + fprintf_fn(private_data, "replace: %s\n", + msg->elements[i].name); + break; + } + } + + for (j=0;jelements[i].num_values;j++) { + struct ldb_val v; + bool use_b64_encode; + ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); + if (ret != LDB_SUCCESS) { + v = msg->elements[i].values[j]; + } + use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY) + && ldb_should_b64_encode(ldb, &v); + if (ret != LDB_SUCCESS || use_b64_encode) { + ret = fprintf_fn(private_data, "%s:: ", + msg->elements[i].name); + CHECK_RET; + ret = base64_encode_f(ldb, fprintf_fn, private_data, + (char *)v.data, v.length, + strlen(msg->elements[i].name)+3); + CHECK_RET; + ret = fprintf_fn(private_data, "\n"); + CHECK_RET; + } else { + ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); + CHECK_RET; + if (ldb->flags & LDB_FLG_SHOW_BINARY) { + ret = fprintf_fn(private_data, "%*.*s", + v.length, v.length, (char *)v.data); + } else { + ret = fold_string(fprintf_fn, private_data, + (char *)v.data, v.length, + strlen(msg->elements[i].name)+2); + } + CHECK_RET; + ret = fprintf_fn(private_data, "\n"); + CHECK_RET; + } + if (v.data != msg->elements[i].values[j].data) { + talloc_free(v.data); + } + } + if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { + fprintf_fn(private_data, "-\n"); + } + } + ret = fprintf_fn(private_data,"\n"); + CHECK_RET; + + talloc_free(mem_ctx); + + return total; +} + +#undef CHECK_RET + + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(ldb, chunk, char, alloc_size); + if (!c2) { + talloc_free(chunk); + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + + +/* simple ldif attribute parser */ +static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) +{ + char *p; + int base64_encoded = 0; + int binary_file = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + if (*p == '<') { + binary_file = 1; + p++; + } + + *attr = *s; + + while (*p == ' ' || *p == '\t') { + p++; + } + + value->data = (uint8_t *)p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + int len = ldb_base64_decode((char *)value->data); + if (len == -1) { + /* it wasn't valid base64 data */ + return -1; + } + value->length = len; + } + + if (binary_file) { + int len = ldb_read_data_file(mem_ctx, value); + if (len == -1) { + /* an error occurred while trying to retrieve the file */ + return -1; + } + } + + return 0; +} + + +/* + free a message from a ldif_read +*/ +void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) +{ + talloc_free(ldif); +} + +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **_olddn, + struct ldb_dn **_newrdn, + bool *_deleteoldrdn, + struct ldb_dn **_newsuperior, + struct ldb_dn **_newdn) +{ + struct ldb_message *msg = ldif->msg; + struct ldb_val *newrdn_val = NULL; + struct ldb_val *deleteoldrdn_val = NULL; + struct ldb_val *newsuperior_val = NULL; + struct ldb_dn *olddn = NULL; + struct ldb_dn *newrdn = NULL; + bool deleteoldrdn = true; + struct ldb_dn *newsuperior = NULL; + struct ldb_dn *newdn = NULL; + struct ldb_val tmp_false; + struct ldb_val tmp_true; + bool ok; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + if (tmp_ctx == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Error: talloc_new() failed"); + goto err_op; + } + + if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: invalid changetype '%d'", + ldif->changetype); + goto err_other; + } + + if (msg->num_elements < 2) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] < 2", + msg->num_elements); + goto err_other; + } + + if (msg->num_elements > 3) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] > 3", + msg->num_elements); + goto err_other; + } + +#define CHECK_ELEMENT(i, _name, v, needed) do { \ + v = NULL; \ + if (msg->num_elements < (i + 1)) { \ + if (needed) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: num_elements[%u] < (%u + 1)", \ + msg->num_elements, i); \ + goto err_other; \ + } \ + } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].name[%s] != [%s]", \ + i, msg->elements[i].name, _name); \ + goto err_other; \ + } else if (msg->elements[i].flags != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].flags[0x%X} != [0x0]", \ + i, msg->elements[i].flags); \ + goto err_other; \ + } else if (msg->elements[i].num_values != 1) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].num_values[%u] != 1", \ + i, msg->elements[i].num_values); \ + goto err_other; \ + } else { \ + v = &msg->elements[i].values[0]; \ + } \ +} while (0) + + CHECK_ELEMENT(0, "newrdn", newrdn_val, true); + CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); + CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); + +#undef CHECK_ELEMENT + + olddn = ldb_dn_copy(tmp_ctx, msg->dn); + if (olddn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy olddn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_op; + } + + newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); + if (!ldb_dn_validate(newrdn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newrdn_val->data); + goto err_dn; + } + + tmp_false.length = 1; + tmp_false.data = discard_const_p(uint8_t, "0"); + tmp_true.length = 1; + tmp_true.data = discard_const_p(uint8_t, "1"); + if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { + deleteoldrdn = false; + } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { + deleteoldrdn = true; + } else { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: deleteoldrdn value invalid '%s' not '0'/'1'", + (char *)deleteoldrdn_val->data); + goto err_attr; + } + + if (newsuperior_val) { + newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); + if (!ldb_dn_validate(newsuperior)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newsuperior_val->data); + goto err_dn; + } + } else { + newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); + if (newsuperior == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to get parent dn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_dn; + } + } + + newdn = ldb_dn_copy(tmp_ctx, newrdn); + if (newdn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy newrdn '%s'", + ldb_dn_get_linearized(newrdn)); + goto err_op; + } + + ok = ldb_dn_add_base(newdn, newsuperior); + if (!ok) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to base '%s' to newdn '%s'", + ldb_dn_get_linearized(newsuperior), + ldb_dn_get_linearized(newdn)); + goto err_op; + } + + if (_olddn) { + *_olddn = talloc_move(mem_ctx, &olddn); + } + if (_newrdn) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } + if (_deleteoldrdn) { + *_deleteoldrdn = deleteoldrdn; + } + if (_newsuperior) { + if (newsuperior_val) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } else { + *_newrdn = NULL; + } + } + if (_newdn) { + *_newdn = talloc_move(mem_ctx, &newdn); + } + + talloc_free(tmp_ctx); + return LDB_SUCCESS; +err_other: + talloc_free(tmp_ctx); + return LDB_ERR_OTHER; +err_op: + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +err_attr: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; +err_dn: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_DN_SYNTAX; +} + +/* + read from a LDIF source, creating a ldb_message +*/ +struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data) +{ + struct ldb_ldif *ldif; + struct ldb_message *msg; + const char *attr=NULL; + char *chunk=NULL, *s; + struct ldb_val value; + unsigned flags = 0; + + value.data = NULL; + + ldif = talloc(ldb, struct ldb_ldif); + if (!ldif) return NULL; + + ldif->msg = talloc(ldif, struct ldb_message); + if (ldif->msg == NULL) { + talloc_free(ldif); + return NULL; + } + + ldif->changetype = LDB_CHANGETYPE_NONE; + msg = ldif->msg; + + msg->dn = NULL; + msg->elements = NULL; + msg->num_elements = 0; + + chunk = next_chunk(ldb, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + talloc_steal(ldif, chunk); + + s = chunk; + + if (next_attr(ldif, &s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (ldb_attr_cmp(attr, "dn") != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", + attr); + goto failed; + } + + msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); + + if ( ! ldb_dn_validate(msg->dn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", + (char *)value.data); + goto failed; + } + + while (next_attr(ldif, &s, &attr, &value) == 0) { + const struct ldb_schema_attribute *a; + struct ldb_message_element *el; + int ret, empty = 0; + + if (ldb_attr_cmp(attr, "changetype") == 0) { + int i; + for (i=0;ldb_changetypes[i].name;i++) { + if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { + ldif->changetype = ldb_changetypes[i].changetype; + break; + } + } + if (!ldb_changetypes[i].name) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Bad ldif changetype '%s'",(char *)value.data); + } + flags = 0; + continue; + } + + if (ldb_attr_cmp(attr, "add") == 0) { + flags = LDB_FLAG_MOD_ADD; + empty = 1; + } + if (ldb_attr_cmp(attr, "delete") == 0) { + flags = LDB_FLAG_MOD_DELETE; + empty = 1; + } + if (ldb_attr_cmp(attr, "replace") == 0) { + flags = LDB_FLAG_MOD_REPLACE; + empty = 1; + } + if (ldb_attr_cmp(attr, "-") == 0) { + flags = 0; + continue; + } + + if (empty) { + if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { + goto failed; + } + continue; + } + + el = &msg->elements[msg->num_elements-1]; + + a = ldb_schema_attribute_by_name(ldb, attr); + + if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && + flags == el->flags) { + /* its a continuation */ + el->values = + talloc_realloc(msg->elements, el->values, + struct ldb_val, el->num_values+1); + if (!el->values) { + goto failed; + } + ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]); + if (ret != 0) { + goto failed; + } + if (value.length == 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Attribute value cannot be empty for attribute '%s'", el->name); + goto failed; + } + if (value.data != el->values[el->num_values].data) { + talloc_steal(el->values, el->values[el->num_values].data); + } + el->num_values++; + } else { + /* its a new attribute */ + msg->elements = talloc_realloc(msg, msg->elements, + struct ldb_message_element, + msg->num_elements+1); + if (!msg->elements) { + goto failed; + } + el = &msg->elements[msg->num_elements]; + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr); + el->values = talloc(msg->elements, struct ldb_val); + if (!el->values || !el->name) { + goto failed; + } + el->num_values = 1; + ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]); + if (ret != 0) { + goto failed; + } + if (value.data != el->values[0].data) { + talloc_steal(el->values, el->values[0].data); + } + msg->num_elements++; + } + } + + if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { + int ret; + + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, + NULL, NULL, NULL, NULL, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + } + + return ldif; + +failed: + talloc_free(ldif); + return NULL; +} + + + +/* + a wrapper around ldif_read() for reading from FILE* +*/ +struct ldif_read_file_state { + FILE *f; +}; + +static int fgetc_file(void *private_data) +{ + struct ldif_read_file_state *state = + (struct ldif_read_file_state *)private_data; + return fgetc(state->f); +} + +struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) +{ + struct ldif_read_file_state state; + state.f = f; + return ldb_ldif_read(ldb, fgetc_file, &state); +} + + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = + (struct ldif_read_string_state *)private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) +{ + struct ldif_read_string_state state; + struct ldb_ldif *ldif; + state.s = *s; + ldif = ldb_ldif_read(ldb, fgetc_string, &state); + *s = state.s; + return ldif; +} + + +/* + wrapper around ldif_write() for a file +*/ +struct ldif_write_file_state { + FILE *f; +}; + +static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +static int fprintf_file(void *private_data, const char *fmt, ...) +{ + struct ldif_write_file_state *state = + (struct ldif_write_file_state *)private_data; + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(state->f, fmt, ap); + va_end(ap); + return ret; +} + +int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) +{ + struct ldif_write_file_state state; + state.f = f; + return ldb_ldif_write(ldb, fprintf_file, &state, ldif); +} + +/* + wrapper around ldif_write() for a string +*/ +struct ldif_write_string_state { + char *string; +}; + +static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +static int ldif_printf_string(void *private_data, const char *fmt, ...) +{ + struct ldif_write_string_state *state = + (struct ldif_write_string_state *)private_data; + va_list ap; + size_t oldlen = talloc_get_size(state->string); + va_start(ap, fmt); + + state->string = talloc_vasprintf_append(state->string, fmt, ap); + va_end(ap); + if (!state->string) { + return -1; + } + + return talloc_get_size(state->string) - oldlen; +} + +char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *ldif) +{ + struct ldif_write_string_state state; + state.string = talloc_strdup(mem_ctx, ""); + if (!state.string) { + return NULL; + } + if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { + return NULL; + } + return state.string; +} + +/* + convenient function to turn a ldb_message into a string. Useful for + debugging + */ +char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg) +{ + struct ldb_ldif ldif; + + ldif.changetype = changetype; + ldif.msg = discard_const_p(struct ldb_message, msg); + + return ldb_ldif_write_string(ldb, mem_ctx, &ldif); +} diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c new file mode 100644 index 00000000000..a42cf9449d3 --- /dev/null +++ b/lib/ldb/common/ldb_match.c @@ -0,0 +1,570 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Simo Sorce 2005 + + ** 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 expression matching + * + * Description: ldb expression matching + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + check if the scope matches in a search result +*/ +static int ldb_match_scope(struct ldb_context *ldb, + struct ldb_dn *base, + struct ldb_dn *dn, + enum ldb_scope scope) +{ + int ret = 0; + + if (base == NULL || dn == NULL) { + return 1; + } + + switch (scope) { + case LDB_SCOPE_BASE: + if (ldb_dn_compare(base, dn) == 0) { + ret = 1; + } + break; + + case LDB_SCOPE_ONELEVEL: + if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { + if (ldb_dn_compare_base(base, dn) == 0) { + ret = 1; + } + } + break; + + case LDB_SCOPE_SUBTREE: + default: + if (ldb_dn_compare_base(base, dn) == 0) { + ret = 1; + } + break; + } + + return ret; +} + + +/* + match if node is present +*/ +static int ldb_match_present(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + const struct ldb_schema_attribute *a; + struct ldb_message_element *el; + + if (ldb_attr_dn(tree->u.present.attr) == 0) { + *matched = true; + return LDB_SUCCESS; + } + + el = ldb_msg_find_element(msg, tree->u.present.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (a->syntax->operator_fn) { + unsigned int i; + for (i = 0; i < el->num_values; i++) { + int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + *matched = false; + return LDB_SUCCESS; + } + + *matched = true; + return LDB_SUCCESS; +} + +static int ldb_match_comparison(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, + enum ldb_parse_op comp_op, bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + + /* FIXME: APPROX comparison not handled yet */ + if (comp_op == LDB_OP_APPROX) { + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + el = ldb_msg_find_element(msg, tree->u.comparison.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + for (i = 0; i < el->num_values; i++) { + if (a->syntax->operator_fn) { + int ret; + ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } else { + int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); + + if (ret == 0) { + *matched = true; + return LDB_SUCCESS; + } + if (ret > 0 && comp_op == LDB_OP_GREATER) { + *matched = true; + return LDB_SUCCESS; + } + if (ret < 0 && comp_op == LDB_OP_LESS) { + *matched = true; + return LDB_SUCCESS; + } + } + } + + *matched = false; + return LDB_SUCCESS; +} + +/* + match a simple leaf node +*/ +static int ldb_match_equality(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, + bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + struct ldb_dn *valuedn; + int ret; + + if (ldb_attr_dn(tree->u.equality.attr) == 0) { + valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); + if (valuedn == NULL) { + return LDB_ERR_INVALID_DN_SYNTAX; + } + + ret = ldb_dn_compare(msg->dn, valuedn); + + talloc_free(valuedn); + + *matched = (ret == 0); + return LDB_SUCCESS; + } + + /* TODO: handle the "*" case derived from an extended search + operation without the attibute type defined */ + el = ldb_msg_find_element(msg, tree->u.equality.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (a == NULL) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + for (i=0;inum_values;i++) { + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &tree->u.equality.value, &el->values[i], matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } else { + if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, + &el->values[i]) == 0) { + *matched = true; + return LDB_SUCCESS; + } + } + } + + *matched = false; + return LDB_SUCCESS; +} + +static int ldb_wildcard_compare(struct ldb_context *ldb, + const struct ldb_parse_tree *tree, + const struct ldb_val value, bool *matched) +{ + const struct ldb_schema_attribute *a; + struct ldb_val val; + struct ldb_val cnk; + struct ldb_val *chunk; + char *p, *g; + uint8_t *save_p = NULL; + unsigned int c = 0; + + a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + save_p = val.data; + cnk.data = NULL; + + if ( ! tree->u.substring.start_with_wildcard ) { + + chunk = tree->u.substring.chunks[c]; + if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; + + /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ + if (cnk.length > val.length) { + goto mismatch; + } + if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; + val.length -= cnk.length; + val.data += cnk.length; + c++; + talloc_free(cnk.data); + cnk.data = NULL; + } + + while (tree->u.substring.chunks[c]) { + + chunk = tree->u.substring.chunks[c]; + if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; + + /* FIXME: case of embedded nulls */ + p = strstr((char *)val.data, (char *)cnk.data); + if (p == NULL) goto mismatch; + if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { + do { /* greedy */ + g = strstr((char *)p + cnk.length, (char *)cnk.data); + if (g) p = g; + } while(g); + } + val.length = val.length - (p - (char *)(val.data)) - cnk.length; + val.data = (uint8_t *)(p + cnk.length); + c++; + talloc_free(cnk.data); + cnk.data = NULL; + } + + /* last chunk may not have reached end of string */ + if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch; + talloc_free(save_p); + *matched = true; + return LDB_SUCCESS; + +mismatch: + *matched = false; + talloc_free(save_p); + talloc_free(cnk.data); + return LDB_SUCCESS; +} + +/* + match a simple leaf node +*/ +static int ldb_match_substring(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + + el = ldb_msg_find_element(msg, tree->u.substring.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + for (i = 0; i < el->num_values; i++) { + int ret; + ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + + *matched = false; + return LDB_SUCCESS; +} + + +/* + bitwise-and comparator +*/ +static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, + bool *matched) +{ + uint64_t i1, i2; + char ibuf[100]; + char *endptr = NULL; + + if (v1->length >= sizeof(ibuf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + memcpy(ibuf, (char *)v1->data, v1->length); + ibuf[v1->length] = 0; + i1 = strtoull(ibuf, &endptr, 0); + if (endptr != NULL) { + if (endptr == ibuf || *endptr != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + + if (v2->length >= sizeof(ibuf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + endptr = NULL; + memcpy(ibuf, (char *)v2->data, v2->length); + ibuf[v2->length] = 0; + i2 = strtoull(ibuf, &endptr, 0); + if (endptr != NULL) { + if (endptr == ibuf || *endptr != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { + *matched = ((i1 & i2) == i2); + } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { + *matched = ((i1 & i2) != 0); + } else { + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + return LDB_SUCCESS; +} + + +/* + extended match, handles things like bitops +*/ +static int ldb_match_extended(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + unsigned int i; + const struct { + const char *oid; + int (*comparator)(const char *, const struct ldb_val *, const struct ldb_val *, bool *); + } rules[] = { + { LDB_OID_COMPARATOR_AND, ldb_comparator_bitmask}, + { LDB_OID_COMPARATOR_OR, ldb_comparator_bitmask} + }; + int (*comp)(const char *,const struct ldb_val *, const struct ldb_val *, bool *) = NULL; + struct ldb_message_element *el; + + if (tree->u.extended.dnAttributes) { + /* FIXME: We really need to find out what this ":dn" part in + * an extended match means and how to handle it. For now print + * only a warning to have s3 winbind and other tools working + * against us. - Matthias */ + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); + } + if (tree->u.extended.rule_id == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + if (tree->u.extended.attr == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + for (i=0;iu.extended.rule_id) == 0) { + comp = rules[i].comparator; + break; + } + } + if (comp == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", + tree->u.extended.rule_id); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + /* find the message element */ + el = ldb_msg_find_element(msg, tree->u.extended.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + for (i=0;inum_values;i++) { + int ret = comp(tree->u.extended.rule_id, &el->values[i], &tree->u.extended.value, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + + *matched = false; + return LDB_SUCCESS; +} + +/* + return 0 if the given parse tree matches the given message. Assumes + the message is in sorted order + + return 1 if it matches, and 0 if it doesn't match + + this is a recursive function, and does short-circuit evaluation + */ +static int ldb_match_message(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + unsigned int i; + int ret; + + *matched = false; + + switch (tree->operation) { + case LDB_OP_AND: + for (i=0;iu.list.num_elements;i++) { + ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); + if (ret != LDB_SUCCESS) return ret; + if (!*matched) return LDB_SUCCESS; + } + *matched = true; + return LDB_SUCCESS; + + case LDB_OP_OR: + for (i=0;iu.list.num_elements;i++) { + ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + *matched = false; + return LDB_SUCCESS; + + case LDB_OP_NOT: + ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); + if (ret != LDB_SUCCESS) return ret; + *matched = ! *matched; + return LDB_SUCCESS; + + case LDB_OP_EQUALITY: + return ldb_match_equality(ldb, msg, tree, scope, matched); + + case LDB_OP_SUBSTRING: + return ldb_match_substring(ldb, msg, tree, scope, matched); + + case LDB_OP_GREATER: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); + + case LDB_OP_LESS: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); + + case LDB_OP_PRESENT: + return ldb_match_present(ldb, msg, tree, scope, matched); + + case LDB_OP_APPROX: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); + + case LDB_OP_EXTENDED: + return ldb_match_extended(ldb, msg, tree, scope, matched); + } + + return LDB_ERR_INAPPROPRIATE_MATCHING; +} + +int ldb_match_msg(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope) +{ + bool matched; + int ret; + + if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { + return 0; + } + + ret = ldb_match_message(ldb, msg, tree, scope, &matched); + if (ret != LDB_SUCCESS) { + /* to match the old API, we need to consider this a + failure to match */ + return 0; + } + return matched?1:0; +} + +int ldb_match_msg_error(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope, + bool *matched) +{ + if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { + *matched = false; + return LDB_SUCCESS; + } + + return ldb_match_message(ldb, msg, tree, scope, matched); +} + +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass) +{ + unsigned int i; + struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); + if (!el) { + return 0; + } + for (i=0; i < el->num_values; i++) { + if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { + return 1; + } + } + return 0; +} + + + diff --git a/lib/ldb/common/ldb_modules.c b/lib/ldb/common/ldb_modules.c new file mode 100644 index 00000000000..61d1901513a --- /dev/null +++ b/lib/ldb/common/ldb_modules.c @@ -0,0 +1,1146 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2004-2008 + + ** 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 modules core + * + * Description: core modules routines + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" +#include "dlinklist.h" +#include "system/dir.h" + +static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) +{ + size_t i, len; + char *trimmed; + + trimmed = talloc_strdup(mem_ctx, string); + if (!trimmed) { + return NULL; + } + + len = strlen(trimmed); + for (i = 0; trimmed[i] != '\0'; i++) { + switch (trimmed[i]) { + case ' ': + case '\t': + case '\n': + memmove(&trimmed[i], &trimmed[i + 1], len -i -1); + break; + } + } + + return trimmed; +} + + +/* modules are called in inverse order on the stack. + Lets place them as an admin would think the right order is. + Modules order is important */ +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) +{ + char **modules = NULL; + const char **m; + char *modstr, *p; + unsigned int i; + + /* spaces not admitted */ + modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); + if ( ! modstr) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); + return NULL; + } + + modules = talloc_realloc(mem_ctx, modules, char *, 2); + if ( ! modules ) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); + talloc_free(modstr); + return NULL; + } + talloc_steal(modules, modstr); + + if (modstr[0] == '\0') { + modules[0] = NULL; + m = (const char **)modules; + return m; + } + + i = 0; + /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ + while ((p = strrchr(modstr, ',')) != NULL) { + *p = '\0'; + p++; + modules[i] = p; + + i++; + modules = talloc_realloc(mem_ctx, modules, char *, i + 2); + if ( ! modules ) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); + return NULL; + } + + } + modules[i] = modstr; + + modules[i + 1] = NULL; + + m = (const char **)modules; + + return m; +} + +static struct backends_list_entry { + struct ldb_backend_ops *ops; + struct backends_list_entry *prev, *next; +} *ldb_backends = NULL; + +static struct ops_list_entry { + const struct ldb_module_ops *ops; + struct ops_list_entry *next; +} *registered_modules = NULL; + +static struct backends_list_entry *ldb_find_backend(const char *url_prefix) +{ + struct backends_list_entry *backend; + + for (backend = ldb_backends; backend; backend = backend->next) { + if (strcmp(backend->ops->name, url_prefix) == 0) { + return backend; + } + } + + return NULL; +} + +/* + register a new ldb backend + + if override is true, then override any existing backend for this prefix +*/ +int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) +{ + struct backends_list_entry *be; + + be = ldb_find_backend(url_prefix); + if (be) { + if (!override) { + return LDB_SUCCESS; + } + } else { + be = talloc_zero(ldb_backends, struct backends_list_entry); + if (!be) { + return LDB_ERR_OPERATIONS_ERROR; + } + be->ops = talloc_zero(be, struct ldb_backend_ops); + if (!be->ops) { + talloc_free(be); + return LDB_ERR_OPERATIONS_ERROR; + } + DLIST_ADD_END(ldb_backends, be, struct backends_list_entry); + } + + be->ops->name = url_prefix; + be->ops->connect_fn = connectfn; + + return LDB_SUCCESS; +} + +/* + Return the ldb module form of a database. + The URL can either be one of the following forms + ldb://path + ldapi://path + + flags is made up of LDB_FLG_* + + the options are passed uninterpreted to the backend, and are + backend specific. + + This allows modules to get at only the backend module, for example where a + module may wish to direct certain requests at a particular backend. +*/ +int ldb_module_connect_backend(struct ldb_context *ldb, + const char *url, + const char *options[], + struct ldb_module **backend_module) +{ + int ret; + char *backend; + struct backends_list_entry *be; + + if (strchr(url, ':') != NULL) { + backend = talloc_strndup(ldb, url, strchr(url, ':')-url); + } else { + /* Default to tdb */ + backend = talloc_strdup(ldb, "tdb"); + } + if (backend == NULL) { + return ldb_oom(ldb); + } + + be = ldb_find_backend(backend); + + talloc_free(backend); + + if (be == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); + return LDB_ERR_OTHER; + } + + ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); + + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Failed to connect to '%s' with backend '%s'", url, be->ops->name); + return ret; + } + return ret; +} + +static struct ldb_hooks { + struct ldb_hooks *next, *prev; + ldb_hook_fn hook_fn; +} *ldb_hooks; + +/* + register a ldb hook function + */ +int ldb_register_hook(ldb_hook_fn hook_fn) +{ + struct ldb_hooks *lc; + lc = talloc_zero(ldb_hooks, struct ldb_hooks); + if (lc == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + lc->hook_fn = hook_fn; + DLIST_ADD_END(ldb_hooks, lc, struct ldb_hooks); + return LDB_SUCCESS; +} + +/* + call ldb hooks of a given type + */ +int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) +{ + struct ldb_hooks *lc; + for (lc = ldb_hooks; lc; lc=lc->next) { + int ret = lc->hook_fn(ldb, t); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} + + +static const struct ldb_module_ops *ldb_find_module_ops(const char *name) +{ + struct ops_list_entry *e; + + for (e = registered_modules; e; e = e->next) { + if (strcmp(e->ops->name, name) == 0) + return e->ops; + } + + return NULL; +} + + +int ldb_register_module(const struct ldb_module_ops *ops) +{ + struct ops_list_entry *entry; + + if (ldb_find_module_ops(ops->name) != NULL) + return LDB_ERR_ENTRY_ALREADY_EXISTS; + + entry = talloc(talloc_autofree_context(), struct ops_list_entry); + if (entry == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + entry->ops = ops; + entry->next = registered_modules; + registered_modules = entry; + + return LDB_SUCCESS; +} + +/* + load a list of modules + */ +int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, + struct ldb_module *backend, struct ldb_module **out) +{ + struct ldb_module *module; + unsigned int i; + + module = backend; + + for (i = 0; module_list && module_list[i] != NULL; i++) { + struct ldb_module *current; + const struct ldb_module_ops *ops; + + if (strcmp(module_list[i], "") == 0) { + continue; + } + + ops = ldb_find_module_ops(module_list[i]); + + if (ops == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", + module_list[i]); + return LDB_ERR_OPERATIONS_ERROR; + } + + current = talloc_zero(ldb, struct ldb_module); + if (current == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + talloc_set_name(current, "ldb_module: %s", module_list[i]); + + current->ldb = ldb; + current->ops = ops; + + DLIST_ADD(module, current); + } + *out = module; + return LDB_SUCCESS; +} + +/* + initialise a chain of modules + */ +int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) +{ + while (module && module->ops->init_context == NULL) + module = module->next; + + /* init is different in that it is not an error if modules + * do not require initialization */ + + if (module) { + int ret = module->ops->init_context(module); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", + module->ops->name, ldb_strerror(ret)); + return ret; + } + } + + return LDB_SUCCESS; +} + +int ldb_load_modules(struct ldb_context *ldb, const char *options[]) +{ + const char *modules_string; + const char **modules = NULL; + int ret; + TALLOC_CTX *mem_ctx = talloc_new(ldb); + if (!mem_ctx) { + return ldb_oom(ldb); + } + + /* find out which modules we are requested to activate */ + + /* check if we have a custom module list passd as ldb option */ + if (options) { + modules_string = ldb_options_find(ldb, options, "modules"); + if (modules_string) { + modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); + } + } + + /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ + if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { + const char * const attrs[] = { "@LIST" , NULL}; + struct ldb_result *res = NULL; + struct ldb_dn *mods_dn; + + mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); + if (mods_dn == NULL) { + talloc_free(mem_ctx); + return ldb_oom(ldb); + } + + ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } else if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); + talloc_free(mem_ctx); + return ret; + } else { + const char *module_list; + if (res->count == 0) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } else if (res->count > 1) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%u), bailing out", res->count); + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } else { + module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); + if (!module_list) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } + modules = ldb_modules_list_from_string(ldb, mem_ctx, + module_list); + } + } + + talloc_free(mods_dn); + } + + if (modules != NULL) { + ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } else { + ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database"); + } + + ret = ldb_module_init_chain(ldb, ldb->modules); + talloc_free(mem_ctx); + return ret; +} + +/* + by using this we allow ldb modules to only implement the functions they care about, + which makes writing a module simpler, and makes it more likely to keep working + when ldb is extended +*/ +#define FIND_OP_NOERR(module, op) do { \ + module = module->next; \ + while (module && module->ops->op == NULL) module = module->next; \ + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ + module->ops->name); \ + } \ +} while (0) + +#define FIND_OP(module, op) do { \ + struct ldb_context *ldb = module->ldb; \ + FIND_OP_NOERR(module, op); \ + if (module == NULL) { \ + ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ + return LDB_ERR_OPERATIONS_ERROR; \ + } \ +} while (0) + + +struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, + struct ldb_context *ldb, + const char *module_name, + const struct ldb_module_ops *ops) +{ + struct ldb_module *module; + + module = talloc(memctx, struct ldb_module); + if (!module) { + ldb_oom(ldb); + return NULL; + } + talloc_set_name_const(module, module_name); + module->ldb = ldb; + module->prev = module->next = NULL; + module->ops = ops; + + return module; +} + +const char * ldb_module_get_name(struct ldb_module *module) +{ + return module->ops->name; +} + +struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) +{ + return module->ldb; +} + +const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) +{ + return module->ops; +} + +void *ldb_module_get_private(struct ldb_module *module) +{ + return module->private_data; +} + +void ldb_module_set_private(struct ldb_module *module, void *private_data) +{ + module->private_data = private_data; +} + +/* + helper functions to call the next module in chain +*/ + +int ldb_next_request(struct ldb_module *module, struct ldb_request *request) +{ + int ret; + + if (request->callback == NULL) { + ldb_set_errstring(module->ldb, "Requests MUST define callbacks"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + request->handle->nesting++; + + switch (request->operation) { + case LDB_SEARCH: + FIND_OP(module, search); + ret = module->ops->search(module, request); + break; + case LDB_ADD: + FIND_OP(module, add); + ret = module->ops->add(module, request); + break; + case LDB_MODIFY: + FIND_OP(module, modify); + ret = module->ops->modify(module, request); + break; + case LDB_DELETE: + FIND_OP(module, del); + ret = module->ops->del(module, request); + break; + case LDB_RENAME: + FIND_OP(module, rename); + ret = module->ops->rename(module, request); + break; + case LDB_EXTENDED: + FIND_OP(module, extended); + ret = module->ops->extended(module, request); + break; + default: + FIND_OP(module, request); + ret = module->ops->request(module, request); + break; + } + + request->handle->nesting--; + + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + + if (!(request->handle->flags & LDB_HANDLE_FLAG_DONE_CALLED)) { + /* It is _extremely_ common that a module returns a + * failure without calling ldb_module_done(), but that + * guarantees we will end up hanging in + * ldb_wait(). This fixes it without having to rewrite + * all our modules, and leaves us one less sharp + * corner for module developers to cut themselves on + */ + ret = ldb_module_done(request, NULL, NULL, ret); + } + return ret; +} + +int ldb_next_init(struct ldb_module *module) +{ + module = module->next; + + return ldb_module_init_chain(module->ldb, module); +} + +int ldb_next_start_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, start_transaction); + ret = module->ops->start_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_end_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, end_transaction); + ret = module->ops->end_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_prepare_commit(struct ldb_module *module) +{ + int ret; + FIND_OP_NOERR(module, prepare_commit); + if (module == NULL) { + /* we are allowed to have no prepare commit in + backends */ + return LDB_SUCCESS; + } + ret = module->ops->prepare_commit(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_del_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, del_transaction); + ret = module->ops->del_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) +{ + struct ldb_handle *h; + + h = talloc_zero(mem_ctx, struct ldb_handle); + if (h == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return NULL; + } + + h->status = LDB_SUCCESS; + h->state = LDB_ASYNC_INIT; + h->ldb = ldb; + h->flags = 0; + h->location = NULL; + h->parent = NULL; + + return h; +} + +/* calls the request callback to send an entry + * + * params: + * req: the original request passed to your module + * msg: reply message (must be a talloc pointer, and it will be stolen + * on the ldb_reply that is sent to the callback) + * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen + * on the ldb_reply that is sent to the callback) + */ + +int ldb_module_send_entry(struct ldb_request *req, + struct ldb_message *msg, + struct ldb_control **ctrls) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_ENTRY; + ares->message = talloc_steal(ares, msg); + ares->controls = talloc_steal(ares, ctrls); + ares->error = LDB_SUCCESS; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + char *s; + ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); + s = ldb_ldif_message_string(req->handle->ldb, msg, LDB_CHANGETYPE_NONE, msg); + ldb_debug_add(req->handle->ldb, "%s\n", s); + talloc_free(s); + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* calls the request callback to send an referrals + * + * params: + * req: the original request passed to your module + * ref: referral string (must be a talloc pointeri, steal) + */ + +int ldb_module_send_referral(struct ldb_request *req, + char *ref) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_REFERRAL; + ares->referral = talloc_steal(ares, ref); + ares->error = LDB_SUCCESS; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + ldb_debug_add(req->handle->ldb, "ldb_trace_response: REFERRAL\n"); + ldb_debug_add(req->handle->ldb, "ref: %s\n", ref); + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* calls the original request callback + * + * params: + * req: the original request passed to your module + * ctrls: controls to send in the reply (must be a talloc pointer, steal) + * response: results for extended request (steal) + * error: LDB_SUCCESS for a successful return + * any other ldb error otherwise + */ +int ldb_module_done(struct ldb_request *req, + struct ldb_control **ctrls, + struct ldb_extended *response, + int error) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_DONE; + ares->controls = talloc_steal(ares, ctrls); + ares->response = talloc_steal(ares, response); + ares->error = error; + + req->handle->flags |= LDB_HANDLE_FLAG_DONE_CALLED; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + ldb_debug_add(req->handle->ldb, "ldb_trace_response: DONE\n"); + ldb_debug_add(req->handle->ldb, "error: %d\n", error); + if (ldb_errstring(req->handle->ldb)) { + ldb_debug_add(req->handle->ldb, "msg: %s\n", + ldb_errstring(req->handle->ldb)); + } + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* to be used *only* in modules init functions. + * this function is synchronous and will register + * the requested OID in the rootdse module if present + * otherwise it will return an error */ +int ldb_mod_register_control(struct ldb_module *module, const char *oid) +{ + struct ldb_request *req; + int ret; + + req = talloc_zero(module, struct ldb_request); + if (req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_REQ_REGISTER_CONTROL; + req->op.reg_control.oid = oid; + req->callback = ldb_op_default_callback; + + ldb_set_timeout(module->ldb, req, 0); + + req->handle = ldb_handle_new(req, module->ldb); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_request(module->ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + talloc_free(req); + + return ret; +} + +static int ldb_modules_load_dir(const char *modules_dir, const char *version); + + +/* + load one module. A static list of loaded module inode numbers is + used to prevent a module being loaded twice + + dlopen() is used on the module, and dlsym() is then used to look for + a ldb_init_module() function. If present, that function is called + with the ldb version number as an argument. + + The ldb_init_module() function will typically call + ldb_register_module() and ldb_register_backend() to register a + module or backend, but it may also be used to register command line + handling functions, ldif handlers or any other local + modififications. + + The ldb_init_module() function does not get a ldb_context passed in, + as modules will be used for multiple ldb context handles. The call + from the first ldb_init() is just a convenient way to ensure it is + called early enough. + */ +static int ldb_modules_load_path(const char *path, const char *version) +{ + void *handle; + int (*init_fn)(const char *); + int ret; + struct stat st; + static struct loaded { + struct loaded *next, *prev; + ino_t st_ino; + dev_t st_dev; + } *loaded; + struct loaded *le; + int dlopen_flags; + + ret = stat(path, &st); + if (ret != 0) { + fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); + return LDB_ERR_UNAVAILABLE; + } + + for (le=loaded; le; le=le->next) { + if (le->st_ino == st.st_ino && + le->st_dev == st.st_dev) { + /* its already loaded */ + return LDB_SUCCESS; + } + } + + le = talloc(loaded, struct loaded); + if (le == NULL) { + fprintf(stderr, "ldb: unable to allocated loaded entry\n"); + return LDB_ERR_UNAVAILABLE; + } + + le->st_ino = st.st_ino; + le->st_dev = st.st_dev; + + DLIST_ADD_END(loaded, le, struct loaded); + + /* if it is a directory, recurse */ + if (S_ISDIR(st.st_mode)) { + return ldb_modules_load_dir(path, version); + } + + dlopen_flags = RTLD_NOW; +#ifdef RTLD_DEEPBIND + /* use deepbind if possible, to avoid issues with different + system library varients, for example ldb modules may be linked + against Heimdal while the application may use MIT kerberos + + See the dlopen manpage for details + */ + dlopen_flags |= RTLD_DEEPBIND; +#endif + + handle = dlopen(path, dlopen_flags); + if (handle == NULL) { + fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); + return LDB_SUCCESS; + } + + init_fn = dlsym(handle, "ldb_init_module"); + if (init_fn == NULL) { + /* ignore it, it could be an old-style + * module. Once we've converted all modules we + * could consider this an error */ + dlclose(handle); + return LDB_SUCCESS; + } + + ret = init_fn(version); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + /* the module is already registered - ignore this, as + * it can happen if LDB_MODULES_PATH points at both + * the build and install directory + */ + ret = LDB_SUCCESS; + } + return ret; +} + +static int qsort_string(const char **s1, const char **s2) +{ + return strcmp(*s1, *s2); +} + + +/* + load all modules from the given ldb modules directory. This is run once + during the first ldb_init() call. + + Modules are loaded in alphabetical order to ensure that any module + load ordering dependencies are reproducible. Modules should avoid + relying on load order + */ +static int ldb_modules_load_dir(const char *modules_dir, const char *version) +{ + DIR *dir; + struct dirent *de; + const char **modlist = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + unsigned i, num_modules = 0; + + dir = opendir(modules_dir); + if (dir == NULL) { + if (errno == ENOENT) { + talloc_free(tmp_ctx); + /* we don't have any modules */ + return LDB_SUCCESS; + } + talloc_free(tmp_ctx); + fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", + modules_dir, strerror(errno)); + return LDB_ERR_UNAVAILABLE; + } + + + while ((de = readdir(dir))) { + if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) + continue; + + modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); + if (modlist == NULL) { + talloc_free(tmp_ctx); + closedir(dir); + fprintf(stderr, "ldb: unable to allocate modules list\n"); + return LDB_ERR_UNAVAILABLE; + } + modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); + if (modlist[num_modules] == NULL) { + talloc_free(tmp_ctx); + closedir(dir); + fprintf(stderr, "ldb: unable to allocate module list entry\n"); + return LDB_ERR_UNAVAILABLE; + } + num_modules++; + } + + closedir(dir); + + /* sort the directory, so we get consistent load ordering */ + TYPESAFE_QSORT(modlist, num_modules, qsort_string); + + for (i=0; ihandle) { + char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", + i++, req, ldb_req_location(req)); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + req = req->handle->parent; + } + return ret; +} + + +/* + return the next module in the chain + */ +struct ldb_module *ldb_module_next(struct ldb_module *module) +{ + return module->next; +} + +/* + set the next module in the module chain + */ +void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) +{ + module->next = next; +} + + +/* + get the popt_options pointer in the ldb structure. This allows a ldb + module to change the command line parsing + */ +struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) +{ + return &ldb->popt_options; +} + + +/* + return the current ldb flags LDB_FLG_* + */ +uint32_t ldb_module_flags(struct ldb_context *ldb) +{ + return ldb->flags; +} diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c new file mode 100644 index 00000000000..28c414e6b23 --- /dev/null +++ b/lib/ldb/common/ldb_msg.c @@ -0,0 +1,1187 @@ +/* + 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 message component utility functions + * + * Description: functions for manipulating ldb_message structures + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + create a new ldb_message in a given memory context (NULL for top level) +*/ +struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldb_message); +} + +/* + find an element in a message by attribute name +*/ +struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, + const char *attr_name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { + return &msg->elements[i]; + } + } + return NULL; +} + +/* + see if two ldb_val structures contain exactly the same data + return 1 for a match, 0 for a mis-match +*/ +int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) return 0; + if (v1->data == v2->data) return 1; + if (v1->length == 0) return 1; + + if (memcmp(v1->data, v2->data, v1->length) == 0) { + return 1; + } + + return 0; +} + +/* + find a value in an element + assumes case sensitive comparison +*/ +struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, + struct ldb_val *val) +{ + unsigned int i; + for (i=0;inum_values;i++) { + if (ldb_val_equal_exact(val, &el->values[i])) { + return &el->values[i]; + } + } + return NULL; +} + +/* + duplicate a ldb_val structure +*/ +struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) +{ + struct ldb_val v2; + v2.length = v->length; + if (v->data == NULL) { + v2.data = NULL; + return v2; + } + + /* the +1 is to cope with buggy C library routines like strndup + that look one byte beyond */ + v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); + if (!v2.data) { + v2.length = 0; + return v2; + } + + memcpy(v2.data, v->data, v->length); + ((char *)v2.data)[v->length] = 0; + return v2; +} + +/** + * Adds new empty element to msg->elements + */ +static int _ldb_msg_add_el(struct ldb_message *msg, + struct ldb_message_element **return_el) +{ + struct ldb_message_element *els; + + /* + * TODO: Find out a way to assert on input parameters. + * msg and return_el must be valid + */ + + els = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements + 1); + if (!els) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ZERO_STRUCT(els[msg->num_elements]); + + msg->elements = els; + msg->num_elements++; + + *return_el = &els[msg->num_elements-1]; + + return LDB_SUCCESS; +} + +/** + * Add an empty element with a given name to a message + */ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) +{ + int ret; + struct ldb_message_element *el; + + ret = _ldb_msg_add_el(msg, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* initialize newly added element */ + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr_name); + if (!el->name) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (return_el) { + *return_el = el; + } + + return LDB_SUCCESS; +} + +/** + * Adds an element to a message. + * + * NOTE: Ownership of ldb_message_element fields + * is NOT transferred. Thus, if *el pointer + * is invalidated for some reason, this will + * corrupt *msg contents also + */ +int ldb_msg_add(struct ldb_message *msg, + const struct ldb_message_element *el, + int flags) +{ + int ret; + struct ldb_message_element *el_new; + /* We have to copy this, just in case *el is a pointer into + * what ldb_msg_add_empty() is about to realloc() */ + struct ldb_message_element el_copy = *el; + + ret = _ldb_msg_add_el(msg, &el_new); + if (ret != LDB_SUCCESS) { + return ret; + } + + el_new->flags = flags; + el_new->name = el_copy.name; + el_new->num_values = el_copy.num_values; + el_new->values = el_copy.values; + + return LDB_SUCCESS; +} + +/* + add a value to a message +*/ +int ldb_msg_add_value(struct ldb_message *msg, + const char *attr_name, + const struct ldb_val *val, + struct ldb_message_element **return_el) +{ + struct ldb_message_element *el; + struct ldb_val *vals; + int ret; + + el = ldb_msg_find_element(msg, attr_name); + if (!el) { + ret = ldb_msg_add_empty(msg, attr_name, 0, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + vals = talloc_realloc(msg->elements, el->values, struct ldb_val, + el->num_values+1); + if (!vals) { + return LDB_ERR_OPERATIONS_ERROR; + } + el->values = vals; + el->values[el->num_values] = *val; + el->num_values++; + + if (return_el) { + *return_el = el; + } + + return LDB_SUCCESS; +} + + +/* + add a value to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_value(struct ldb_message *msg, + const char *attr_name, + struct ldb_val *val) +{ + int ret; + struct ldb_message_element *el; + + ret = ldb_msg_add_value(msg, attr_name, val, &el); + if (ret == LDB_SUCCESS) { + talloc_steal(el->values, val->data); + } + return ret; +} + + +/* + add a string element to a message +*/ +int ldb_msg_add_string(struct ldb_message *msg, + const char *attr_name, const char *str) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, str); + val.length = strlen(str); + + if (val.length == 0) { + /* allow empty strings as non-existent attributes */ + return LDB_SUCCESS; + } + + return ldb_msg_add_value(msg, attr_name, &val, NULL); +} + +/* + add a string element to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_string(struct ldb_message *msg, + const char *attr_name, char *str) +{ + struct ldb_val val; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + if (val.length == 0) { + /* allow empty strings as non-existent attributes */ + return LDB_SUCCESS; + } + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + add a DN element to a message + WARNING: this uses the linearized string from the dn, and does not + copy the string. +*/ +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn) +{ + char *str = ldb_dn_alloc_linearized(msg, dn); + + if (str == NULL) { + /* we don't want to have unknown DNs added */ + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_msg_add_steal_string(msg, attr_name, str); +} + +/* + add a printf formatted element to a message +*/ +int ldb_msg_add_fmt(struct ldb_message *msg, + const char *attr_name, const char *fmt, ...) +{ + struct ldb_val val; + va_list ap; + char *str; + + va_start(ap, fmt); + str = talloc_vasprintf(msg, fmt, ap); + va_end(ap); + + if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + compare two ldb_message_element structures + assumes case sensitive comparison +*/ +int ldb_msg_element_compare(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + unsigned int i; + + if (el1->num_values != el2->num_values) { + return el1->num_values - el2->num_values; + } + + for (i=0;inum_values;i++) { + if (!ldb_msg_find_val(el2, &el1->values[i])) { + return -1; + } + } + + return 0; +} + +/* + compare two ldb_message_element structures + comparing by element name +*/ +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + return ldb_attr_cmp(el1->name, el2->name); +} + +/* + convenience functions to return common types from a message + these return the first value if the attribute is multi-valued +*/ +const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, + const char *attr_name) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); + if (!el || el->num_values == 0) { + return NULL; + } + return &el->values[0]; +} + +int ldb_msg_find_attr_as_int(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + int ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, + const char *attr_name, + unsigned int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + unsigned int ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (unsigned int) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (unsigned int) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, + const char *attr_name, + int64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + int64_t ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int64_t) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, + const char *attr_name, + uint64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + uint64_t ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (uint64_t) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (uint64_t) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +double ldb_msg_find_attr_as_double(const struct ldb_message *msg, + const char *attr_name, + double default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char *buf; + char *end = NULL; + double ret; + + if (!v || !v->data) { + return default_value; + } + buf = talloc_strndup(msg, (const char *)v->data, v->length); + if (buf == NULL) { + return default_value; + } + + errno = 0; + ret = strtod(buf, &end); + talloc_free(buf); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) { + return 0; + } + if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) { + return 1; + } + return default_value; +} + +const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, + const char *attr_name, + const char *default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + if (v->data[v->length] != '\0') { + return default_value; + } + return (const char *)v->data; +} + +struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char *attr_name) +{ + struct ldb_dn *res_dn; + const struct ldb_val *v; + + v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return NULL; + } + res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v); + if ( ! ldb_dn_validate(res_dn)) { + talloc_free(res_dn); + return NULL; + } + return res_dn; +} + +/* + sort the elements of a message by name +*/ +void ldb_msg_sort_elements(struct ldb_message *msg) +{ + TYPESAFE_QSORT(msg->elements, msg->num_elements, + ldb_msg_element_compare_name); +} + +/* + shallow copy a message - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + unsigned int i; + + msg2 = talloc(mem_ctx, struct ldb_message); + if (msg2 == NULL) return NULL; + + *msg2 = *msg; + + msg2->elements = talloc_array(msg2, struct ldb_message_element, + msg2->num_elements); + if (msg2->elements == NULL) goto failed; + + for (i=0;inum_elements;i++) { + msg2->elements[i] = msg->elements[i]; + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/* + copy a message, allocating new memory for all parts +*/ +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + unsigned int i, j; + + msg2 = ldb_msg_copy_shallow(mem_ctx, msg); + if (msg2 == NULL) return NULL; + + msg2->dn = ldb_dn_copy(msg2, msg2->dn); + if (msg2->dn == NULL) goto failed; + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg2->elements[i]; + struct ldb_val *values = el->values; + el->name = talloc_strdup(msg2->elements, el->name); + if (el->name == NULL) goto failed; + el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); + for (j=0;jnum_values;j++) { + el->values[j] = ldb_val_dup(el->values, &values[j]); + if (el->values[j].data == NULL && values[j].length != 0) { + goto failed; + } + } + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/** + * Canonicalize a message, merging elements of the same name + */ +struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + int ret; + struct ldb_message *msg2; + + /* + * Preserve previous behavior and allocate + * *msg2 into *ldb context + */ + ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return msg2; +} + +/** + * Canonicalize a message, merging elements of the same name + */ +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out) +{ + unsigned int i; + struct ldb_message *msg2; + + msg2 = ldb_msg_copy(mem_ctx, msg); + if (msg2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_msg_sort_elements(msg2); + + for (i=1; i < msg2->num_elements; i++) { + struct ldb_message_element *el1 = &msg2->elements[i-1]; + struct ldb_message_element *el2 = &msg2->elements[i]; + + if (ldb_msg_element_compare_name(el1, el2) == 0) { + el1->values = talloc_realloc(msg2->elements, + el1->values, struct ldb_val, + el1->num_values + el2->num_values); + if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { + talloc_free(msg2); + return LDB_ERR_OPERATIONS_ERROR; + } + memcpy(el1->values + el1->num_values, + el2->values, + sizeof(struct ldb_val) * el2->num_values); + el1->num_values += el2->num_values; + talloc_free(discard_const_p(char, el2->name)); + if ((i+1) < msg2->num_elements) { + memmove(el2, el2+1, sizeof(struct ldb_message_element) * + (msg2->num_elements - (i+1))); + } + msg2->num_elements--; + i--; + } + } + + *_msg_out = msg2; + return LDB_SUCCESS; +} + + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + */ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) +{ + int ldb_ret; + struct ldb_message *mod; + + ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); + if (ldb_ret != LDB_SUCCESS) { + return NULL; + } + + return mod; +} + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out) +{ + int ldb_res; + unsigned int i; + struct ldb_message *mod; + struct ldb_message_element *el; + TALLOC_CTX *temp_ctx; + + temp_ctx = talloc_new(mem_ctx); + if (!temp_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = ldb_msg_new(temp_ctx); + if (mod == NULL) { + goto failed; + } + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; + + /* + * Canonicalize *msg2 so we have no repeated elements + * Resulting message is allocated in *mod's mem context, + * as we are going to move some elements from *msg2 to + * *mod object later + */ + ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + + /* look in msg2 to find elements that need to be added or modified */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg1, msg2->elements[i].name); + + if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { + continue; + } + + ldb_res = ldb_msg_add(mod, + &msg2->elements[i], + el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + + /* look in msg1 to find elements that need to be deleted */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg2, msg1->elements[i].name); + if (el == NULL) { + ldb_res = ldb_msg_add_empty(mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE, NULL); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + } + + /* steal resulting message into supplied context */ + talloc_steal(mem_ctx, mod); + *_msg_out = mod; + + talloc_free(temp_ctx); + return LDB_SUCCESS; + +failed: + talloc_free(temp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +} + + +int ldb_msg_sanity_check(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + unsigned int i, j; + + /* basic check on DN */ + if (msg->dn == NULL) { + ldb_set_errstring(ldb, "ldb message lacks a DN!"); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + /* basic syntax checks */ + for (i = 0; i < msg->num_elements; i++) { + for (j = 0; j < msg->elements[i].num_values; j++) { + if (msg->elements[i].values[j].length == 0) { + /* an attribute cannot be empty */ + ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", + msg->elements[i].name, + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return LDB_SUCCESS; +} + + + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers) +*/ +const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) +{ + const char **ret; + unsigned int i; + + for (i=0;attrs && attrs[i];i++) /* noop */ ; + ret = talloc_array(mem_ctx, const char *, i+1); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs && attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = attrs[i]; + return ret; +} + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers). The new attribute is added to the list. +*/ +const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) +{ + const char **ret; + unsigned int i; + bool found = false; + + for (i=0;attrs && attrs[i];i++) { + if (ldb_attr_cmp(attrs[i], new_attr) == 0) { + found = true; + } + } + if (found) { + return ldb_attr_list_copy(mem_ctx, attrs); + } + ret = talloc_array(mem_ctx, const char *, i+2); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs && attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = new_attr; + ret[i+1] = NULL; + return ret; +} + + +/* + return 1 if an attribute is in a list of attributes, or 0 otherwise +*/ +int ldb_attr_in_list(const char * const *attrs, const char *attr) +{ + unsigned int i; + for (i=0;attrs && attrs[i];i++) { + if (ldb_attr_cmp(attrs[i], attr) == 0) { + return 1; + } + } + return 0; +} + + +/* + rename the specified attribute in a search result +*/ +int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + if (el == NULL) { + return LDB_SUCCESS; + } + el->name = talloc_strdup(msg->elements, replace); + if (el->name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; +} + + +/* + copy the specified attribute in a search result to a new attribute +*/ +int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + int ret; + + if (el == NULL) { + return LDB_SUCCESS; + } + ret = ldb_msg_add(msg, el, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + return ldb_msg_rename_attr(msg, attr, replace); +} + +/* + remove the specified element in a search result +*/ +void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) +{ + ptrdiff_t n = (el - msg->elements); + if (n >= msg->num_elements) { + /* should we abort() here? */ + return; + } + if (n != msg->num_elements-1) { + memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); + } + msg->num_elements--; +} + + +/* + remove the specified attribute in a search result +*/ +void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) +{ + struct ldb_message_element *el; + + while ((el = ldb_msg_find_element(msg, attr)) != NULL) { + ldb_msg_remove_element(msg, el); + } +} + +/* + return a LDAP formatted GeneralizedTime string +*/ +char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) +{ + struct tm *tm = gmtime(&t); + char *ts; + int r; + + if (!tm) { + return NULL; + } + + /* we now excatly how long this string will be */ + ts = talloc_array(mem_ctx, char, 18); + + /* formatted like: 20040408072012.0Z */ + r = snprintf(ts, 18, + "%04u%02u%02u%02u%02u%02u.0Z", + tm->tm_year+1900, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + if (r != 17) { + talloc_free(ts); + return NULL; + } + + return ts; +} + +/* + convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert +*/ +time_t ldb_string_to_time(const char *s) +{ + struct tm tm; + + if (s == NULL) return 0; + + memset(&tm, 0, sizeof(tm)); + if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + +/* + convert a LDAP GeneralizedTime string in ldb_val format to a + time_t. +*/ +int ldb_val_to_time(const struct ldb_val *v, time_t *t) +{ + struct tm tm; + + if (v == NULL || !v->data || v->length < 17) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + memset(&tm, 0, sizeof(tm)); + + if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + *t = timegm(&tm); + + return LDB_SUCCESS; +} + +/* + return a LDAP formatted UTCTime string +*/ +char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t) +{ + struct tm *tm = gmtime(&t); + char *ts; + int r; + + if (!tm) { + return NULL; + } + + /* we now excatly how long this string will be */ + ts = talloc_array(mem_ctx, char, 14); + + /* formatted like: 20040408072012.0Z => 040408072012Z */ + r = snprintf(ts, 14, + "%02u%02u%02u%02u%02u%02uZ", + (tm->tm_year+1900)%100, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + if (r != 13) { + talloc_free(ts); + return NULL; + } + + return ts; +} + +/* + convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert +*/ +time_t ldb_string_utc_to_time(const char *s) +{ + struct tm tm; + + if (s == NULL) return 0; + + memset(&tm, 0, sizeof(tm)); + if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + if (tm.tm_year < 50) { + tm.tm_year += 100; + } + tm.tm_mon -= 1; + + return timegm(&tm); +} + + +/* + dump a set of results to a file. Useful from within gdb +*/ +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) +{ + unsigned int i; + + for (i = 0; i < result->count; i++) { + struct ldb_ldif ldif; + fprintf(f, "# record %d\n", i+1); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = result->msgs[i]; + ldb_ldif_write_file(ldb, f, &ldif); + } +} + +/* + checks for a string attribute. Returns "1" on match and otherwise "0". +*/ +int ldb_msg_check_string_attribute(const struct ldb_message *msg, + const char *name, const char *value) +{ + struct ldb_message_element *el; + struct ldb_val val; + + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return 0; + } + + val.data = discard_const_p(uint8_t, value); + val.length = strlen(value); + + if (ldb_msg_find_val(el, &val)) { + return 1; + } + + return 0; +} + diff --git a/lib/ldb/common/ldb_options.c b/lib/ldb/common/ldb_options.c new file mode 100644 index 00000000000..f07f3935624 --- /dev/null +++ b/lib/ldb/common/ldb_options.c @@ -0,0 +1,72 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2010 + + ** 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 options[] handling + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + find an option within an options array + + accepts the following forms: + + NAME + NAME:value + NAME=value + + returns a pointer into an element of the options[] array, or NULL is + not found. + + For the NAME form, returns a pointer to an empty string (thus + allowing for boolean options). + */ +const char *ldb_options_find(struct ldb_context *ldb, const char *options[], + const char *option_name) +{ + size_t len = strlen(option_name); + int i; + + if (options == NULL) { + return NULL; + } + + for (i=0; options[i]; i++) { + if (strncmp(option_name, options[i], len) != 0) { + continue; + } + if (options[i][len] == ':' || options[i][len] == '=') { + return &options[i][len+1]; + } + if (options[i][len] == 0) { + return &options[i][len]; + } + } + + return NULL; +} diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c new file mode 100644 index 00000000000..b4eabf8375c --- /dev/null +++ b/lib/ldb/common/ldb_parse.c @@ -0,0 +1,903 @@ +/* + 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 expression parsing + * + * Description: parse LDAP-like search expressions + * + * Author: Andrew Tridgell + */ + +/* + TODO: + - add RFC2254 binary string handling + - possibly add ~=, <= and >= handling + - expand the test suite + - add better parse error handling + +*/ + +#include "ldb_private.h" +#include "system/locale.h" + +static int ldb_parse_hex2char(const char *x) +{ + if (isxdigit(x[0]) && isxdigit(x[1])) { + const char h1 = x[0], h2 = x[1]; + int c = 0; + + if (h1 >= 'a') c = h1 - (int)'a' + 10; + else if (h1 >= 'A') c = h1 - (int)'A' + 10; + else if (h1 >= '0') c = h1 - (int)'0'; + c = c << 4; + if (h2 >= 'a') c += h2 - (int)'a' + 10; + else if (h2 >= 'A') c += h2 - (int)'A' + 10; + else if (h2 >= '0') c += h2 - (int)'0'; + + return c; + } + + return -1; +} + +/* +a filter is defined by: + ::= '(' ')' + ::= | | | + ::= '&' + ::= '|' + ::= '!' + ::= | + ::= + ::= '=' | '~=' | '<=' | '>=' +*/ + +/* + decode a RFC2254 binary string representation of a buffer. + Used in LDAP filters. +*/ +struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +{ + size_t i, j; + struct ldb_val ret; + size_t slen = str?strlen(str):0; + + ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); + ret.length = 0; + if (ret.data == NULL) return ret; + + for (i=j=0;idata == NULL) return NULL; + + val++; + } + + if (ret != NULL) { + ret[val] = NULL; + } + + return ret; +} + +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); + + +/* + parse an extended match + + possible forms: + (attr:oid:=value) + (attr:dn:oid:=value) + (attr:dn:=value) + (:dn:oid:=value) + + the ':dn' part sets the dnAttributes boolean if present + the oid sets the rule_id string + +*/ +static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, + char *attr, char *value) +{ + char *p1, *p2; + + ret->operation = LDB_OP_EXTENDED; + ret->u.extended.value = ldb_binary_decode(ret, value); + if (ret->u.extended.value.data == NULL) goto failed; + + p1 = strchr(attr, ':'); + if (p1 == NULL) goto failed; + p2 = strchr(p1+1, ':'); + + *p1 = 0; + if (p2) *p2 = 0; + + ret->u.extended.attr = attr; + if (strcmp(p1+1, "dn") == 0) { + ret->u.extended.dnAttributes = 1; + if (p2) { + ret->u.extended.rule_id = talloc_strdup(ret, p2+1); + if (ret->u.extended.rule_id == NULL) goto failed; + } else { + ret->u.extended.rule_id = NULL; + } + } else { + ret->u.extended.dnAttributes = 0; + ret->u.extended.rule_id = talloc_strdup(ret, p1+1); + if (ret->u.extended.rule_id == NULL) goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) +{ + enum ldb_parse_op filter = 0; + char *name, *val, *k; + const char *p = *s; + const char *t, *t1; + + /* retrieve attributetype name */ + t = p; + + if (*p == '@') { /* for internal attributes the first char can be @ */ + p++; + } + + while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { + /* attribute names can only be alphanums */ + p++; + } + + if (*p == ':') { /* but extended searches have : and . chars too */ + p = strstr(p, ":="); + if (p == NULL) { /* malformed attribute name */ + return 0; + } + } + + t1 = p; + + while (isspace((unsigned char)*p)) p++; + + if (!strchr("=<>~:", *p)) { + return 0; + } + + /* save name */ + name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); + if (name == NULL) return 0; + name[t1 - t] = '\0'; + + /* retrieve filtertype */ + + if (*p == '=') { + filter = LDB_OP_EQUALITY; + } else if (*(p + 1) == '=') { + switch (*p) { + case '<': + filter = LDB_OP_LESS; + p++; + break; + case '>': + filter = LDB_OP_GREATER; + p++; + break; + case '~': + filter = LDB_OP_APPROX; + p++; + break; + case ':': + filter = LDB_OP_EXTENDED; + p++; + break; + } + } + if (!filter) { + talloc_free(name); + return filter; + } + p++; + + while (isspace((unsigned char)*p)) p++; + + /* retrieve value */ + t = p; + + while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; + + val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); + if (val == NULL) { + talloc_free(name); + return 0; + } + val[p - t] = '\0'; + + k = &(val[p - t]); + + /* remove trailing spaces from value */ + while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; + *k = '\0'; + + *type = name; + *value = val; + *s = p; + return filter; +} + +/* + ::= +*/ +static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) +{ + char *attr, *value; + struct ldb_parse_tree *ret; + enum ldb_parse_op filtertype; + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + filtertype = ldb_parse_filtertype(ret, &attr, &value, s); + if (!filtertype) { + talloc_free(ret); + return NULL; + } + + switch (filtertype) { + + case LDB_OP_PRESENT: + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = attr; + break; + + case LDB_OP_EQUALITY: + + if (strcmp(value, "*") == 0) { + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = attr; + break; + } + + if (ldb_parse_find_wildcard(value) != NULL) { + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = attr; + ret->u.substring.start_with_wildcard = 0; + ret->u.substring.end_with_wildcard = 0; + ret->u.substring.chunks = ldb_wildcard_decode(ret, value); + if (ret->u.substring.chunks == NULL){ + talloc_free(ret); + return NULL; + } + if (value[0] == '*') + ret->u.substring.start_with_wildcard = 1; + if (value[strlen(value) - 1] == '*') + ret->u.substring.end_with_wildcard = 1; + talloc_free(value); + + break; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = attr; + ret->u.equality.value = ldb_binary_decode(ret, value); + if (ret->u.equality.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_GREATER: + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_LESS: + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_APPROX: + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_EXTENDED: + + ret = ldb_parse_extended(ret, attr, value); + break; + + default: + talloc_free(ret); + return NULL; + } + + return ret; +} + + +/* + parse a filterlist + ::= '&' + ::= '|' + ::= | +*/ +static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret, *next; + enum ldb_parse_op op; + const char *p = *s; + + switch (*p) { + case '&': + op = LDB_OP_AND; + break; + case '|': + op = LDB_OP_OR; + break; + default: + return NULL; + } + p++; + + while (isspace((unsigned char)*p)) p++; + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = op; + ret->u.list.num_elements = 1; + ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); + if (!ret->u.list.elements) { + errno = ENOMEM; + talloc_free(ret); + return NULL; + } + + ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); + if (!ret->u.list.elements[0]) { + talloc_free(ret); + return NULL; + } + + while (isspace((unsigned char)*p)) p++; + + while (*p && (next = ldb_parse_filter(ret->u.list.elements, &p))) { + struct ldb_parse_tree **e; + e = talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements + 1); + if (!e) { + errno = ENOMEM; + talloc_free(ret); + return NULL; + } + ret->u.list.elements = e; + ret->u.list.elements[ret->u.list.num_elements] = next; + ret->u.list.num_elements++; + while (isspace((unsigned char)*p)) p++; + } + + *s = p; + + return ret; +} + + +/* + ::= '!' +*/ +static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + if (*p != '!') { + return NULL; + } + p++; + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldb_parse_filter(ret, &p); + if (!ret->u.isnot.child) { + talloc_free(ret); + return NULL; + } + + *s = p; + + return ret; +} + +/* + parse a filtercomp + ::= | | | +*/ +static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + while (isspace((unsigned char)*p)) p++; + + switch (*p) { + case '&': + ret = ldb_parse_filterlist(mem_ctx, &p); + break; + + case '|': + ret = ldb_parse_filterlist(mem_ctx, &p); + break; + + case '!': + ret = ldb_parse_not(mem_ctx, &p); + break; + + case '(': + case ')': + return NULL; + + default: + ret = ldb_parse_simple(mem_ctx, &p); + + } + + *s = p; + return ret; +} + + +/* + ::= '(' ')' +*/ +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + if (*p != '(') { + return NULL; + } + p++; + + ret = ldb_parse_filtercomp(mem_ctx, &p); + + if (*p != ')') { + return NULL; + } + p++; + + while (isspace((unsigned char)*p)) { + p++; + } + + *s = p; + + return ret; +} + + +/* + main parser entry point. Takes a search string and returns a parse tree + + expression ::= | +*/ +struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +{ + if (s == NULL || *s == 0) { + s = "(|(objectClass=*)(distinguishedName=*))"; + } + + while (isspace((unsigned char)*s)) s++; + + if (*s == '(') { + return ldb_parse_filter(mem_ctx, &s); + } + + return ldb_parse_simple(mem_ctx, &s); +} + + +/* + construct a ldap parse filter given a parse tree +*/ +char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) +{ + char *s, *s2, *ret; + unsigned int i; + + if (tree == NULL) { + return NULL; + } + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); + if (ret == NULL) return NULL; + for (i=0;iu.list.num_elements;i++) { + s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + s2 = talloc_asprintf_append(ret, "%s", s); + talloc_free(s); + if (s2 == NULL) { + talloc_free(ret); + return NULL; + } + ret = s2; + } + s = talloc_asprintf_append(ret, ")"); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + return s; + case LDB_OP_NOT: + s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); + if (s == NULL) return NULL; + + ret = talloc_asprintf(mem_ctx, "(!%s)", s); + talloc_free(s); + return ret; + case LDB_OP_EQUALITY: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_SUBSTRING: + ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, + tree->u.substring.start_with_wildcard?"*":""); + if (ret == NULL) return NULL; + for (i = 0; tree->u.substring.chunks[i]; i++) { + s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); + if (s2 == NULL) { + talloc_free(ret); + return NULL; + } + if (tree->u.substring.chunks[i+1] || + tree->u.substring.end_with_wildcard) { + s = talloc_asprintf_append(ret, "%s*", s2); + } else { + s = talloc_asprintf_append(ret, "%s", s2); + } + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + } + s = talloc_asprintf_append(ret, ")"); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + return ret; + case LDB_OP_GREATER: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s>=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_LESS: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s<=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_PRESENT: + ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); + return ret; + case LDB_OP_APPROX: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s~=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_EXTENDED: + s = ldb_binary_encode(mem_ctx, tree->u.extended.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", + tree->u.extended.attr?tree->u.extended.attr:"", + tree->u.extended.dnAttributes?":dn":"", + tree->u.extended.rule_id?":":"", + tree->u.extended.rule_id?tree->u.extended.rule_id:"", + s); + talloc_free(s); + return ret; + } + + return NULL; +} + + +/* + replace any occurrences of an attribute name in the parse tree with a + new name +*/ +void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, + const char *attr, + const char *replace) +{ + unsigned int i; + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + for (i=0;iu.list.num_elements;i++) { + ldb_parse_tree_attr_replace(tree->u.list.elements[i], + attr, replace); + } + break; + case LDB_OP_NOT: + ldb_parse_tree_attr_replace(tree->u.isnot.child, attr, replace); + break; + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) { + tree->u.equality.attr = replace; + } + break; + case LDB_OP_SUBSTRING: + if (ldb_attr_cmp(tree->u.substring.attr, attr) == 0) { + tree->u.substring.attr = replace; + } + break; + case LDB_OP_PRESENT: + if (ldb_attr_cmp(tree->u.present.attr, attr) == 0) { + tree->u.present.attr = replace; + } + break; + case LDB_OP_EXTENDED: + if (tree->u.extended.attr && + ldb_attr_cmp(tree->u.extended.attr, attr) == 0) { + tree->u.extended.attr = replace; + } + break; + } +} + +/* + shallow copy a tree - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_parse_tree *ot) +{ + unsigned int i; + struct ldb_parse_tree *nt; + + nt = talloc(mem_ctx, struct ldb_parse_tree); + if (!nt) { + return NULL; + } + + *nt = *ot; + + switch (ot->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *, + ot->u.list.num_elements); + if (!nt->u.list.elements) { + talloc_free(nt); + return NULL; + } + + for (i=0;iu.list.num_elements;i++) { + nt->u.list.elements[i] = + ldb_parse_tree_copy_shallow(nt->u.list.elements, + ot->u.list.elements[i]); + if (!nt->u.list.elements[i]) { + talloc_free(nt); + return NULL; + } + } + break; + case LDB_OP_NOT: + nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt, + ot->u.isnot.child); + if (!nt->u.isnot.child) { + talloc_free(nt); + return NULL; + } + break; + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + case LDB_OP_SUBSTRING: + case LDB_OP_PRESENT: + case LDB_OP_EXTENDED: + break; + } + + return nt; +} diff --git a/lib/ldb/common/ldb_utf8.c b/lib/ldb/common/ldb_utf8.c new file mode 100644 index 00000000000..55d8f905d35 --- /dev/null +++ b/lib/ldb/common/ldb_utf8.c @@ -0,0 +1,136 @@ +/* + 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 utf8 handling + * + * Description: case folding and case comparison for UTF8 strings + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" +#include "system/locale.h" + + +/* + this allow the user to pass in a caseless comparison + function to handle utf8 caseless comparisons + */ +void ldb_set_utf8_fns(struct ldb_context *ldb, + void *context, + char *(*casefold)(void *, void *, const char *, size_t)) +{ + if (context) + ldb->utf8_fns.context = context; + if (casefold) + ldb->utf8_fns.casefold = casefold; +} + +/* + a simple case folding function + NOTE: does not handle UTF8 +*/ +char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) +{ + size_t i; + char *ret = talloc_strndup(mem_ctx, s, n); + if (!s) { + errno = ENOMEM; + return NULL; + } + for (i=0;ret[i];i++) { + ret[i] = toupper((unsigned char)ret[i]); + } + return ret; +} + +void ldb_set_utf8_default(struct ldb_context *ldb) +{ + ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); +} + +char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) +{ + return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); +} + +/* + check the attribute name is valid according to rfc2251 + returns 1 if the name is ok + */ + +int ldb_valid_attr_name(const char *s) +{ + size_t i; + + if (!s || !s[0]) + return 0; + + /* handle special ldb_tdb wildcard */ + if (strcmp(s, "*") == 0) return 1; + + for (i = 0; s[i]; i++) { + if (! isascii(s[i])) { + return 0; + } + if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ + if (! (isalpha(s[i]) || (s[i] == '@'))) { + return 0; + } + } else { + if (! (isalnum(s[i]) || (s[i] == '-'))) { + return 0; + } + } + } + return 1; +} + +char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) +{ + size_t i; + char *ret = talloc_strdup(mem_ctx, s); + if (!ret) { + errno = ENOMEM; + return NULL; + } + for (i = 0; ret[i]; i++) { + ret[i] = toupper((unsigned char)ret[i]); + } + return ret; +} + +/* + we accept either 'dn' or 'distinguishedName' for a distinguishedName +*/ +int ldb_attr_dn(const char *attr) +{ + if (ldb_attr_cmp(attr, "dn") == 0 || + ldb_attr_cmp(attr, "distinguishedName") == 0) { + return 0; + } + return -1; +} diff --git a/lib/ldb/common/qsort.c b/lib/ldb/common/qsort.c new file mode 100644 index 00000000000..1a0b886b8c2 --- /dev/null +++ b/lib/ldb/common/qsort.c @@ -0,0 +1,251 @@ +/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + 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 2.1 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 + Lesser 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; if not, see . */ + +/* If you consider tuning this algorithm, you should consult first: + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +/* Modified to be used in samba4 by + * Simo Sorce 2005 + */ + +#include "ldb_private.h" + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +void ldb_qsort (void *const pbase, size_t total_elems, size_t size, + void *opaque, ldb_qsort_cmp_fn_t cmp) +{ + register char *base_ptr = (char *) pbase; + + const size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack; + + PUSH (NULL, NULL); + + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) + SWAP (mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + register char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} diff --git a/lib/ldb/configure b/lib/ldb/configure new file mode 100755 index 00000000000..82146fe109a --- /dev/null +++ b/lib/ldb/configure @@ -0,0 +1,21 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +if [ -f $PREVPATH/../../buildtools/bin/waf ]; then + WAF=../../buildtools/bin/waf +elif [ -f $PREVPATH/buildtools/bin/waf ]; then + WAF=./buildtools/bin/waf +else + echo "ldb: Unable to find waf" + exit 1 +fi + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd . || exit 1 +$WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/lib/ldb/docs/builddocs.sh b/lib/ldb/docs/builddocs.sh new file mode 100755 index 00000000000..449dcb26815 --- /dev/null +++ b/lib/ldb/docs/builddocs.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# build ldb docs +# tridge@samba.org August 2006 + +XSLTPROC="$1" +SRCDIR="$2" + +if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then + echo "xsltproc not installed" + exit 0 +fi + +MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" +HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" + +mkdir -p man + +for f in $SRCDIR/man/*.xml; do + base=`basename $f .xml` + out=man/"`basename $base`" + if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then + echo Processing manpage $f + $XSLTPROC --nonet -o "$out" "$MANXSL" $f + ret=$? + if [ "$ret" = "4" ]; then + echo "ignoring stylesheet error 4 for $MANXSL" + exit 0 + fi + if [ "$ret" != "0" ]; then + echo "xsltproc failed with error $ret" + exit $ret + fi + fi +done + +for f in $SRCDIR/man/*.xml; do + base=`basename $f .xml` + out=man/"`basename $base`".html + if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then + echo Processing html $f + $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f + ret=$? + if [ "$ret" = "4" ]; then + echo "ignoring stylesheet error 4 for $HTMLXSL" + exit 0 + fi + if [ "$ret" != "0" ]; then + echo "xsltproc failed with error $ret" + exit $ret + fi + fi +done diff --git a/lib/ldb/docs/design.txt b/lib/ldb/docs/design.txt new file mode 100644 index 00000000000..0bb278b5b42 --- /dev/null +++ b/lib/ldb/docs/design.txt @@ -0,0 +1,41 @@ +The list of indexed fields +-------------------------- + +dn=@INDEXLIST + list of field names that are indexed + + contains fields of type @IDXATTR which contain attriute names + of indexed fields + + +Data records +------------ + +for each user record in the db there is: + main record + key: DN=dn + data: packed attribute/value list + + a index record for each indexed field in the record + + +Index Records +------------- + +The index records contain the list of dn's that contain records +matching the index key + +All index records are of the form: + dn=@INDEX:field:value + +and contain fields of type @IDX which are the dns of the records +that have that value for some attribute + + +Search Expressions +------------------ + +Very similar to LDAP search expressions, but does not allow ~=, <= or >= + + attrib0 := (field=value) + attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib diff --git a/lib/ldb/docs/installdocs.sh b/lib/ldb/docs/installdocs.sh new file mode 100755 index 00000000000..6cc7b74ad51 --- /dev/null +++ b/lib/ldb/docs/installdocs.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# install ldb docs +# tridge@samba.org August 2006 + +MANDIR="$1" + +MAN1="`/bin/ls man/*.1`" +MAN3="`/bin/ls man/*.3`" + +if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then + echo "No manpages have been built" + exit 0 +fi + +mkdir -p "$MANDIR/man1" "$MANDIR/man3" +cp $MAN1 "$MANDIR/man1/" || exit 1 +cp $MAN3 "$MANDIR/man3/" || exit 1 diff --git a/lib/ldb/examples.dox b/lib/ldb/examples.dox new file mode 100644 index 00000000000..ef4b4f0a400 --- /dev/null +++ b/lib/ldb/examples.dox @@ -0,0 +1,16 @@ +/** \example ldbreader.c + +The code below shows a simple LDB application. + +It lists / dumps the records in a LDB database to standard output. + +*/ + + +/** \example ldifreader.c + +The code below shows a simple LDB application. + +It lists / dumps the entries in an LDIF file to standard output. + +*/ diff --git a/lib/ldb/examples/ldbreader.c b/lib/ldb/examples/ldbreader.c new file mode 100644 index 00000000000..3496baf4ce2 --- /dev/null +++ b/lib/ldb/examples/ldbreader.c @@ -0,0 +1,122 @@ +/* + example code for the ldb database library + + Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 + + ** 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 . +*/ + +/** \example ldbreader.c + +The code below shows a simple LDB application. + +It lists / dumps the records in a LDB database to standard output. + +*/ + +#include "ldb.h" + +/* + ldb_ldif_write takes a function pointer to a custom output + function. This version is about as simple as the output function can + be. In a more complex example, you'd likely be doing something with + the private data function (e.g. holding a file handle). +*/ +static int vprintf_fn(void *private_data, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + /* We just write to standard output */ + retval = vprintf(fmt, ap); + va_end(ap); + /* Note that the function should return the number of + bytes written, or a negative error code */ + return retval; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + const char *expression = "(dn=*)"; + struct ldb_result *resultMsg; + int i; + + /* + This is the always the first thing you want to do in an LDB + application - initialise up the context structure. + + Note that you can use the context structure as a parent + for talloc allocations as well + */ + ldb = ldb_init(NULL, NULL); + + /* + We now open the database. In this example we just hard code the connection path. + + Also note that the database is being opened read-only. This means that the + call will fail unless the database already exists. + */ + if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ + printf("Problem on connection\n"); + exit(-1); + } + + /* + At this stage we have an open database, and can start using it. It is opened + read-only, so a query is possible. + + We construct a search that just returns all the (sensible) contents. You can do + quite fine grained results with the LDAP search syntax, however it is a bit + confusing to start with. See RFC2254. + */ + if (LDB_SUCCESS != ldb_search(ldb, ldb, &resultMsg, + NULL, LDB_SCOPE_DEFAULT, NULL, + "%s", expression)) { + printf("Problem in search\n"); + exit(-1); + } + + printf("%i records returned\n", resultMsg->count); + + /* + We can now iterate through the results, writing them out + (to standard output) with our custom output routine as defined + at the top of this file + */ + for (i = 0; i < resultMsg->count; ++i) { + struct ldb_ldif ldifMsg; + + printf("Message: %i\n", i+1); + + ldifMsg.changetype = LDB_CHANGETYPE_NONE; + ldifMsg.msg = resultMsg->msgs[i]; + ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); + } + + /* + There are two objects to clean up - the result from the + ldb_search() query, and the original ldb context. + */ + talloc_free(resultMsg); + + talloc_free(ldb); + + return 0; +} diff --git a/lib/ldb/examples/ldifreader.c b/lib/ldb/examples/ldifreader.c new file mode 100644 index 00000000000..dcd9daf8121 --- /dev/null +++ b/lib/ldb/examples/ldifreader.c @@ -0,0 +1,125 @@ +/* + example code for the ldb database library + + Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 + + ** 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 . +*/ + +/** \example ldifreader.c + +The code below shows a simple LDB application. + +It lists / dumps the entries in an LDIF file to standard output. + +*/ + +#include "ldb.h" + +/* + ldb_ldif_write takes a function pointer to a custom output + function. This version is about as simple as the output function can + be. In a more complex example, you'd likely be doing something with + the private data function (e.g. holding a file handle). +*/ +static int vprintf_fn(void *private_data, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + /* We just write to standard output */ + retval = vprintf(fmt, ap); + va_end(ap); + /* Note that the function should return the number of + bytes written, or a negative error code */ + return retval; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + FILE *fileStream; + struct ldb_ldif *ldifMsg; + + if (argc != 2) { + printf("Usage %s filename.ldif\n", argv[0]); + exit(1); + } + + /* + This is the always the first thing you want to do in an LDB + application - initialise up the context structure. + + Note that you can use the context structure as a parent + for talloc allocations as well + */ + ldb = ldb_init(NULL, NULL); + + fileStream = fopen(argv[1], "r"); + if (0 == fileStream) { + perror(argv[1]); + exit(1); + } + + /* + We now work through the filestream to get each entry. + */ + while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { + /* + Each message has a particular change type. For Add, + Modify and Delete, this will also appear in the + output listing (as changetype: add, changetype: + modify or changetype:delete, respectively). + */ + switch (ldifMsg->changetype) { + case LDB_CHANGETYPE_NONE: + printf("ChangeType: None\n"); + break; + case LDB_CHANGETYPE_ADD: + printf("ChangeType: Add\n"); + break; + case LDB_CHANGETYPE_MODIFY: + printf("ChangeType: Modify\n"); + break; + case LDB_CHANGETYPE_DELETE: + printf("ChangeType: Delete\n"); + break; + default: + printf("ChangeType: Unknown\n"); + } + + /* + We can now write out the results, using our custom + output routine as defined at the top of this file. + */ + ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); + + /* + Clean up the message + */ + ldb_ldif_read_free(ldb, ldifMsg); + } + + /* + Clean up the context + */ + talloc_free(ldb); + + return 0; +} diff --git a/lib/ldb/include/dlinklist.h b/lib/ldb/include/dlinklist.h new file mode 100644 index 00000000000..1c577bb6b90 --- /dev/null +++ b/lib/ldb/include/dlinklist.h @@ -0,0 +1,185 @@ +/* + Unix SMB/CIFS implementation. + some simple double linked list macros + + Copyright (C) Andrew Tridgell 1998-2010 + + ** 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 . +*/ + +/* To use these macros you must have a structure containing a next and + prev pointer */ + +#ifndef _DLINKLIST_H +#define _DLINKLIST_H + +/* + February 2010 - changed list format to have a prev pointer from the + list head. This makes DLIST_ADD_END() O(1) even though we only have + one list pointer. + + The scheme is as follows: + + 1) with no entries in the list: + list_head == NULL + + 2) with 1 entry in the list: + list_head->next == NULL + list_head->prev == list_head + + 3) with 2 entries in the list: + list_head->next == element2 + list_head->prev == element2 + element2->prev == list_head + element2->next == NULL + + 4) with N entries in the list: + list_head->next == element2 + list_head->prev == elementN + elementN->prev == element{N-1} + elementN->next == NULL + + This allows us to find the tail of the list by using + list_head->prev, which means we can add to the end of the list in + O(1) time + + + Note that the 'type' arguments below are no longer needed, but + are kept for now to prevent an incompatible argument change + */ + + +/* + add an element at the front of a list +*/ +#define DLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (p)->prev = (list) = (p); \ + (p)->next = NULL; \ + } else { \ + (p)->prev = (list)->prev; \ + (list)->prev = (p); \ + (p)->next = (list); \ + (list) = (p); \ + } \ +} while (0) + +/* + remove an element from a list + Note that the element doesn't have to be in the list. If it + isn't then this is a no-op +*/ +#define DLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + (list) = (p)->next; \ + } else if ((list) && (p) == (list)->prev) { \ + (p)->prev->next = NULL; \ + (list)->prev = (p)->prev; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) != (list)) (p)->next = (p)->prev = NULL; \ +} while (0) + +/* + find the head of the list given any element in it. + Note that this costs O(N), so you should avoid this macro + if at all possible! +*/ +#define DLIST_HEAD(p, result_head) \ +do { \ + (result_head) = (p); \ + while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ +} while(0) + +/* return the last element in the list */ +#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) + +/* return the previous element in the list. */ +#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) + +/* insert 'p' after the given element 'el' in a list. If el is NULL then + this is the same as a DLIST_ADD() */ +#define DLIST_ADD_AFTER(list, p, el) \ +do { \ + if (!(list) || !(el)) { \ + DLIST_ADD(list, p); \ + } else { \ + (p)->prev = (el); \ + (p)->next = (el)->next; \ + (el)->next = (p); \ + if ((p)->next) (p)->next->prev = (p); \ + if ((list)->prev == (el)) (list)->prev = (p); \ + }\ +} while (0) + + +/* + add to the end of a list. + Note that 'type' is ignored +*/ +#define DLIST_ADD_END(list, p, type) \ +do { \ + if (!(list)) { \ + DLIST_ADD(list, p); \ + } else { \ + DLIST_ADD_AFTER(list, p, (list)->prev); \ + } \ +} while (0) + +/* promote an element to the from of a list */ +#define DLIST_PROMOTE(list, p) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD(list, p); \ +} while (0) + +/* + demote an element to the end of a list. + Note that 'type' is ignored +*/ +#define DLIST_DEMOTE(list, p, type) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD_END(list, p, NULL); \ +} while (0) + +/* + concatenate two lists - putting all elements of the 2nd list at the + end of the first list. + Note that 'type' is ignored +*/ +#define DLIST_CONCATENATE(list1, list2, type) \ +do { \ + if (!(list1)) { \ + (list1) = (list2); \ + } else { \ + (list1)->prev->next = (list2); \ + if (list2) { \ + void *_tmplist = (void *)(list1)->prev; \ + (list1)->prev = (list2)->prev; \ + (list2)->prev = _tmplist; \ + } \ + } \ +} while (0) + +#endif /* _DLINKLIST_H */ diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h new file mode 100644 index 00000000000..d745f377b61 --- /dev/null +++ b/lib/ldb/include/ldb.h @@ -0,0 +1,2254 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2005-2006 + + ** 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 header + * + * Description: defines for base ldb API + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +/** + \file ldb.h Samba's ldb database + + This header file provides the main API for ldb. +*/ + +#ifndef _LDB_H_ + +/*! \cond DOXYGEN_IGNORE */ +#define _LDB_H_ 1 +/*! \endcond */ + +#include +#include +#include +#include +#include + +/* + major restrictions as compared to normal LDAP: + + - each record must have a unique key field + - the key must be representable as a NULL terminated C string and may not + contain a comma or braces + + major restrictions as compared to tdb: + + - no explicit locking calls, but we have transactions when using ldb_tdb + +*/ + +#ifndef ldb_val +/** + Result value + + An individual lump of data in a result comes in this format. The + pointer will usually be to a UTF-8 string if the application is + sensible, but it can be to anything you like, including binary data + blobs of arbitrary size. + + \note the data is null (0x00) terminated, but the length does not + include the terminator. +*/ +struct ldb_val { + uint8_t *data; /*!< result data */ + size_t length; /*!< length of data */ +}; +#endif + +/*! \cond DOXYGEN_IGNORE */ +#ifndef PRINTF_ATTRIBUTE +#define PRINTF_ATTRIBUTE(a,b) +#endif + +#ifndef _DEPRECATED_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif +/*! \endcond */ + +/* opaque ldb_dn structures, see ldb_dn.c for internals */ +struct ldb_dn_component; +struct ldb_dn; + +/** + There are a number of flags that are used with ldap_modify() in + ldb_message_element.flags fields. The LDB_FLAGS_MOD_ADD, + LDB_FLAGS_MOD_DELETE and LDB_FLAGS_MOD_REPLACE flags are used in + ldap_modify() calls to specify whether attributes are being added, + deleted or modified respectively. +*/ +#define LDB_FLAG_MOD_MASK 0x3 + +/** + use this to extract the mod type from the operation + */ +#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) + +/** + Flag value used in ldap_modify() to indicate that attributes are + being added. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_ADD 1 + +/** + Flag value used in ldap_modify() to indicate that attributes are + being replaced. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_REPLACE 2 + +/** + Flag value used in ldap_modify() to indicate that attributes are + being deleted. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_DELETE 3 + +/** + flag bits on an element usable only by the internal implementation +*/ +#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 + +/** + OID for logic AND comaprison. + + This is the well known object ID for a logical AND comparitor. +*/ +#define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" + +/** + OID for logic OR comparison. + + This is the well known object ID for a logical OR comparitor. +*/ +#define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" + +/** + results are given back as arrays of ldb_message_element +*/ +struct ldb_message_element { + unsigned int flags; + const char *name; + unsigned int num_values; + struct ldb_val *values; +}; + + +/** + a ldb_message represents all or part of a record. It can contain an arbitrary + number of elements. +*/ +struct ldb_message { + struct ldb_dn *dn; + unsigned int num_elements; + struct ldb_message_element *elements; +}; + +enum ldb_changetype { + LDB_CHANGETYPE_NONE=0, + LDB_CHANGETYPE_ADD, + LDB_CHANGETYPE_DELETE, + LDB_CHANGETYPE_MODIFY, + LDB_CHANGETYPE_MODRDN +}; + +/** + LDIF record + + This structure contains a LDIF record, as returned from ldif_read() + and equivalent functions. +*/ +struct ldb_ldif { + enum ldb_changetype changetype; /*!< The type of change */ + struct ldb_message *msg; /*!< The changes */ +}; + +enum ldb_scope {LDB_SCOPE_DEFAULT=-1, + LDB_SCOPE_BASE=0, + LDB_SCOPE_ONELEVEL=1, + LDB_SCOPE_SUBTREE=2}; + +struct ldb_context; +struct tevent_context; + +/* debugging uses one of the following levels */ +enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, + LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; + +/** + the user can optionally supply a debug function. The function + is based on the vfprintf() style of interface, but with the addition + of a severity level +*/ +struct ldb_debug_ops { + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + void *context; +}; + +/** + The user can optionally supply a custom utf8 functions, + to handle comparisons and casefolding. +*/ +struct ldb_utf8_fns { + void *context; + char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); +}; + +/** + Flag value for database connection mode. + + If LDB_FLG_RDONLY is used in ldb_connect, then the database will be + opened read-only, if possible. +*/ +#define LDB_FLG_RDONLY 1 + +/** + Flag value for database connection mode. + + If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be + opened without synchronous operations, if possible. +*/ +#define LDB_FLG_NOSYNC 2 + +/** + Flag value to specify autoreconnect mode. + + If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will + be opened in a way that makes it try to auto reconnect if the + connection is dropped (actually make sense only with ldap). +*/ +#define LDB_FLG_RECONNECT 4 + +/** + Flag to tell backends not to use mmap +*/ +#define LDB_FLG_NOMMAP 8 + +/** + Flag to tell ldif handlers not to force encoding of binary + structures in base64 +*/ +#define LDB_FLG_SHOW_BINARY 16 + +/** + Flags to enable ldb tracing +*/ +#define LDB_FLG_ENABLE_TRACING 32 + +/* + structures for ldb_parse_tree handling code +*/ +enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, + LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, + LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, + LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; + +struct ldb_parse_tree { + enum ldb_parse_op operation; + union { + struct { + struct ldb_parse_tree *child; + } isnot; + struct { + const char *attr; + struct ldb_val value; + } equality; + struct { + const char *attr; + int start_with_wildcard; + int end_with_wildcard; + struct ldb_val **chunks; + } substring; + struct { + const char *attr; + } present; + struct { + const char *attr; + struct ldb_val value; + } comparison; + struct { + const char *attr; + int dnAttributes; + char *rule_id; + struct ldb_val value; + } extended; + struct { + unsigned int num_elements; + struct ldb_parse_tree **elements; + } list; + } u; +}; + +struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); +char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); + +/** + Encode a binary blob + + This function encodes a binary blob using the encoding rules in RFC + 2254 (Section 4). This function also escapes any non-printable + characters. + + \param mem_ctx the memory context to allocate the return string in. + \param val the (potentially) binary data to be encoded + + \return the encoded data as a null terminated string + + \sa RFC 2252. +*/ +char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val); + +/** + Encode a string + + This function encodes a string using the encoding rules in RFC 2254 + (Section 4). This function also escapes any non-printable + characters. + + \param mem_ctx the memory context to allocate the return string in. + \param string the string to be encoded + + \return the encoded data as a null terminated string + + \sa RFC 2252. +*/ +char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string); + +/* + functions for controlling attribute handling +*/ +typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); +typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); +struct ldb_schema_attribute; +typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, + const struct ldb_schema_attribute *a, + const struct ldb_val *, const struct ldb_val *, bool *matched); + +/* + attribute handler structure + + attr -> The attribute name + ldif_read_fn -> convert from ldif to binary format + ldif_write_fn -> convert from binary to ldif format + canonicalise_fn -> canonicalise a value, for use by indexing and dn construction + comparison_fn -> compare two values +*/ + +struct ldb_schema_syntax { + const char *name; + ldb_attr_handler_t ldif_read_fn; + ldb_attr_handler_t ldif_write_fn; + ldb_attr_handler_t canonicalise_fn; + ldb_attr_comparison_t comparison_fn; + ldb_attr_operator_t operator_fn; +}; + +struct ldb_schema_attribute { + const char *name; + unsigned flags; + const struct ldb_schema_syntax *syntax; +}; + +const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, + const char *name); + +struct ldb_dn_extended_syntax { + const char *name; + ldb_attr_handler_t read_fn; + ldb_attr_handler_t write_clear_fn; + ldb_attr_handler_t write_hex_fn; +}; + +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name); + +/** + The attribute is not returned by default +*/ +#define LDB_ATTR_FLAG_HIDDEN (1<<0) + +/* the attribute handler name should be freed when released */ +#define LDB_ATTR_FLAG_ALLOCATED (1<<1) + +/** + The attribute is supplied by the application and should not be removed +*/ +#define LDB_ATTR_FLAG_FIXED (1<<2) + +/* + when this is set, attempts to create two records which have the same + value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS + */ +#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3) + +/* + when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION + */ +#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) + +/** + LDAP attribute syntax for a DN + + This is the well-known LDAP attribute syntax for a DN. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" + +/** + LDAP attribute syntax for a Directory String + + This is the well-known LDAP attribute syntax for a Directory String. + + \sa RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" + +/** + LDAP attribute syntax for an integer + + This is the well-known LDAP attribute syntax for an integer. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" + +/** + LDAP attribute syntax for a boolean + + This is the well-known LDAP attribute syntax for a boolean. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_BOOLEAN "1.3.6.1.4.1.1466.115.121.1.7" + +/** + LDAP attribute syntax for an octet string + + This is the well-known LDAP attribute syntax for an octet string. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" + +/** + LDAP attribute syntax for UTC time. + + This is the well-known LDAP attribute syntax for a UTC time. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" + +#define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" + +/* sorting helpers */ +typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); + +/* Individual controls */ + +/** + OID for getting and manipulating attributes from the ldb + without interception in the operational module. + It can be used to access attribute that used to be stored in the sam + and that are now calculated. +*/ +#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" +#define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" + +/** + OID for recalculate SD control. This control force the + dsdb code to recalculate the SD of the object as if the + object was just created. + +*/ +#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" +#define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" + +/** + REVEAL_INTERNALS is used to reveal internal attributes and DN + components which are not normally shown to the user +*/ +#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" +#define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" + +/** + LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations + that are performed by the system, but with a user's credentials, e.g. + updating prefix map +*/ +#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" + +/** + LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is + mainly thought to be used for the provisioning. +*/ +#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" +#define LDB_CONTROL_PROVISION_NAME "provision" + +/* AD controls */ + +/** + OID for the paged results control. This control is included in the + searchRequest and searchResultDone messages as part of the controls + field of the LDAPMessage, as defined in Section 4.1.12 of + LDAP v3. + + \sa RFC 2696. +*/ +#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" +#define LDB_CONTROL_PAGED_RESULTS_NAME "paged_results" + +/** + OID for specifying the returned elements of the ntSecurityDescriptor + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" +#define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" + +/** + OID for specifying an advanced scope for the search (one partition) + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" +#define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" + +/** + OID for specifying an advanced scope for a search + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" +#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" + +/** + OID for notification + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" +#define LDB_CONTROL_NOTIFICATION_NAME "notification" + +/** + OID for performing subtree deletes + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" +#define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" + +/** + OID for getting deleted objects + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" +#define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" + +/** + OID for getting recycled objects + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" +#define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" + +/** + OID for getting deactivated linked attributes + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" +#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" + +/** + OID for extended DN + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" +#define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" + +/** + OID for LDAP server sort result extension. + + This control is included in the searchRequest message as part of + the controls field of the LDAPMessage, as defined in Section 4.1.12 + of LDAP v3. The controlType is set to + "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or + FALSE (where absent is also equivalent to FALSE) at the client's + option. + + \sa RFC 2891. +*/ +#define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" +#define LDB_CONTROL_SERVER_SORT_NAME "server_sort" + +/** + OID for LDAP server sort result response extension. + + This control is included in the searchResultDone message as part of + the controls field of the LDAPMessage, as defined in Section 4.1.12 of + LDAP v3. + + \sa RFC 2891. +*/ +#define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" +#define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" + +/** + OID for LDAP Attribute Scoped Query extension. + + This control is included in SearchRequest or SearchResponse + messages as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" +#define LDB_CONTROL_ASQ_NAME "asq" + +/** + OID for LDAP Directory Sync extension. + + This control is included in SearchRequest or SearchResponse + messages as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" +#define LDB_CONTROL_DIRSYNC_NAME "dirsync" + + +/** + OID for LDAP Virtual List View Request extension. + + This control is included in SearchRequest messages + as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" +#define LDB_CONTROL_VLV_REQ_NAME "vlv" + +/** + OID for LDAP Virtual List View Response extension. + + This control is included in SearchResponse messages + as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" +#define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" + +/** + OID to let modifies don't give an error when adding an existing + attribute with the same value or deleting an nonexisting one attribute + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" +#define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" + +/** + OID to allow the server to be more 'fast and loose' with the data being added. + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" + +/** + Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" +#define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" + +/* Other standardised controls */ + +/** + OID for the allowing client to request temporary relaxed + enforcement of constraints of the x.500 model. + + Mainly used for the OpenLDAP backend. + + \sa draft managedit. +*/ +#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" +#define LDB_CONTROL_RELAX_NAME "relax" + +/* Extended operations */ + +/** + OID for LDAP Extended Operation SEQUENCE_NUMBER + + This extended operation is used to retrieve the extended sequence number. +*/ +#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" + +/** + OID for LDAP Extended Operation PASSWORD_CHANGE. + + This Extended operation is used to allow user password changes by the user + itself. +*/ +#define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" + + +/** + OID for LDAP Extended Operation FAST_BIND + + This Extended operations is used to perform a fast bind. +*/ +#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" + +/** + OID for LDAP Extended Operation START_TLS. + + This Extended operation is used to start a new TLS channel on top of a clear + text channel. +*/ +#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" + +/** + OID for LDAP Extended Operation DYNAMIC_REFRESH. + + This Extended operation is used to create and maintain objects which exist + only a specific time, e.g. when a certain client or a certain person is + logged in. Data refreshes have to be periodically sent in a specific + interval. Otherwise the entry is going to be removed. +*/ +#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" + +struct ldb_sd_flags_control { + /* + * request the owner 0x00000001 + * request the group 0x00000002 + * request the DACL 0x00000004 + * request the SACL 0x00000008 + */ + unsigned secinfo_flags; +}; + +/* + * DOMAIN_SCOPE 0x00000001 + * this limits the search to one partition, + * and no referrals will be returned. + * (Note this doesn't limit the entries by there + * objectSid belonging to a domain! Builtin and Foreign Sids + * are still returned) + * + * PHANTOM_ROOT 0x00000002 + * this search on the whole tree on a domain controller + * over multiple partitions without referrals. + * (This is the default behavior on the Global Catalog Port) + */ + +#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001 +#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002 + +struct ldb_search_options_control { + unsigned search_options; +}; + +struct ldb_paged_control { + int size; + int cookie_len; + char *cookie; +}; + +struct ldb_extended_dn_control { + int type; +}; + +struct ldb_server_sort_control { + const char *attributeName; + const char *orderingRule; + int reverse; +}; + +struct ldb_sort_resp_control { + int result; + char *attr_desc; +}; + +struct ldb_asq_control { + int request; + char *source_attribute; + int src_attr_len; + int result; +}; + +struct ldb_dirsync_control { + int flags; + int max_attributes; + int cookie_len; + char *cookie; +}; + +struct ldb_vlv_req_control { + int beforeCount; + int afterCount; + int type; + union { + struct { + int offset; + int contentCount; + } byOffset; + struct { + int value_len; + char *value; + } gtOrEq; + } match; + int ctxid_len; + char *contextId; +}; + +struct ldb_vlv_resp_control { + int targetPosition; + int contentCount; + int vlv_result; + int ctxid_len; + char *contextId; +}; + +struct ldb_control { + const char *oid; + int critical; + void *data; +}; + +enum ldb_request_type { + LDB_SEARCH, + LDB_ADD, + LDB_MODIFY, + LDB_DELETE, + LDB_RENAME, + LDB_EXTENDED, + LDB_REQ_REGISTER_CONTROL, + LDB_REQ_REGISTER_PARTITION +}; + +enum ldb_reply_type { + LDB_REPLY_ENTRY, + LDB_REPLY_REFERRAL, + LDB_REPLY_DONE +}; + +enum ldb_wait_type { + LDB_WAIT_ALL, + LDB_WAIT_NONE +}; + +enum ldb_state { + LDB_ASYNC_INIT, + LDB_ASYNC_PENDING, + LDB_ASYNC_DONE +}; + +struct ldb_extended { + const char *oid; + void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ +}; + +enum ldb_sequence_type { + LDB_SEQ_HIGHEST_SEQ, + LDB_SEQ_HIGHEST_TIMESTAMP, + LDB_SEQ_NEXT +}; + +#define LDB_SEQ_GLOBAL_SEQUENCE 0x01 +#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 + +struct ldb_seqnum_request { + enum ldb_sequence_type type; +}; + +struct ldb_seqnum_result { + uint64_t seq_num; + uint32_t flags; +}; + +struct ldb_result { + unsigned int count; + struct ldb_message **msgs; + struct ldb_extended *extended; + struct ldb_control **controls; + char **refs; +}; + +struct ldb_reply { + int error; + enum ldb_reply_type type; + struct ldb_message *message; + struct ldb_extended *response; + struct ldb_control **controls; + char *referral; +}; + +struct ldb_request; +struct ldb_handle; + +struct ldb_search { + struct ldb_dn *base; + enum ldb_scope scope; + struct ldb_parse_tree *tree; + const char * const *attrs; + struct ldb_result *res; +}; + +struct ldb_add { + const struct ldb_message *message; +}; + +struct ldb_modify { + const struct ldb_message *message; +}; + +struct ldb_delete { + struct ldb_dn *dn; +}; + +struct ldb_rename { + struct ldb_dn *olddn; + struct ldb_dn *newdn; +}; + +struct ldb_register_control { + const char *oid; +}; + +struct ldb_register_partition { + struct ldb_dn *dn; +}; + +typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *); + +struct ldb_request { + + enum ldb_request_type operation; + + union { + struct ldb_search search; + struct ldb_add add; + struct ldb_modify mod; + struct ldb_delete del; + struct ldb_rename rename; + struct ldb_extended extended; + struct ldb_register_control reg_control; + struct ldb_register_partition reg_partition; + } op; + + struct ldb_control **controls; + + void *context; + ldb_request_callback_t callback; + + int timeout; + time_t starttime; + struct ldb_handle *handle; +}; + +int ldb_request(struct ldb_context *ldb, struct ldb_request *request); +int ldb_request_done(struct ldb_request *req, int status); +bool ldb_request_is_done(struct ldb_request *req); + +int ldb_modules_wait(struct ldb_handle *handle); +int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); + +int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); +int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); +void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); +void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); +struct tevent_context; +void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev); +struct tevent_context * ldb_get_event_context(struct ldb_context *ldb); + +/** + Initialise ldbs' global information + + This is required before any other LDB call + + \return 0 if initialisation succeeded, -1 otherwise +*/ +int ldb_global_init(void); + +/** + Initialise an ldb context + + This is required before any other LDB call. + + \param mem_ctx pointer to a talloc memory context. Pass NULL if there is + no suitable context available. + + \return pointer to ldb_context that should be free'd (using talloc_free()) + at the end of the program. +*/ +struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); + +/** + Connect to a database. + + This is typically called soon after ldb_init(), and is required prior to + any search or database modification operations. + + The URL can be one of the following forms: + - tdb://path + - ldapi://path + - ldap://host + - sqlite://path + + \param ldb the context associated with the database (from ldb_init()) + \param url the URL of the database to connect to, as noted above + \param flags a combination of LDB_FLG_* to modify the connection behaviour + \param options backend specific options - passed uninterpreted to the backend + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note It is an error to connect to a database that does not exist in readonly mode + (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[]); + +/* + return an automatic basedn from the rootDomainNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb); + +/* + return an automatic basedn from the configurationNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb); + +/* + return an automatic basedn from the schemaNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb); + +/* + return an automatic baseDN from the defaultNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); + +/** + The default async search callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note this function expects req->context to always be an struct ldb_result pointer + AND a talloc context, this function will steal on the context each message + from the ares reply passed on by the async core so that in the end all the + messages will be in the context (ldb_result) memory tree. + Freeing the passed context (ldb_result tree) will free all the resources + (the request need to be freed separately and the result doe not depend on the + request that can be freed as sson as the search request is finished) +*/ + +int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +/** + The default async extended operation callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +/** + Helper function to build a search request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) + \param scope the search scope for the query + \param expression the search expression to use for this query + \param attrs the search attributes for the query (pass NULL if none required) + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_search_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + const char *expression, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +int ldb_build_search_req_ex(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build an add request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param message contains the entry to be added + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_add_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a modify request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param message contains the entry to be modified + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_mod_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a delete request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param dn the DN to be deleted + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_del_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a rename request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param olddn the old DN + \param newdn the new DN + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_rename_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Add a ldb_control to a ldb_request + + \param req the request struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data); + +/** + replace a ldb_control in a ldb_request + + \param req the request struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); + +/** + check if a control with the specified "oid" exist and return it + \param req the request struct where to add the control + \param oid the object identifier of the control as string + + \return the control, NULL if not found +*/ +struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); + +/** + check if a control with the specified "oid" exist and return it + \param rep the reply struct where to add the control + \param oid the object identifier of the control as string + + \return the control, NULL if not found +*/ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); + +/** + Search the database + + This function searches the database, and returns + records that match an LDAP-like search expression + + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx the memory context to use for the request and the results + \param result the return result + \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) + \param scope the search scope for the query + \param attrs the search attributes for the query (pass NULL if none required) + \param exp_fmt the search expression to use for this query (printf like) + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note use talloc_free() to free the ldb_result returned +*/ +int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); + +/** + Add a record to the database. + + This function adds a record to the database. This function will fail + if a record with the specified class and key already exists in the + database. + + \param ldb the context associated with the database (from + ldb_init()) + \param message the message containing the record to add. + + \return result code (LDB_SUCCESS if the record was added, otherwise + a failure code) +*/ +int ldb_add(struct ldb_context *ldb, + const struct ldb_message *message); + +/** + Modify the specified attributes of a record + + This function modifies a record that is in the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param message the message containing the changes required. + + \return result code (LDB_SUCCESS if the record was modified as + requested, otherwise a failure code) +*/ +int ldb_modify(struct ldb_context *ldb, + const struct ldb_message *message); + +/** + Rename a record in the database + + This function renames a record in the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param olddn the DN for the record to be renamed. + \param newdn the new DN + + \return result code (LDB_SUCCESS if the record was renamed as + requested, otherwise a failure code) +*/ +int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn); + +/** + Delete a record from the database + + This function deletes a record from the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param dn the DN for the record to be deleted. + + \return result code (LDB_SUCCESS if the record was deleted, + otherwise a failure code) +*/ +int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn); + +/** + The default async extended operation callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note this function expects req->context to always be an struct ldb_result pointer + AND a talloc context, this function will steal on the context each message + from the ares reply passed on by the async core so that in the end all the + messages will be in the context (ldb_result) memory tree. + Freeing the passed context (ldb_result tree) will free all the resources + (the request need to be freed separately and the result doe not depend on the + request that can be freed as sson as the search request is finished) +*/ + +int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares); + + +/** + Helper function to build a extended request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param oid the OID of the extended operation. + \param data a void pointer a the extended operation specific parameters, + it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_build_extended_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *oid, + void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + call an extended operation + + This function deletes a record from the database. + + \param ldb the context associated with the database (from ldb_init()) + \param oid the OID of the extended operation. + \param data a void pointer a the extended operation specific parameters, + it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it + \param res the result of the extended operation + + \return result code (LDB_SUCCESS if the extended operation returned fine, + otherwise a failure code) +*/ +int ldb_extended(struct ldb_context *ldb, + const char *oid, + void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ + struct ldb_result **res); + +/** + Obtain current/next database sequence number +*/ +int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); + +/** + start a transaction +*/ +int ldb_transaction_start(struct ldb_context *ldb); + +/** + first phase of two phase commit + */ +int ldb_transaction_prepare_commit(struct ldb_context *ldb); + +/** + commit a transaction +*/ +int ldb_transaction_commit(struct ldb_context *ldb); + +/** + cancel a transaction +*/ +int ldb_transaction_cancel(struct ldb_context *ldb); + +/* + cancel a transaction with no error if no transaction is pending + used when we fork() to clear any parent transactions +*/ +int ldb_transaction_cancel_noerr(struct ldb_context *ldb); + + +/** + return extended error information from the last call +*/ +const char *ldb_errstring(struct ldb_context *ldb); + +/** + return a string explaining what a ldb error constant meancs +*/ +const char *ldb_strerror(int ldb_err); + +/** + setup the default utf8 functions + FIXME: these functions do not yet handle utf8 +*/ +void ldb_set_utf8_default(struct ldb_context *ldb); + +/** + Casefold a string + + \param ldb the ldb context + \param mem_ctx the memory context to allocate the result string + memory from. + \param s the string that is to be folded + \return a copy of the string, converted to upper case + + \note The default function is not yet UTF8 aware. Provide your own + set of functions through ldb_set_utf8_fns() +*/ +char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n); + +/** + Check the attribute name is valid according to rfc2251 + \param s the string to check + + \return 1 if the name is ok +*/ +int ldb_valid_attr_name(const char *s); + +/* + ldif manipulation functions +*/ + +/** + Write an LDIF message + + This function writes an LDIF message using a caller supplied write + function. + + \param ldb the ldb context (from ldb_init()) + \param fprintf_fn a function pointer for the write function. This must take + a private data pointer, followed by a format string, and then a variable argument + list. + \param private_data pointer that will be provided back to the write + function. This is useful for maintaining state or context. + \param ldif the message to write out + + \return the total number of bytes written, or an error code as returned + from the write function. + + \sa ldb_ldif_write_file for a more convenient way to write to a + file stream. + + \sa ldb_ldif_read for the reader equivalent to this function. +*/ +int ldb_ldif_write(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), + void *private_data, + const struct ldb_ldif *ldif); + +/** + Clean up an LDIF message + + This function cleans up a LDIF message read using ldb_ldif_read() + or related functions (such as ldb_ldif_read_string() and + ldb_ldif_read_file(). + + \param ldb the ldb context (from ldb_init()) + \param msg the message to clean up and free + +*/ +void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); + +/** + Read an LDIF message + + This function creates an LDIF message using a caller supplied read + function. + + \param ldb the ldb context (from ldb_init()) + \param fgetc_fn a function pointer for the read function. This must + take a private data pointer, and must return a pointer to an + integer corresponding to the next byte read (or EOF if there is no + more data to be read). + \param private_data pointer that will be provided back to the read + function. This is udeful for maintaining state or context. + + \return the LDIF message that has been read in + + \note You must free the LDIF message when no longer required, using + ldb_ldif_read_free(). + + \sa ldb_ldif_read_file for a more convenient way to read from a + file stream. + + \sa ldb_ldif_read_string for a more convenient way to read from a + string (char array). + + \sa ldb_ldif_write for the writer equivalent to this function. +*/ +struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data); + +/** + Read an LDIF message from a file + + This function reads the next LDIF message from the contents of a + file stream. If you want to get all of the LDIF messages, you will + need to repeatedly call this function, until it returns NULL. + + \param ldb the ldb context (from ldb_init()) + \param f the file stream to read from (typically from fdopen()) + + \sa ldb_ldif_read_string for an equivalent function that will read + from a string (char array). + + \sa ldb_ldif_write_file for the writer equivalent to this function. + +*/ +struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); + +/** + Read an LDIF message from a string + + This function reads the next LDIF message from the contents of a char + array. If you want to get all of the LDIF messages, you will need + to repeatedly call this function, until it returns NULL. + + \param ldb the ldb context (from ldb_init()) + \param s pointer to the char array to read from + + \sa ldb_ldif_read_file for an equivalent function that will read + from a file stream. + + \sa ldb_ldif_write for a more general (arbitrary read function) + version of this function. +*/ +struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); + +/** + Parse a modrdn LDIF message from a struct ldb_message + + \param ldb the ldb context (from ldb_init()) + \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) + + \param mem_ctx the memory context that's used for return values + + \param olddn the old dn as struct ldb_dn, if not needed pass NULL + \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL + \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL + \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL + *newsuperior can be NULL as it is optional in the LDIF + \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL + +*/ +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **olddn, + struct ldb_dn **newrdn, + bool *deleteoldrdn, + struct ldb_dn **newsuperior, + struct ldb_dn **newdn); + +/** + Write an LDIF message to a file + + \param ldb the ldb context (from ldb_init()) + \param f the file stream to write to (typically from fdopen()) + \param msg the message to write out + + \return the total number of bytes written, or a negative error code + + \sa ldb_ldif_read_file for the reader equivalent to this function. +*/ +int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); + +/** + Write an LDIF message to a string + + \param ldb the ldb context (from ldb_init()) + \param mem_ctx the talloc context on which to attach the string) + \param msg the message to write out + + \return the string containing the LDIF, or NULL on error + + \sa ldb_ldif_read_string for the reader equivalent to this function. +*/ +char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *msg); + + +/* + Produce a string form of an ldb message + + convenient function to turn a ldb_message into a string. Useful for + debugging + */ +char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg); + + +/** + Base64 encode a buffer + + \param mem_ctx the memory context that the result is allocated + from. + \param buf pointer to the array that is to be encoded + \param len the number of elements in the array to be encoded + + \return pointer to an array containing the encoded data + + \note The caller is responsible for freeing the result +*/ +char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len); + +/** + Base64 decode a buffer + + This function decodes a base64 encoded string in place. + + \param s the string to decode. + + \return the length of the returned (decoded) string. + + \note the string is null terminated, but the null terminator is not + included in the length. +*/ +int ldb_base64_decode(char *s); + +/* The following definitions come from lib/ldb/common/ldb_dn.c */ + +/** + Get the linear form of a DN (without any extended components) + + \param dn The DN to linearize +*/ + +const char *ldb_dn_get_linearized(struct ldb_dn *dn); + +/** + Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context + + \param dn The DN to linearize + \param mem_ctx TALLOC context to return result on +*/ + +char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); + +/** + Get the linear form of a DN (with any extended components) + + \param mem_ctx TALLOC context to return result on + \param dn The DN to linearize + \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) +*/ +char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); +int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); +void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); +void ldb_dn_remove_extended_components(struct ldb_dn *dn); +bool ldb_dn_has_extended(struct ldb_dn *dn); + +int ldb_dn_extended_add_syntax(struct ldb_context *ldb, + unsigned flags, + const struct ldb_dn_extended_syntax *syntax); + +/** + Allocate a new DN from a string + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); +/** + Allocate a new DN from a printf style format string and arguments + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param new_fms The new DN as a format string (plus arguments) + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); +/** + Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); + +/** + Determine if this DN is syntactically valid + + \param dn The DN to validate +*/ + +bool ldb_dn_validate(struct ldb_dn *dn); + +char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); +const char *ldb_dn_get_casefold(struct ldb_dn *dn); +char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); + +int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); +int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); + +bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base); +bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) PRINTF_ATTRIBUTE(2,3); +bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child); +bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_ATTRIBUTE(2,3); +bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num); +bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num); + +struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +int ldb_dn_get_comp_num(struct ldb_dn *dn); +int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); +const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); +const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); +const char *ldb_dn_get_rdn_name(struct ldb_dn *dn); +const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn); +int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); + +bool ldb_dn_is_valid(struct ldb_dn *dn); +bool ldb_dn_is_special(struct ldb_dn *dn); +bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); +bool ldb_dn_is_null(struct ldb_dn *dn); +int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); + + +/** + Compare two attributes + + This function compares to attribute names. Note that this is a + case-insensitive comparison. + + \param a the first attribute name to compare + \param b the second attribute name to compare + + \return 0 if the attribute names are the same, or only differ in + case; non-zero if there are any differences + + attribute names are restricted by rfc2251 so using + strcasecmp and toupper here is ok. + return 0 for match +*/ +#define ldb_attr_cmp(a, b) strcasecmp(a, b) +char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s); +int ldb_attr_dn(const char *attr); + +/** + Create an empty message + + \param mem_ctx the memory context to create in. You can pass NULL + to get the top level context, however the ldb context (from + ldb_init()) may be a better choice +*/ +struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx); + +/** + Find an element within an message +*/ +struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, + const char *attr_name); + +/** + Compare two ldb_val values + + \param v1 first ldb_val structure to be tested + \param v2 second ldb_val structure to be tested + + \return 1 for a match, 0 if there is any difference +*/ +int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); + +/** + find a value within an ldb_message_element + + \param el the element to search + \param val the value to search for + + \note This search is case sensitive +*/ +struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, + struct ldb_val *val); + +/** + add a new empty element to a ldb_message +*/ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el); + +/** + add a element to a ldb_message +*/ +int ldb_msg_add(struct ldb_message *msg, + const struct ldb_message_element *el, + int flags); +int ldb_msg_add_value(struct ldb_message *msg, + const char *attr_name, + const struct ldb_val *val, + struct ldb_message_element **return_el); +int ldb_msg_add_steal_value(struct ldb_message *msg, + const char *attr_name, + struct ldb_val *val); +int ldb_msg_add_steal_string(struct ldb_message *msg, + const char *attr_name, char *str); +int ldb_msg_add_string(struct ldb_message *msg, + const char *attr_name, const char *str); +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn); +int ldb_msg_add_fmt(struct ldb_message *msg, + const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +/** + compare two message elements - return 0 on match +*/ +int ldb_msg_element_compare(struct ldb_message_element *el1, + struct ldb_message_element *el2); +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2); + +/** + Find elements in a message. + + This function finds elements and converts to a specific type, with + a give default value if not found. Assumes that elements are + single valued. +*/ +const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); +int ldb_msg_find_attr_as_int(const struct ldb_message *msg, + const char *attr_name, + int default_value); +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, + const char *attr_name, + unsigned int default_value); +int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, + const char *attr_name, + int64_t default_value); +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, + const char *attr_name, + uint64_t default_value); +double ldb_msg_find_attr_as_double(const struct ldb_message *msg, + const char *attr_name, + double default_value); +int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, + const char *attr_name, + int default_value); +const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, + const char *attr_name, + const char *default_value); + +struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char *attr_name); + +void ldb_msg_sort_elements(struct ldb_message *msg); + +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg); +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg); + +/* + * ldb_msg_canonicalize() is now depreciated + * Please use ldb_msg_normalize() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ +struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, + const struct ldb_message *msg) _DEPRECATED_; + +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out); + + +/* + * ldb_msg_diff() is now depreciated + * Please use ldb_msg_difference() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) _DEPRECATED_; + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have + * different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out); + +/** + Tries to find a certain string attribute in a message + + \param msg the message to check + \param name attribute name + \param value attribute value + + \return 1 on match and 0 otherwise. +*/ +int ldb_msg_check_string_attribute(const struct ldb_message *msg, + const char *name, + const char *value); + +/** + Integrity check an ldb_message + + This function performs basic sanity / integrity checks on an + ldb_message. + + \param ldb context in which to perform the checks + \param msg the message to check + + \return LDB_SUCCESS if the message is OK, or a non-zero error code + (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or + LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a + message. +*/ +int ldb_msg_sanity_check(struct ldb_context *ldb, + const struct ldb_message *msg); + +/** + Duplicate an ldb_val structure + + This function copies an ldb value structure. + + \param mem_ctx the memory context that the duplicated value will be + allocated from + \param v the ldb_val to be duplicated. + + \return the duplicated ldb_val structure. +*/ +struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v); + +/** + this allows the user to set a debug function for error reporting +*/ +int ldb_set_debug(struct ldb_context *ldb, + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), + void *context); + +/** + this allows the user to set custom utf8 function for error reporting +*/ +void ldb_set_utf8_fns(struct ldb_context *ldb, + void *context, + char *(*casefold)(void *, void *, const char *, size_t n)); + +/** + this sets up debug to print messages on stderr +*/ +int ldb_set_debug_stderr(struct ldb_context *ldb); + +/* control backend specific opaque values */ +int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); +void *ldb_get_opaque(struct ldb_context *ldb, const char *name); + +const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs); +const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr); +int ldb_attr_in_list(const char * const *attrs, const char *attr); + +int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); +int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); +void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); +void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); + + +void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, + const char *attr, + const char *replace); + +/* + shallow copy a tree - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_parse_tree *ot); + +/** + Convert a time structure to a string + + This function converts a time_t structure to an LDAP formatted + GeneralizedTime string. + + \param mem_ctx the memory context to allocate the return string in + \param t the time structure to convert + + \return the formatted string, or NULL if the time structure could + not be converted +*/ +char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t); + +/** + Convert a string to a time structure + + This function converts an LDAP formatted GeneralizedTime string + to a time_t structure. + + \param s the string to convert + + \return the time structure, or 0 if the string cannot be converted +*/ +time_t ldb_string_to_time(const char *s); + +/** + convert a LDAP GeneralizedTime string in ldb_val format to a + time_t. +*/ +int ldb_val_to_time(const struct ldb_val *v, time_t *t); + +/** + Convert a time structure to a string + + This function converts a time_t structure to an LDAP formatted + UTCTime string. + + \param mem_ctx the memory context to allocate the return string in + \param t the time structure to convert + + \return the formatted string, or NULL if the time structure could + not be converted +*/ +char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t); + +/** + Convert a string to a time structure + + This function converts an LDAP formatted UTCTime string + to a time_t structure. + + \param s the string to convert + + \return the time structure, or 0 if the string cannot be converted +*/ +time_t ldb_string_utc_to_time(const char *s); + + +void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); + +#ifndef discard_const +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) +#endif + +/* + a wrapper around ldb_qsort() that ensures the comparison function is + type safe. This will produce a compilation warning if the types + don't match + */ +#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ +do { \ + if (numel > 1) { \ + ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ + comparison(&((base)[0]), &((base)[1]), opaque); \ + } \ +} while (0) + +/* allow ldb to also call TYPESAFE_QSORT() */ +#ifndef TYPESAFE_QSORT +#define TYPESAFE_QSORT(base, numel, comparison) \ +do { \ + if (numel > 1) { \ + qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ + comparison(&((base)[0]), &((base)[1])); \ + } \ +} while (0) +#endif + + + +/** + Convert a control into its string representation. + + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control A struct ldb_control to convert + + \return string representation of the control +*/ +char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); +/** + Convert a string representing a control into a ldb_control structure + + \param ldb LDB context + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control_strings A string-formatted control + + \return a ldb_control element +*/ +struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); +/** + Convert an array of string represention of a control into an array of ldb_control structures + + \param ldb LDB context + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control_strings Array of string-formatted controls + + \return array of ldb_control elements +*/ +struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings); + +/** + return the ldb flags +*/ +unsigned int ldb_get_flags(struct ldb_context *ldb); + +/* set the ldb flags */ +void ldb_set_flags(struct ldb_context *ldb, unsigned flags); + + +struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const struct ldb_val *strdn); + +int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); +int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); + +/* debugging functions for ldb requests */ +void ldb_req_set_location(struct ldb_request *req, const char *location); +const char *ldb_req_location(struct ldb_request *req); + +/* set the location marker on a request handle - used for debugging */ +#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) + +/* + minimise a DN. The caller must pass in a validated DN. + + If the DN has an extended component then only the first extended + component is kept, the DN string is stripped. + + The existing dn is modified + */ +bool ldb_dn_minimise(struct ldb_dn *dn); + +#endif diff --git a/lib/ldb/include/ldb_errors.h b/lib/ldb/include/ldb_errors.h new file mode 100644 index 00000000000..b247fbe09c4 --- /dev/null +++ b/lib/ldb/include/ldb_errors.h @@ -0,0 +1,312 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** 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 header + * + * Description: defines error codes following RFC 2251 ldap error codes + * + * Author: Simo Sorce + */ + +#ifndef _LDB_ERRORS_H_ + +/*! \cond DOXYGEN_IGNORE */ +#define _LDB_ERRORS_H_ 1 +/*! \endcond */ + +/** + \file ldb_errors.h + + This header provides a set of result codes for LDB function calls. + + Many LDB function calls return an integer value (int). As shown in + the function documentation, those return values may indicate + whether the function call worked correctly (in which case it + returns LDB_SUCCESS) or some problem occurred (in which case some + other value will be returned). As a special case, + LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, + which does not indicate an error. + + \note Not all error codes make sense for LDB, however they are + based on the LDAP error codes, and are kept for reference and to + avoid overlap. + + \note Some of this documentation is based on information in + the OpenLDAP documentation, as developed and maintained by the + The OpenLDAP Project. + */ + +/** + The function call succeeded. + + If a function returns LDB_SUCCESS, then that function, and the + underlying transactions that may have been required, completed + successfully. +*/ +#define LDB_SUCCESS 0 + +/** + The function call failed for some non-specific reason. +*/ +#define LDB_ERR_OPERATIONS_ERROR 1 + +/** + The function call failed because of a protocol violation. +*/ +#define LDB_ERR_PROTOCOL_ERROR 2 + +/** + The function call failed because a time limit was exceeded. +*/ +#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 + +/** + The function call failed because a size limit was exceeded. +*/ +#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 + +/** + The function was for value comparison, and the comparison operation + returned false. + + \note This is a status value, and doesn't normally indicate an + error. +*/ +#define LDB_ERR_COMPARE_FALSE 5 + +/** + The function was for value comparison, and the comparison operation + returned true. + + \note This is a status value, and doesn't normally indicate an + error. +*/ +#define LDB_ERR_COMPARE_TRUE 6 + +/** + The function used an authentication method that is not supported by + the database. +*/ +#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 + +/** + The function call required a underlying operation that required + strong authentication. + + This will normally only occur if you are using LDB with a LDAP + backend. +*/ +#define LDB_ERR_STRONG_AUTH_REQUIRED 8 + +/* 9 RESERVED */ + +/** + The function resulted in a referral to another server. +*/ +#define LDB_ERR_REFERRAL 10 + +/** + The function failed because an administrative / policy limit was + exceeded. +*/ +#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 + +/** + The function required an extension or capability that the + database cannot provide. +*/ +#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 + +/** + The function involved a transaction or database operation that + could not be performed without a secure link. +*/ +#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 + +/** + This is an intermediate result code for SASL bind operations that + have more than one step. + + \note This is a result code that does not normally indicate an + error has occurred. +*/ +#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 + +/** + The function referred to an attribute type that is not present in + the entry. +*/ +#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 + +/** + The function referred to an attribute type that is invalid +*/ +#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 + +/** + The function required a filter type that is not available for the + specified attribute. +*/ +#define LDB_ERR_INAPPROPRIATE_MATCHING 18 + +/** + The function would have violated an attribute constraint. +*/ +#define LDB_ERR_CONSTRAINT_VIOLATION 19 + +/** + The function involved an attribute type or attribute value that + already exists in the entry. +*/ +#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 + +/** + The function used an invalid (incorrect syntax) attribute value. +*/ +#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 + +/* 22-31 unused */ + +/** + The function referred to an object that does not exist in the + database. +*/ +#define LDB_ERR_NO_SUCH_OBJECT 32 + +/** + The function referred to an alias which points to a non-existent + object in the database. +*/ +#define LDB_ERR_ALIAS_PROBLEM 33 + +/** + The function used a DN which was invalid (incorrect syntax). +*/ +#define LDB_ERR_INVALID_DN_SYNTAX 34 + +/* 35 RESERVED */ + +/** + The function required dereferencing of an alias, and something went + wrong during the dereferencing process. +*/ +#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 + +/* 37-47 unused */ + +/** + The function passed in the wrong authentication method. +*/ +#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 + +/** + The function passed in or referenced incorrect credentials during + authentication. +*/ +#define LDB_ERR_INVALID_CREDENTIALS 49 + +/** + The function required access permissions that the user does not + possess. +*/ +#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 + +/** + The function required a transaction or call that the database could + not perform because it is busy. +*/ +#define LDB_ERR_BUSY 51 + +/** + The function required a transaction or call to a database that is + not available. +*/ +#define LDB_ERR_UNAVAILABLE 52 + +/** + The function required a transaction or call to a database that the + database declined to perform. +*/ +#define LDB_ERR_UNWILLING_TO_PERFORM 53 + +/** + The function failed because it resulted in a loop being detected. +*/ +#define LDB_ERR_LOOP_DETECT 54 + +/* 55-63 unused */ + +/** + The function failed because it would have violated a naming rule. +*/ +#define LDB_ERR_NAMING_VIOLATION 64 + +/** + The function failed because it would have violated the schema. +*/ +#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 + +/** + The function required an operation that is only allowed on leaf + objects, but the object is not a leaf. +*/ +#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 + +/** + The function required an operation that cannot be performed on a + Relative DN, but the object is a Relative DN. +*/ +#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 + +/** + The function failed because the entry already exists. +*/ +#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 + +/** + The function failed because modifications to an object class are + not allowable. +*/ +#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 + +/* 70 RESERVED FOR CLDAP */ + +/** + The function failed because it needed to be applied to multiple + databases. +*/ +#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 + +/* 72-79 unused */ + +/** + The function failed for unknown reasons. +*/ +#define LDB_ERR_OTHER 80 + +/* 81-90 RESERVED for APIs */ + +#endif /* _LDB_ERRORS_H_ */ diff --git a/lib/ldb/include/ldb_handlers.h b/lib/ldb/include/ldb_handlers.h new file mode 100644 index 00000000000..6e71f1fa014 --- /dev/null +++ b/lib/ldb/include/ldb_handlers.h @@ -0,0 +1,40 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** 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 header + * + * Description: defines attribute handlers + * + * Author: Simo Sorce + */ + +int ldb_handler_copy( struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out); +int ldb_comparison_binary( struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2); +int ldb_comparison_fold( struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2); + diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h new file mode 100644 index 00000000000..6d6fff251cd --- /dev/null +++ b/lib/ldb/include/ldb_module.h @@ -0,0 +1,344 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2008 + + ** 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 module header + * + * Description: defines ldb modules structures and helpers + * + */ + +#ifndef _LDB_MODULE_H_ +#define _LDB_MODULE_H_ + +#include + +struct ldb_context; +struct ldb_module; + +/** + internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK + */ +#define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 + +/* disable any single value checking on this attribute */ +#define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 + +/* attribute has failed access check and must not be exposed */ +#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 + +/* force single value checking on this attribute */ +#define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 + + +/* + these function pointers define the operations that a ldb module can intercept +*/ +struct ldb_module_ops { + const char *name; + int (*init_context) (struct ldb_module *); + int (*search)(struct ldb_module *, struct ldb_request *); /* search */ + int (*add)(struct ldb_module *, struct ldb_request *); /* add */ + int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ + int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ + int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ + int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ + int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ + int (*start_transaction)(struct ldb_module *); + int (*prepare_commit)(struct ldb_module *); + int (*end_transaction)(struct ldb_module *); + int (*del_transaction)(struct ldb_module *); + int (*sequence_number)(struct ldb_module *, struct ldb_request *); + void *private_data; +}; + + +/* The following definitions come from lib/ldb/common/ldb_debug.c */ +void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, + const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); +void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); + +#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) + +#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") +#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) +#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") + +/* The following definitions come from lib/ldb/common/ldb.c */ + +void ldb_request_set_state(struct ldb_request *req, int state); +int ldb_request_get_status(struct ldb_request *req); + +unsigned int ldb_get_create_perms(struct ldb_context *ldb); + +const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, + const char *syntax); + +/* The following definitions come from lib/ldb/common/ldb_attributes.c */ + +int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, + const char *name, + unsigned flags, + const struct ldb_schema_syntax *syntax); +int ldb_schema_attribute_add(struct ldb_context *ldb, + const char *name, + unsigned flags, + const char *syntax); +void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name); + +/* we allow external code to override the name -> schema_attribute function */ +typedef const struct ldb_schema_attribute *(*ldb_attribute_handler_override_fn_t)(struct ldb_context *, void *, const char *); + +void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, + ldb_attribute_handler_override_fn_t override, + void *private_data); + +/* A useful function to build comparison functions with */ +int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, + ldb_attr_handler_t canonicalise_fn, + const struct ldb_val *v1, + const struct ldb_val *v2); + +/* The following definitions come from lib/ldb/common/ldb_controls.c */ +int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); +/* Returns a list of controls, except the one specified. Included + * controls become a child of returned list if they were children of + * controls_in */ +struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, + TALLOC_CTX *mem_ctx, + struct ldb_control *exclude); +int ldb_check_critical_controls(struct ldb_control **controls); + +/* The following definitions come from lib/ldb/common/ldb_ldif.c */ +int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val); + +/* The following definitions come from lib/ldb/common/ldb_match.c */ +int ldb_match_msg(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope); + +int ldb_match_msg_error(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope, + bool *matched); + +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass); + +/* The following definitions come from lib/ldb/common/ldb_modules.c */ + +struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, + struct ldb_context *ldb, + const char *module_name, + const struct ldb_module_ops *ops); + +const char * ldb_module_get_name(struct ldb_module *module); +struct ldb_context *ldb_module_get_ctx(struct ldb_module *module); +void *ldb_module_get_private(struct ldb_module *module); +void ldb_module_set_private(struct ldb_module *module, void *private_data); +const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); + +int ldb_next_request(struct ldb_module *module, struct ldb_request *request); +int ldb_next_start_trans(struct ldb_module *module); +int ldb_next_end_trans(struct ldb_module *module); +int ldb_next_del_trans(struct ldb_module *module); +int ldb_next_prepare_commit(struct ldb_module *module); +int ldb_next_init(struct ldb_module *module); + +void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); +void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +void ldb_reset_err_string(struct ldb_context *ldb); +int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); + +const char *ldb_default_modules_dir(void); + +int ldb_register_module(const struct ldb_module_ops *); + +typedef int (*ldb_connect_fn)(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **module); + +struct ldb_backend_ops { + const char *name; + ldb_connect_fn connect_fn; +}; + +const char *ldb_default_modules_dir(void); + +int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); + +struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); + +int ldb_module_send_entry(struct ldb_request *req, + struct ldb_message *msg, + struct ldb_control **ctrls); + +int ldb_module_send_referral(struct ldb_request *req, + char *ref); + +int ldb_module_done(struct ldb_request *req, + struct ldb_control **ctrls, + struct ldb_extended *response, + int error); + +int ldb_mod_register_control(struct ldb_module *module, const char *oid); + +void ldb_set_default_dns(struct ldb_context *ldb); +/** + Add a ldb_control to a ldb_reply + + \param ares the reply struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); + +/** + mark a request as untrusted. This tells the rootdse module to remove + unregistered controls + */ +void ldb_req_mark_untrusted(struct ldb_request *req); + +/** + mark a request as trusted. + */ +void ldb_req_mark_trusted(struct ldb_request *req); + +/** + return true is a request is untrusted + */ +bool ldb_req_is_untrusted(struct ldb_request *req); + +/** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req); + +/* load all modules from the given directory */ +int ldb_modules_load(const char *modules_path, const char *version); + +/* init functions prototype */ +typedef int (*ldb_module_init_fn)(const char *); + +/* + general ldb hook function + */ +enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, + LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, + LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; + +typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); + +/* + register a ldb hook function + */ +int ldb_register_hook(ldb_hook_fn hook_fn); + +/* + call ldb hooks of a given type + */ +int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); + +#define LDB_MODULE_CHECK_VERSION(version) do { \ + if (strcmp(version, LDB_VERSION) != 0) { \ + fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ + __FILE__, version, LDB_VERSION); \ + return LDB_ERR_UNAVAILABLE; \ + }} while (0) + + +/* + return a string representation of the calling chain for the given + ldb request + */ +char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); + +/* + return the next module in the chain + */ +struct ldb_module *ldb_module_next(struct ldb_module *module); + +/* + set the next module in the module chain + */ +void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); + +/* + load a list of modules + */ +int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, + struct ldb_module *backend, struct ldb_module **out); + +/* + get the popt_options pointer in the ldb structure. This allows a ldb + module to change the command line parsing + */ +struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); + +/* modules are called in inverse order on the stack. + Lets place them as an admin would think the right order is. + Modules order is important */ +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); + +/* + return the current ldb flags LDB_FLG_* + */ +uint32_t ldb_module_flags(struct ldb_context *ldb); + +int ldb_module_connect_backend(struct ldb_context *ldb, + const char *url, + const char *options[], + struct ldb_module **backend_module); + +/* + initialise a chain of modules + */ +int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); + +/* + * prototype for the init function defined by dynamically loaded modules + */ +int ldb_init_module(const char *version); + + +#endif diff --git a/lib/ldb/include/ldb_private.h b/lib/ldb/include/ldb_private.h new file mode 100644 index 00000000000..cafc020e291 --- /dev/null +++ b/lib/ldb/include/ldb_private.h @@ -0,0 +1,184 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004-2005 + + ** 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 private header + * + * Description: defines internal ldb structures used by the subsystem and modules + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +#ifndef _LDB_PRIVATE_H_ +#define _LDB_PRIVATE_H_ 1 + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "ldb_module.h" + +struct ldb_context; + +struct ldb_module_ops; + +struct ldb_backend_ops; + +#define LDB_HANDLE_FLAG_DONE_CALLED 1 +/* call is from an untrusted source - eg. over ldap:// */ +#define LDB_HANDLE_FLAG_UNTRUSTED 2 + +struct ldb_handle { + int status; + enum ldb_state state; + struct ldb_context *ldb; + unsigned flags; + /* flags dedicated to be set by application using ldb */ + uint32_t custom_flags; + unsigned nesting; + + /* used for debugging */ + struct ldb_request *parent; + const char *location; +}; + +/* basic module structure */ +struct ldb_module { + struct ldb_module *prev, *next; + struct ldb_context *ldb; + void *private_data; + const struct ldb_module_ops *ops; +}; + +/* + schema related information needed for matching rules +*/ +struct ldb_schema { + void *attribute_handler_override_private; + ldb_attribute_handler_override_fn_t attribute_handler_override; + + /* attribute handling table */ + unsigned num_attributes; + struct ldb_schema_attribute *attributes; + + unsigned num_dn_extended_syntax; + struct ldb_dn_extended_syntax *dn_extended_syntax; +}; + +/* + every ldb connection is started by establishing a ldb_context +*/ +struct ldb_context { + /* the operations provided by the backend */ + struct ldb_module *modules; + + /* debugging operations */ + struct ldb_debug_ops debug_ops; + + /* custom utf8 functions */ + struct ldb_utf8_fns utf8_fns; + + /* backend specific opaque parameters */ + struct ldb_opaque { + struct ldb_opaque *next; + const char *name; + void *value; + } *opaque; + + struct ldb_schema schema; + + char *err_string; + + int transaction_active; + + int default_timeout; + + unsigned int flags; + + unsigned int create_perms; + + struct tevent_context *ev_ctx; + + bool prepare_commit_done; + + char *partial_debug; + + struct poptOption *popt_options; +}; + +/* The following definitions come from lib/ldb/common/ldb.c */ + +extern const struct ldb_module_ops ldb_objectclass_module_ops; +extern const struct ldb_module_ops ldb_paged_results_module_ops; +extern const struct ldb_module_ops ldb_rdn_name_module_ops; +extern const struct ldb_module_ops ldb_schema_module_ops; +extern const struct ldb_module_ops ldb_asq_module_ops; +extern const struct ldb_module_ops ldb_server_sort_module_ops; +extern const struct ldb_module_ops ldb_ldap_module_ops; +extern const struct ldb_module_ops ldb_ildap_module_ops; +extern const struct ldb_module_ops ldb_paged_searches_module_ops; +extern const struct ldb_module_ops ldb_tdb_module_ops; +extern const struct ldb_module_ops ldb_skel_module_ops; +extern const struct ldb_module_ops ldb_subtree_rename_module_ops; +extern const struct ldb_module_ops ldb_subtree_delete_module_ops; +extern const struct ldb_module_ops ldb_sqlite3_module_ops; +extern const struct ldb_module_ops ldb_wins_ldb_module_ops; +extern const struct ldb_module_ops ldb_ranged_results_module_ops; + +extern const struct ldb_backend_ops ldb_tdb_backend_ops; +extern const struct ldb_backend_ops ldb_sqlite3_backend_ops; +extern const struct ldb_backend_ops ldb_ldap_backend_ops; +extern const struct ldb_backend_ops ldb_ldapi_backend_ops; +extern const struct ldb_backend_ops ldb_ldaps_backend_ops; + +int ldb_setup_wellknown_attributes(struct ldb_context *ldb); + +const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); +void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); +int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); + +/* The following definitions come from lib/ldb/common/ldb_utf8.c */ +char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); + +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); + + +/* The following definitions come from lib/ldb/common/ldb_modules.c */ + +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); +int ldb_load_modules(struct ldb_context *ldb, const char *options[]); + +struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); + + +/* The following definitions come from lib/ldb/common/ldb_options.c */ + +const char *ldb_options_find(struct ldb_context *ldb, const char *options[], + const char *option_name); + +#endif diff --git a/lib/ldb/ldb.pc.in b/lib/ldb/ldb.pc.in new file mode 100644 index 00000000000..aeba17a6775 --- /dev/null +++ b/lib/ldb/ldb.pc.in @@ -0,0 +1,16 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +modulesdir=@LDB_MODULESDIR@ + +Name: ldb +Description: An LDAP-like embedded database +Version: @PACKAGE_VERSION@ +Requires.private: tdb +Requires: talloc +Libs: @LIB_RPATH@ -L${libdir} -lldb +Libs.private: @LDAP_LIBS@ +Cflags: -I${includedir} +Modulesdir: ${modulesdir} +URL: http://ldb.samba.org/ diff --git a/lib/ldb/ldb_ldap/ldb_ldap.c b/lib/ldb/ldb_ldap/ldb_ldap.c new file mode 100644 index 00000000000..7e6ac903c8a --- /dev/null +++ b/lib/ldb/ldb_ldap/ldb_ldap.c @@ -0,0 +1,982 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Simo Sorce 2006 + + ** 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_ldap + * + * Component: ldb ldap backend + * + * Description: core files for LDAP backend + * + * Author: Andrew Tridgell + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" +#include "ldb_private.h" + +#define LDAP_DEPRECATED 1 +#include + +struct lldb_private { + LDAP *ldap; +}; + +struct lldb_context { + struct ldb_module *module; + struct ldb_request *req; + + struct lldb_private *lldb; + + struct ldb_control **controls; + int msgid; +}; + +static int lldb_ldap_to_ldb(int err) { + /* Ldap errors and ldb errors are defined to the same values */ + return err; +} + +/* + convert a ldb_message structure to a list of LDAPMod structures + ready for ldap_add() or ldap_modify() +*/ +static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) +{ + LDAPMod **mods; + unsigned int i, j; + int num_mods = 0; + + /* allocate maximum number of elements needed */ + mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); + if (!mods) { + errno = ENOMEM; + return NULL; + } + mods[0] = NULL; + + for (i=0;inum_elements;i++) { + const struct ldb_message_element *el = &msg->elements[i]; + + mods[num_mods] = talloc(mods, LDAPMod); + if (!mods[num_mods]) { + goto failed; + } + mods[num_mods+1] = NULL; + mods[num_mods]->mod_op = LDAP_MOD_BVALUES; + if (use_flags) { + switch (el->flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + mods[num_mods]->mod_op |= LDAP_MOD_ADD; + break; + case LDB_FLAG_MOD_DELETE: + mods[num_mods]->mod_op |= LDAP_MOD_DELETE; + break; + case LDB_FLAG_MOD_REPLACE: + mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; + break; + } + } + mods[num_mods]->mod_type = discard_const_p(char, el->name); + mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], + struct berval *, + 1+el->num_values); + if (!mods[num_mods]->mod_vals.modv_bvals) { + goto failed; + } + + for (j=0;jnum_values;j++) { + mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, + struct berval); + if (!mods[num_mods]->mod_vals.modv_bvals[j]) { + goto failed; + } + mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; + mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; + } + mods[num_mods]->mod_vals.modv_bvals[j] = NULL; + num_mods++; + } + + return mods; + +failed: + talloc_free(mods); + return NULL; +} + +/* + add a single set of ldap message values to a ldb_message +*/ +static int lldb_add_msg_attr(struct ldb_context *ldb, + struct ldb_message *msg, + const char *attr, struct berval **bval) +{ + int count, i; + struct ldb_message_element *el; + + count = ldap_count_values_len(bval); + + if (count <= 0) { + return -1; + } + + el = talloc_realloc(msg, msg->elements, struct ldb_message_element, + msg->num_elements + 1); + if (!el) { + errno = ENOMEM; + return -1; + } + + msg->elements = el; + + el = &msg->elements[msg->num_elements]; + + el->name = talloc_strdup(msg->elements, attr); + if (!el->name) { + errno = ENOMEM; + return -1; + } + el->flags = 0; + + el->num_values = 0; + el->values = talloc_array(msg->elements, struct ldb_val, count); + if (!el->values) { + errno = ENOMEM; + return -1; + } + + for (i=0;ivalues[i].data = talloc_size(el->values, bval[i]->bv_len+1); + if (!el->values[i].data) { + errno = ENOMEM; + return -1; + } + memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); + el->values[i].data[bval[i]->bv_len] = 0; + el->values[i].length = bval[i]->bv_len; + el->num_values++; + } + + msg->num_elements++; + + return 0; +} + +/* + search for matching records +*/ +static int lldb_search(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + struct timeval tv; + int ldap_scope; + char *search_base; + char *expression; + int ret; + + ldb = ldb_module_get_ctx(module); + + if (!req->callback || !req->context) { + ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ldb_set_errstring(ldb, "Invalid expression parse tree"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->controls != NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base); + if (req->op.search.base == NULL) { + search_base = talloc_strdup(lldb_ac, ""); + } + if (search_base == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree); + if (expression == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + switch (req->op.search.scope) { + case LDB_SCOPE_BASE: + ldap_scope = LDAP_SCOPE_BASE; + break; + case LDB_SCOPE_ONELEVEL: + ldap_scope = LDAP_SCOPE_ONELEVEL; + break; + default: + ldap_scope = LDAP_SCOPE_SUBTREE; + break; + } + + tv.tv_sec = req->timeout; + tv.tv_usec = 0; + + ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, + expression, + discard_const_p(char *, req->op.search.attrs), + 0, + NULL, + NULL, + &tv, + LDAP_NO_LIMIT, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + add a record +*/ +static int lldb_add(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + LDAPMod **mods; + char *dn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); + if (mods == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_add_ext(lldb->ldap, dn, mods, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + modify a record +*/ +static int lldb_modify(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + LDAPMod **mods; + char *dn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); + if (mods == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_modify_ext(lldb->ldap, dn, mods, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + delete a record +*/ +static int lldb_delete(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + char *dnstr; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn); + + ret = ldap_delete_ext(lldb->ldap, dnstr, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + rename a record +*/ +static int lldb_rename(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + const char *rdn_name; + const struct ldb_val *rdn_val; + char *old_dn; + char *newrdn; + char *parentdn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); + if (old_dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); + rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); + + if ((rdn_name != NULL) && (rdn_val != NULL)) { + newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, + rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); + } else { + newrdn = talloc_strdup(lldb_ac, ""); + } + if (!newrdn) { + return LDB_ERR_OPERATIONS_ERROR; + } + + parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); + if (!parentdn) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, + 1, NULL, NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +static int lldb_start_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static int lldb_end_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static int lldb_del_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static void lldb_request_done(struct lldb_context *ac, + struct ldb_control **ctrls, int error) +{ + struct ldb_request *req; + struct ldb_reply *ares; + + req = ac->req; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb_module_get_ctx(ac->module)); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->controls = talloc_steal(ares, ctrls); + ares->error = error; + + req->callback(req, ares); +} + +/* return false if the request is still in progress + * return true if the request is completed + */ +static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = ac->lldb; + LDAPControl **serverctrlsp = NULL; + char **referralsp = NULL; + char *matcheddnp = NULL; + char *errmsgp = NULL; + LDAPMessage *msg; + int type; + struct ldb_message *ldbmsg; + char *referral; + bool callback_failed; + bool request_done; + bool lret; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + type = ldap_msgtype(result); + callback_failed = false; + request_done = false; + + switch (type) { + case LDAP_RES_SEARCH_ENTRY: + + msg = ldap_first_entry(lldb->ldap, result); + if (msg != NULL) { + BerElement *berptr = NULL; + char *attr, *dn; + + ldbmsg = ldb_msg_new(ac); + if (!ldbmsg) { + ldb_oom(ldb); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + + dn = ldap_get_dn(lldb->ldap, msg); + if (!dn) { + ldb_oom(ldb); + talloc_free(ldbmsg); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); + if ( ! ldb_dn_validate(ldbmsg->dn)) { + ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); + talloc_free(ldbmsg); + ret = LDB_ERR_OPERATIONS_ERROR; + ldap_memfree(dn); + break; + } + ldap_memfree(dn); + + ldbmsg->num_elements = 0; + ldbmsg->elements = NULL; + + /* loop over all attributes */ + for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); + attr; + attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { + struct berval **bval; + bval = ldap_get_values_len(lldb->ldap, msg, attr); + + if (bval) { + lldb_add_msg_attr(ldb, ldbmsg, attr, bval); + ldap_value_free_len(bval); + } + } + if (berptr) ber_free(berptr, 0); + + ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "entry send failed: %s", + ldb_errstring(ldb)); + callback_failed = true; + } + } else { + ret = LDB_ERR_OPERATIONS_ERROR; + } + break; + + case LDAP_RES_SEARCH_REFERENCE: + + ret = ldap_parse_reference(lldb->ldap, result, + &referralsp, &serverctrlsp, 0); + if (ret != LDAP_SUCCESS) { + ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", + ldap_err2string(ret), errmsgp); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + if (referralsp == NULL) { + ldb_asprintf_errstring(ldb, "empty ldap referrals list"); + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + for (i = 0; referralsp[i]; i++) { + referral = talloc_strdup(ac, referralsp[i]); + + ret = ldb_module_send_referral(ac->req, referral); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "referral send failed: %s", + ldb_errstring(ldb)); + callback_failed = true; + break; + } + } + break; + + case LDAP_RES_SEARCH_RESULT: + case LDAP_RES_MODIFY: + case LDAP_RES_ADD: + case LDAP_RES_DELETE: + case LDAP_RES_MODDN: + + if (ldap_parse_result(lldb->ldap, result, &ret, + &matcheddnp, &errmsgp, + &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + } + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", + type, ldap_err2string(ret), errmsgp); + break; + } + + if (serverctrlsp != NULL) { + /* FIXME: transform the LDAPControl list into an ldb_control one */ + ac->controls = NULL; + } + + request_done = true; + break; + + default: + ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + + /* if the callback failed the caller will have freed the + * request. Just return and don't try to use it */ + if (callback_failed) { + + /* tell lldb_wait to remove the request from the + * queue */ + lret = true; + goto free_and_return; + } + + request_done = true; + } + + if (request_done) { + lldb_request_done(ac, ac->controls, ret); + lret = true; + goto free_and_return; + } + + lret = false; + +free_and_return: + + if (matcheddnp) ldap_memfree(matcheddnp); + if (errmsgp && *errmsgp) { + ldb_set_errstring(ldb, errmsgp); + } + if (errmsgp) { + ldap_memfree(errmsgp); + } + if (referralsp) ldap_value_free(referralsp); + if (serverctrlsp) ldap_controls_free(serverctrlsp); + + ldap_msgfree(result); + + return lret; +} + +static void lldb_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + ac = talloc_get_type(private_data, struct lldb_context); + + lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void lldb_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + struct tevent_timer *lte; + struct timeval tv; + LDAPMessage *result; + int lret; + + ac = talloc_get_type(private_data, struct lldb_context); + + if (!ac->msgid) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + return; + } + + tv.tv_sec = 0; + tv.tv_usec = 0; + lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result); + if (lret == 0) { + goto respin; + } + if (lret == -1) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + return; + } + + if ( ! lldb_parse_result(ac, result)) { + goto respin; + } + + return; + +respin: + tv.tv_sec = 0; + tv.tv_usec = 100; + lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac); + if (NULL == lte) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + } +} + +static bool lldb_dn_is_special(struct ldb_request *req) +{ + struct ldb_dn *dn = NULL; + + switch (req->operation) { + case LDB_ADD: + dn = req->op.add.message->dn; + break; + case LDB_MODIFY: + dn = req->op.mod.message->dn; + break; + case LDB_DELETE: + dn = req->op.del.dn; + break; + case LDB_RENAME: + dn = req->op.rename.olddn; + break; + default: + break; + } + + if (dn && ldb_dn_is_special(dn)) { + return true; + } + return false; +} + +static void lldb_auto_done_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + + ac = talloc_get_type(private_data, struct lldb_context); + lldb_request_done(ac, NULL, LDB_SUCCESS); +} + +static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct lldb_private *lldb; + struct lldb_context *ac; + struct tevent_context *ev; + struct tevent_timer *te; + struct timeval tv; + int ret; + + lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); + ldb = ldb_module_get_ctx(module); + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ev = ldb_get_event_context(ldb); + if (NULL == ev) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac = talloc_zero(ldb, struct lldb_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->lldb = lldb; + ac->msgid = 0; + + if (lldb_dn_is_special(req)) { + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, + lldb_auto_done_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; + } + + switch (ac->req->operation) { + case LDB_SEARCH: + ret = lldb_search(ac); + break; + case LDB_ADD: + ret = lldb_add(ac); + break; + case LDB_MODIFY: + ret = lldb_modify(ac); + break; + case LDB_DELETE: + ret = lldb_delete(ac); + break; + case LDB_RENAME: + ret = lldb_rename(ac); + break; + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + lldb_request_done(ac, NULL, ret); + return ret; + } + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lldb_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static const struct ldb_module_ops lldb_ops = { + .name = "ldap", + .search = lldb_handle_request, + .add = lldb_handle_request, + .modify = lldb_handle_request, + .del = lldb_handle_request, + .rename = lldb_handle_request, + .request = lldb_handle_request, + .start_transaction = lldb_start_trans, + .end_transaction = lldb_end_trans, + .del_transaction = lldb_del_trans, +}; + + +static int lldb_destructor(struct lldb_private *lldb) +{ + ldap_unbind(lldb->ldap); + return 0; +} + + +/* + optionally perform a bind + */ +static int lldb_bind(struct ldb_module *module, + const char *options[]) +{ + const char *bind_mechanism; + struct lldb_private *lldb; + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + + bind_mechanism = ldb_options_find(ldb, options, "bindMech"); + if (bind_mechanism == NULL) { + /* no bind wanted */ + return LDB_SUCCESS; + } + + lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); + + if (strcmp(bind_mechanism, "simple") == 0) { + const char *bind_id, *bind_secret; + + bind_id = ldb_options_find(ldb, options, "bindID"); + bind_secret = ldb_options_find(ldb, options, "bindSecret"); + if (bind_id == NULL || bind_secret == NULL) { + ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); + if (ret != LDAP_SUCCESS) { + ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); + return ret; + } + return LDB_SUCCESS; + } + + ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); + return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; +} + +/* + connect to the database +*/ +static int lldb_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct lldb_private *lldb; + int version = 3; + int ret; + + module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + lldb = talloc_zero(module, struct lldb_private); + if (!lldb) { + ldb_oom(ldb); + goto failed; + } + ldb_module_set_private(module, lldb); + + ret = ldap_initialize(&lldb->ldap, url); + if (ret != LDAP_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", + url, ldap_err2string(ret)); + goto failed; + } + + talloc_set_destructor(lldb, lldb_destructor); + + ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ret != LDAP_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", + ldap_err2string(ret)); + goto failed; + } + + *_module = module; + + ret = lldb_bind(module, options); + if (ret != LDB_SUCCESS) { + goto failed; + } + + + return LDB_SUCCESS; + +failed: + talloc_free(module); + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + initialise the module + */ +int ldb_ldap_init(const char *version) +{ + int ret, i; + const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; + LDB_MODULE_CHECK_VERSION(version); + for (i=0; names[i]; i++) { + ret = ldb_register_backend(names[i], lldb_connect, false); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} diff --git a/lib/ldb/ldb_map/ldb_map.c b/lib/ldb/ldb_map/ldb_map.c new file mode 100644 index 00000000000..d35e5c604fc --- /dev/null +++ b/lib/ldb/ldb_map/ldb_map.c @@ -0,0 +1,1139 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Simo Sorce 2008 + + ** 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 ldb_map module + * + * Description: Map portions of data into a different format on a + * remote partition. + * + * Author: Jelmer Vernooij, Martin Kuehl + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + +/* Description of the provided ldb requests: + - special attribute 'isMapped' + + - search: + - if parse tree can be split + - search remote records w/ remote attrs and parse tree + - otherwise + - enumerate all remote records + - for each remote result + - map remote result to local message + - search local result + - is present + - merge local into remote result + - run callback on merged result + - otherwise + - run callback on remote result + + - add: + - split message into local and remote part + - if local message is not empty + - add isMapped to local message + - add local message + - add remote message + + - modify: + - split message into local and remote part + - if local message is not empty + - add isMapped to local message + - search for local record + - if present + - modify local record + - otherwise + - add local message + - modify remote record + + - delete: + - search for local record + - if present + - delete local record + - delete remote record + + - rename: + - search for local record + - if present + - rename local record + - modify local isMapped + - rename remote record +*/ + + + +/* Private data structures + * ======================= */ + +/* Global private data */ +/* Extract mappings from private data. */ +const struct ldb_map_context *map_get_context(struct ldb_module *module) +{ + const struct map_private *data = talloc_get_type(ldb_module_get_private(module), struct map_private); + return data->context; +} + +/* Create a generic request context. */ +struct map_context *map_init_context(struct ldb_module *module, + struct ldb_request *req) +{ + struct ldb_context *ldb; + struct map_context *ac; + + ldb = ldb_module_get_ctx(module); + + ac = talloc_zero(req, struct map_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return NULL; + } + + ac->module = module; + ac->req = req; + + return ac; +} + +/* Dealing with DNs for different partitions + * ========================================= */ + +/* Check whether any data should be stored in the local partition. */ +bool map_check_local_db(struct ldb_module *module) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (!data->remote_base_dn || !data->local_base_dn) { + return false; + } + + return true; +} + +/* Copy a DN with the base DN of the local partition. */ +static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( ! ldb_dn_validate(new_dn)) { + talloc_free(new_dn); + return NULL; + } + + /* may be we don't need to rebase at all */ + if ( ! data->remote_base_dn || ! data->local_base_dn) { + return new_dn; + } + + if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) { + talloc_free(new_dn); + return NULL; + } + + if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Copy a DN with the base DN of the remote partition. */ +static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( ! ldb_dn_validate(new_dn)) { + talloc_free(new_dn); + return NULL; + } + + /* may be we don't need to rebase at all */ + if ( ! data->remote_base_dn || ! data->local_base_dn) { + return new_dn; + } + + if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) { + talloc_free(new_dn); + return NULL; + } + + if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Run a request and make sure it targets the remote partition. */ +/* TODO: free old DNs and messages? */ +int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message *msg; + + ldb = ldb_module_get_ctx(module); + + switch (request->operation) { + case LDB_SEARCH: + if (request->op.search.base) { + request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); + } else { + request->op.search.base = data->remote_base_dn; + /* TODO: adjust scope? */ + } + break; + + case LDB_ADD: + msg = ldb_msg_copy_shallow(request, request->op.add.message); + msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); + request->op.add.message = msg; + break; + + case LDB_MODIFY: + msg = ldb_msg_copy_shallow(request, request->op.mod.message); + msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); + request->op.mod.message = msg; + break; + + case LDB_DELETE: + request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); + break; + + case LDB_RENAME: + request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); + request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); + break; + + default: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Invalid remote request!"); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, request); +} + + +/* Finding mappings for attributes and objectClasses + * ================================================= */ + +/* Find an objectClass mapping by the local name. */ +static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { + return &data->objectclass_maps[i]; + } + } + + return NULL; +} + +/* Find an objectClass mapping by the remote name. */ +static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { + if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { + return &data->objectclass_maps[i]; + } + } + + return NULL; +} + +/* Find an attribute mapping by the local name. */ +const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->attribute_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { + return &data->attribute_maps[i]; + } + } + for (i = 0; data->attribute_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { + return &data->attribute_maps[i]; + } + } + + return NULL; +} + +/* Find an attribute mapping by the remote name. */ +const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) +{ + const struct ldb_map_attribute *map; + const struct ldb_map_attribute *wildcard = NULL; + unsigned int i, j; + + for (i = 0; data->attribute_maps[i].local_name; i++) { + map = &data->attribute_maps[i]; + if (ldb_attr_cmp(map->local_name, "*") == 0) { + wildcard = &data->attribute_maps[i]; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + break; + + case LDB_MAP_KEEP: + if (ldb_attr_cmp(map->local_name, name) == 0) { + return map; + } + break; + + case LDB_MAP_RENAME: + case LDB_MAP_CONVERT: + if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { + return map; + } + break; + + case LDB_MAP_GENERATE: + for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) { + if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { + return map; + } + } + break; + } + } + + /* We didn't find it, so return the wildcard record if one was configured */ + return wildcard; +} + + +/* Mapping attributes + * ================== */ + +/* Check whether an attribute will be mapped into the remote partition. */ +bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr) +{ + const struct ldb_map_attribute *map = map_attr_find_local(data, attr); + + if (map == NULL) { + return false; + } + if (map->type == LDB_MAP_IGNORE) { + return false; + } + + return true; +} + +/* Map an attribute name into the remote partition. */ +const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) +{ + if (map == NULL) { + return talloc_strdup(mem_ctx, attr); + } + + switch (map->type) { + case LDB_MAP_KEEP: + return talloc_strdup(mem_ctx, attr); + + case LDB_MAP_RENAME: + case LDB_MAP_CONVERT: + return talloc_strdup(mem_ctx, map->u.rename.remote_name); + + default: + return NULL; + } +} + +/* Map an attribute name back into the local partition. */ +const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) +{ + if (map == NULL) { + return talloc_strdup(mem_ctx, attr); + } + + if (map->type == LDB_MAP_KEEP) { + return talloc_strdup(mem_ctx, attr); + } + + return talloc_strdup(mem_ctx, map->local_name); +} + + +/* Merge two lists of attributes into a single one. */ +int map_attrs_merge(struct ldb_module *module, void *mem_ctx, + const char ***attrs, const char * const *more_attrs) +{ + unsigned int i, j, k; + + for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; + for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; + + *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); + if (*attrs == NULL) { + map_oom(module); + return -1; + } + + for (k = 0; k < j; k++) { + (*attrs)[i + k] = more_attrs[k]; + } + + (*attrs)[i+k] = NULL; + + return 0; +} + +/* Mapping ldb values + * ================== */ + +/* Map an ldb value into the remote partition. */ +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, + const struct ldb_map_attribute *map, const struct ldb_val *val) +{ + if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { + return map->u.convert.convert_local(module, mem_ctx, val); + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Map an ldb value back into the local partition. */ +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, + const struct ldb_map_attribute *map, const struct ldb_val *val) +{ + if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { + return map->u.convert.convert_remote(module, mem_ctx, val); + } + + return ldb_val_dup(mem_ctx, val); +} + + +/* Mapping DNs + * =========== */ + +/* Check whether a DN is below the local baseDN. */ +bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (!data->local_base_dn) { + return true; + } + + return ldb_dn_compare_base(data->local_base_dn, dn) == 0; +} + +/* Map a DN into the remote partition. */ +struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_dn *newdn; + const struct ldb_map_attribute *map; + enum ldb_map_attr_type map_type; + const char *name; + struct ldb_val value; + int i, ret; + + if (dn == NULL) { + return NULL; + } + + ldb = ldb_module_get_ctx(module); + + newdn = ldb_dn_copy(mem_ctx, dn); + if (newdn == NULL) { + map_oom(module); + return NULL; + } + + /* For each RDN, map the component name and possibly the value */ + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); + + /* Unknown attribute - leave this RDN as is and hope the best... */ + if (map == NULL) { + map_type = LDB_MAP_KEEP; + } else { + map_type = map->type; + } + + switch (map_type) { + case LDB_MAP_IGNORE: + case LDB_MAP_GENERATE: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "'convert_local' not set for attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + } + /* fall through */ + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + + break; + } + } + + return newdn; + +failed: + talloc_free(newdn); + return NULL; +} + +/* Map a DN into the local partition. */ +struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_dn *newdn; + const struct ldb_map_attribute *map; + enum ldb_map_attr_type map_type; + const char *name; + struct ldb_val value; + int i, ret; + + if (dn == NULL) { + return NULL; + } + + ldb = ldb_module_get_ctx(module); + + newdn = ldb_dn_copy(mem_ctx, dn); + if (newdn == NULL) { + map_oom(module); + return NULL; + } + + /* For each RDN, map the component name and possibly the value */ + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); + + /* Unknown attribute - leave this RDN as is and hope the best... */ + if (map == NULL) { + map_type = LDB_MAP_KEEP; + } else { + map_type = map->type; + } + + switch (map_type) { + case LDB_MAP_IGNORE: + case LDB_MAP_GENERATE: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "'convert_remote' not set for attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + } + /* fall through */ + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + + break; + } + } + + return newdn; + +failed: + talloc_free(newdn); + return NULL; +} + +/* Map a DN and its base into the local partition. */ +/* TODO: This should not be required with GUIDs. */ +struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_dn *dn1, *dn2; + + dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); + dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); + + talloc_free(dn1); + return dn2; +} + + +/* Converting DNs and objectClasses (as ldb values) + * ================================================ */ + +/* Map a DN contained in an ldb value into the remote partition. */ +static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + struct ldb_context *ldb; + struct ldb_dn *dn, *newdn; + struct ldb_val newval; + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); + if (! ldb_dn_validate(dn)) { + newval.length = 0; + newval.data = NULL; + talloc_free(dn); + return newval; + } + newdn = ldb_dn_map_local(module, mem_ctx, dn); + talloc_free(dn); + + newval.length = 0; + newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); + if (newval.data) { + newval.length = strlen((char *)newval.data); + } + talloc_free(newdn); + + return newval; +} + +/* Map a DN contained in an ldb value into the local partition. */ +static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + struct ldb_context *ldb; + struct ldb_dn *dn, *newdn; + struct ldb_val newval; + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); + if (! ldb_dn_validate(dn)) { + newval.length = 0; + newval.data = NULL; + talloc_free(dn); + return newval; + } + newdn = ldb_dn_map_remote(module, mem_ctx, dn); + talloc_free(dn); + + newval.length = 0; + newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); + if (newval.data) { + newval.length = strlen((char *)newval.data); + } + talloc_free(newdn); + + return newval; +} + +/* Map an objectClass into the remote partition. */ +static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *name = (char *)val->data; + const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); + struct ldb_val newval; + + if (map) { + newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); + newval.length = strlen((char *)newval.data); + return newval; + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Generate a remote message with a mapped objectClass. */ +static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message_element *el, *oc; + struct ldb_val val; + bool found_extensibleObject = false; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + /* Find old local objectClass */ + oc = ldb_msg_find_element(old, "objectClass"); + if (oc == NULL) { + return; + } + + /* Prepare new element */ + el = talloc_zero(remote, struct ldb_message_element); + if (el == NULL) { + ldb_oom(ldb); + return; /* TODO: fail? */ + } + + /* Copy local objectClass element, reverse space for an extra value */ + el->num_values = oc->num_values + 1; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return; /* TODO: fail? */ + } + + /* Copy local element name "objectClass" */ + el->name = talloc_strdup(el, local_attr); + + /* Convert all local objectClasses */ + for (i = 0; i < el->num_values - 1; i++) { + el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); + if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { + found_extensibleObject = true; + } + } + + if (!found_extensibleObject) { + val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); + val.length = strlen((char *)val.data); + + /* Append additional objectClass data->add_objectclass */ + el->values[i] = val; + } else { + el->num_values--; + } + + /* Add new objectClass to remote message */ + ldb_msg_add(remote, el, 0); +} + +/* Map an objectClass into the local partition. */ +static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *name = (char *)val->data; + const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); + struct ldb_val newval; + + if (map) { + newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); + newval.length = strlen((char *)newval.data); + return newval; + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Generate a local message with a mapped objectClass. */ +static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message_element *el, *oc; + struct ldb_val val; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + /* Find old remote objectClass */ + oc = ldb_msg_find_element(remote, "objectClass"); + if (oc == NULL) { + return NULL; + } + + /* Prepare new element */ + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + ldb_oom(ldb); + return NULL; + } + + /* Copy remote objectClass element */ + el->num_values = oc->num_values; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return NULL; + } + + /* Copy remote element name "objectClass" */ + el->name = talloc_strdup(el, local_attr); + + /* Convert all remote objectClasses */ + for (i = 0; i < el->num_values; i++) { + el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); + } + + val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); + val.length = strlen((char *)val.data); + + /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ + if (ldb_val_equal_exact(&val, &el->values[i-1])) { + el->num_values--; + el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return NULL; + } + } + + return el; +} + +static const struct ldb_map_attribute objectclass_convert_map = { + .local_name = "objectClass", + .type = LDB_MAP_CONVERT, + .u = { + .convert = { + .remote_name = "objectClass", + .convert_local = map_objectclass_convert_local, + .convert_remote = map_objectclass_convert_remote, + }, + }, +}; + + +/* Mappings for searches on objectClass= assuming a one-to-one + * mapping. Needed because this is a generate operator for the + * add/modify code */ +static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, + struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + + return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map); +} + +/* Auxiliary request construction + * ============================== */ + +/* Build a request to search a record by its DN. */ +struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback) +{ + const struct ldb_parse_tree *search_tree; + struct ldb_context *ldb; + struct ldb_request *req; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + if (tree) { + search_tree = tree; + } else { + search_tree = ldb_parse_tree(ac, NULL); + if (search_tree == NULL) { + return NULL; + } + } + + ret = ldb_build_search_req_ex(&req, ldb, ac, + dn, LDB_SCOPE_BASE, + search_tree, attrs, + NULL, + context, callback, + ac->req); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return req; +} + +/* Build a request to update the 'IS_MAPPED' attribute */ +struct ldb_request *map_build_fixup_req(struct map_context *ac, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + void *context, + ldb_map_callback_t callback) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_message *msg; + const char *dn; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* Prepare message */ + msg = ldb_msg_new(ac); + if (msg == NULL) { + map_oom(ac->module); + return NULL; + } + + /* Update local 'IS_MAPPED' to the new remote DN */ + msg->dn = ldb_dn_copy(msg, olddn); + dn = ldb_dn_alloc_linearized(msg, newdn); + if ( ! dn || ! ldb_dn_validate(msg->dn)) { + goto failed; + } + if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto failed; + } + if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { + goto failed; + } + + /* Prepare request */ + ret = ldb_build_mod_req(&req, ldb, + ac, msg, NULL, + context, callback, + ac->req); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + goto failed; + } + talloc_steal(req, msg); + + return req; +failed: + talloc_free(msg); + return NULL; +} + +/* Module initialization + * ===================== */ + + +/* Builtin mappings for DNs and objectClasses */ +static const struct ldb_map_attribute builtin_attribute_maps[] = { + { + .local_name = "dn", + .type = LDB_MAP_CONVERT, + .u = { + .convert = { + .remote_name = "dn", + .convert_local = ldb_dn_convert_local, + .convert_remote = ldb_dn_convert_remote, + }, + }, + }, + { + .local_name = NULL, + } +}; + +static const struct ldb_map_attribute objectclass_attribute_map = { + .local_name = "objectClass", + .type = LDB_MAP_GENERATE, + .convert_operator = map_objectclass_convert_operator, + .u = { + .generate = { + .remote_names = { "objectClass", NULL }, + .generate_local = map_objectclass_generate_local, + .generate_remote = map_objectclass_generate_remote, + }, + }, +}; + + +/* Find the special 'MAP_DN_NAME' record and store local and remote + * base DNs in private data. */ +static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) +{ + static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; + struct ldb_context *ldb; + struct ldb_dn *dn; + struct ldb_message *msg; + struct ldb_result *res; + int ret; + + if (!name) { + data->local_base_dn = NULL; + data->remote_base_dn = NULL; + return LDB_SUCCESS; + } + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); + if ( ! ldb_dn_validate(dn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Failed to construct '%s' DN!", MAP_DN_NAME); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search(ldb, data, &res, dn, LDB_SCOPE_BASE, attrs, NULL); + talloc_free(dn); + if (ret != LDB_SUCCESS) { + return ret; + } + if (res->count == 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "No results for '%s=%s'!", MAP_DN_NAME, name); + talloc_free(res); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + if (res->count > 1) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Too many results for '%s=%s'!", MAP_DN_NAME, name); + talloc_free(res); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + msg = res->msgs[0]; + data->local_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_FROM); + data->remote_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_TO); + talloc_free(res); + + return LDB_SUCCESS; +} + +/* Store attribute maps and objectClass maps in private data. */ +static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, + const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes) +{ + unsigned int i, j, last; + last = 0; + + /* Count specified attribute maps */ + for (i = 0; attrs[i].local_name; i++) /* noop */ ; + /* Count built-in attribute maps */ + for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; + + /* Store list of attribute maps */ + data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+2); + if (data->attribute_maps == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Specified ones go first */ + for (i = 0; attrs[i].local_name; i++) { + data->attribute_maps[last] = attrs[i]; + last++; + } + + /* Built-in ones go last */ + for (i = 0; builtin_attribute_maps[i].local_name; i++) { + data->attribute_maps[last] = builtin_attribute_maps[i]; + last++; + } + + if (data->add_objectclass) { + /* ObjectClass one is very last, if required */ + data->attribute_maps[last] = objectclass_attribute_map; + last++; + } else if (ocls) { + data->attribute_maps[last] = objectclass_convert_map; + last++; + } + + /* Ensure 'local_name == NULL' for the last entry */ + memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); + + /* Store list of objectClass maps */ + data->objectclass_maps = ocls; + + data->wildcard_attributes = wildcard_attributes; + + return LDB_SUCCESS; +} + +/* Initialize global private data. */ +_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes, + const char *add_objectclass, + const char *name) +{ + struct map_private *data; + int ret; + + /* Prepare private data */ + data = talloc_zero(module, struct map_private); + if (data == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_module_set_private(module, data); + + data->context = talloc_zero(data, struct ldb_map_context); + if (!data->context) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Store local and remote baseDNs */ + ret = map_init_dns(module, data->context, name); + if (ret != LDB_SUCCESS) { + talloc_free(data); + return ret; + } + + data->context->add_objectclass = add_objectclass; + + /* Store list of attribute and objectClass maps */ + ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); + if (ret != LDB_SUCCESS) { + talloc_free(data); + return ret; + } + + return LDB_SUCCESS; +} diff --git a/lib/ldb/ldb_map/ldb_map.h b/lib/ldb/ldb_map/ldb_map.h new file mode 100644 index 00000000000..5db3e02a08a --- /dev/null +++ b/lib/ldb/ldb_map/ldb_map.h @@ -0,0 +1,173 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + + ** 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 . + +*/ + +#ifndef __LDB_MAP_H__ +#define __LDB_MAP_H__ + +#include "ldb_module.h" + +/* ldb_map is a skeleton LDB module that can be used for any other modules + * that need to map attributes. + * + * The term 'remote' in this header refers to the connection where the + * original schema is used on while 'local' means the local connection + * that any upper layers will use. + * + * All local attributes will have to have a definition. Not all remote + * attributes need a definition as LDB is a lot less strict than LDAP + * (in other words, sending unknown attributes to an LDAP server hurts us, + * while returning too many attributes in ldb_search() doesn't) + */ + + +/* Name of the internal attribute pointing from the local to the + * remote part of a record */ +#define IS_MAPPED "isMapped" + + +struct ldb_map_context; + +/* convert a local ldb_val to a remote ldb_val */ +typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); + +#define LDB_MAP_MAX_REMOTE_NAMES 10 + +/* map from local to remote attribute */ +struct ldb_map_attribute { + const char *local_name; /* local name */ + + enum ldb_map_attr_type { + LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ + LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ + LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ + LDB_MAP_CONVERT, /* Rename + convert data */ + LDB_MAP_GENERATE /* Use generate function for generating new name/data. + Used for generating attributes based on + multiple remote attributes. */ + } type; + + /* if set, will be called for search expressions that contain this attribute */ + int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **ntree, const struct ldb_parse_tree *otree); + + union { + struct { + const char *remote_name; + } rename; + + struct { + const char *remote_name; + + /* Convert local to remote data */ + ldb_map_convert_func convert_local; + + /* Convert remote to local data */ + /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name + * that is non-NULL before it. */ + ldb_map_convert_func convert_remote; + } convert; + + struct { + /* Generate the local attribute from remote message */ + struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); + + /* Update remote message with information from local message */ + void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); + + /* Name(s) for this attribute on the remote server. This is an array since + * one local attribute's data can be split up into several attributes + * remotely */ + const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; + + /* Names of additional remote attributes + * required for the generation. NULL + * indicates that `local_attr' suffices. */ + /* +#define LDB_MAP_MAX_SELF_ATTRIBUTES 10 + const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; + */ + } generate; + } u; +}; + + +#define LDB_MAP_MAX_SUBCLASSES 10 +#define LDB_MAP_MAX_MUSTS 10 +#define LDB_MAP_MAX_MAYS 50 + +/* map from local to remote objectClass */ +struct ldb_map_objectclass { + const char *local_name; + const char *remote_name; + const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; + const char *musts[LDB_MAP_MAX_MUSTS]; + const char *mays[LDB_MAP_MAX_MAYS]; +}; + + +/* private context data */ +struct ldb_map_context { + struct ldb_map_attribute *attribute_maps; + /* NOTE: Always declare base classes first here */ + const struct ldb_map_objectclass *objectclass_maps; + + /* Remote (often operational) attributes that should be added + * to any wildcard search */ + const char * const *wildcard_attributes; + + /* ObjectClass (if any) to be added to remote attributes on add */ + const char *add_objectclass; + + /* struct ldb_context *mapped_ldb; */ + struct ldb_dn *local_base_dn; + struct ldb_dn *remote_base_dn; +}; + +/* Global private data */ +struct map_private { + void *caller_private; + struct ldb_map_context *context; +}; + +/* Initialize global private data. */ +int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes, + const char *add_objectclass, + const char *name); + +int ldb_map_add(struct ldb_module *module, struct ldb_request *req); +int ldb_map_search(struct ldb_module *module, struct ldb_request *req); +int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); +int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); +int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); + +#define LDB_MAP_OPS \ + .add = ldb_map_add, \ + .modify = ldb_map_modify, \ + .del = ldb_map_delete, \ + .rename = ldb_map_rename, \ + .search = ldb_map_search, + +#endif /* __LDB_MAP_H__ */ diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c new file mode 100644 index 00000000000..b61037222a8 --- /dev/null +++ b/lib/ldb/ldb_map/ldb_map_inbound.c @@ -0,0 +1,837 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Simo Sorce 2008 + + ** 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 . + +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + + +/* Mapping message elements + * ======================== */ + +/* Map a message element into the remote partition. */ +static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) +{ + struct ldb_message_element *el; + unsigned int i; + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return NULL; + } + + el->num_values = old->num_values; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + el->name = map_attr_map_local(el, map, old->name); + + for (i = 0; i < el->num_values; i++) { + el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); + } + + return el; +} + +/* Add a message element either to a local or to a remote message, + * depending on whether it goes into the local or remote partition. */ +static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); + struct ldb_message_element *el=NULL; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + /* Unknown attribute: ignore */ + if (map == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': no mapping found", + old->name); + goto local; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + goto local; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': " + "'convert_local' not set", + map->local_name); + goto local; + } + /* fall through */ + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + el = ldb_msg_el_map_local(module, remote, map, old); + break; + + case LDB_MAP_GENERATE: + if (map->u.generate.generate_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': " + "'generate_remote' not set", + map->local_name); + goto local; + } + + /* TODO: if this attr requires context: + * make sure all context attrs are mappable (in 'names') + * make sure all context attrs have already been mapped? + * maybe postpone generation until they have been mapped? + */ + + map->u.generate.generate_remote(module, map->local_name, msg, remote, local); + return 0; + } + + if (el == NULL) { + return -1; + } + + return ldb_msg_add(remote, el, old->flags); + +local: + el = talloc(local, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return -1; + } + + *el = *old; /* copy the old element */ + + return ldb_msg_add(local, el, old->flags); +} + +/* Mapping messages + * ================ */ + +/* Check whether a message will be (partially) mapped into the remote partition. */ +static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) +{ + const struct ldb_map_context *data = map_get_context(module); + bool ret; + unsigned int i; + + for (i = 0; i < msg->num_elements; i++) { + ret = map_attr_check_remote(data, msg->elements[i].name); + if (ret) { + return ret; + } + } + + return false; +} + +/* Split message elements that stay in the local partition from those + * that are mapped into the remote partition. */ +static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) +{ + /* const char * const names[]; */ + struct ldb_context *ldb; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + + for (i = 0; i < msg->num_elements; i++) { + /* Skip 'IS_MAPPED' */ + if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Skipping attribute '%s'", + msg->elements[i].name); + continue; + } + + ret = ldb_msg_el_partition(module, local, remote, msg, msg->elements[i].name, &msg->elements[i]); + if (ret) { + return ret; + } + } + + return 0; +} + + +static int map_add_do_local(struct map_context *ac); +static int map_modify_do_local(struct map_context *ac); +static int map_delete_do_local(struct map_context *ac); +static int map_rename_do_local(struct map_context *ac); +static int map_rename_do_fixup(struct map_context *ac); +static int map_rename_local_callback(struct ldb_request *req, + struct ldb_reply *ares); + + +/***************************************************************************** + * COMMON INBOUND functions +*****************************************************************************/ + +/* Store the DN of a single search result in context. */ +static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* We are interested only in the single reply */ + switch(ares->type) { + case LDB_REPLY_ENTRY: + /* We have already found a remote DN */ + if (ac->local_dn) { + ldb_set_errstring(ldb, + "Too many results!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Store local DN */ + ac->local_dn = talloc_steal(ac, ares->message->dn); + break; + + case LDB_REPLY_DONE: + + switch (ac->req->operation) { + case LDB_MODIFY: + ret = map_modify_do_local(ac); + break; + case LDB_DELETE: + ret = map_delete_do_local(ac); + break; + case LDB_RENAME: + ret = map_rename_do_local(ac); + break; + default: + /* if we get here we have definitely a problem */ + ret = LDB_ERR_OPERATIONS_ERROR; + } + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + default: + /* ignore referrals */ + break; + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +/* Build a request to search the local record by its DN. */ +static int map_search_self_req(struct ldb_request **req, + struct map_context *ac, + struct ldb_dn *dn) +{ + /* attrs[] is returned from this function in + * ac->search_req->op.search.attrs, so it must be static, as + * otherwise the compiler can put it on the stack */ + static const char * const attrs[] = { IS_MAPPED, NULL }; + struct ldb_parse_tree *tree; + + /* Limit search to records with 'IS_MAPPED' present */ + tree = ldb_parse_tree(ac, "(" IS_MAPPED "=*)"); + if (tree == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + *req = map_search_base_req(ac, dn, attrs, tree, + ac, map_search_self_callback); + if (*req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static int map_op_local_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_set_errstring(ldb, "Invalid reply type!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Do the remote request. */ + ret = ldb_next_remote_request(ac->module, ac->remote_req); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +static int map_op_remote_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_set_errstring(ldb, "Invalid reply type!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); +} + + +/***************************************************************************** + * ADD operations +*****************************************************************************/ + + +/* Add a record. */ +int ldb_map_add(struct ldb_module *module, struct ldb_request *req) +{ + const struct ldb_message *msg = req->op.add.message; + struct ldb_context *ldb; + struct map_context *ac; + struct ldb_message *remote_msg; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified), skip to next module */ + if (!ldb_dn_check_local(module, msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping needed, fail */ + if (!ldb_msg_check_remote(module, msg)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + + /* Prepare the local message */ + ac->local_msg = ldb_msg_new(ac); + if (ac->local_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->local_msg->dn = msg->dn; + + /* Prepare the remote message */ + remote_msg = ldb_msg_new(ac); + if (remote_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); + + /* Split local from remote message */ + ldb_msg_partition(module, ac->local_msg, remote_msg, msg); + + /* Prepare the remote operation */ + ret = ldb_build_add_req(&ac->remote_req, ldb, + ac, remote_msg, + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((ac->local_msg->num_elements == 0) || + ( ! map_check_local_db(ac->module))) { + /* No local data or db, just run the remote request */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Store remote DN in 'IS_MAPPED' */ + /* TODO: use GUIDs here instead */ + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + remote_msg->dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return map_add_do_local(ac); +} + +/* Add the local record. */ +static int map_add_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* Prepare the local operation */ + ret = ldb_build_add_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * MODIFY operations +*****************************************************************************/ + +/* Modify a record. */ +int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) +{ + const struct ldb_message *msg = req->op.mod.message; + struct ldb_request *search_req; + struct ldb_message *remote_msg; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified), skip to next module */ + if (!ldb_dn_check_local(module, msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping needed, skip to next module */ + /* TODO: What if the remote part exists, the local doesn't, + * and this request wants to modify local data and thus + * add the local record? */ + if (!ldb_msg_check_remote(module, msg)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the local message */ + ac->local_msg = ldb_msg_new(ac); + if (ac->local_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->local_msg->dn = msg->dn; + + /* Prepare the remote message */ + remote_msg = ldb_msg_new(ac->remote_req); + if (remote_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); + + /* Split local from remote message */ + ldb_msg_partition(module, ac->local_msg, remote_msg, msg); + + /* Prepare the remote operation */ + ret = ldb_build_mod_req(&ac->remote_req, ldb, + ac, remote_msg, + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((ac->local_msg->num_elements == 0) || + ( ! map_check_local_db(ac->module))) { + /* No local data or db, just run the remote request */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* prepare the search operation */ + ret = map_search_self_req(&search_req, ac, msg->dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Modify the local record. */ +static int map_modify_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + if (ac->local_dn == NULL) { + /* No local record present, add it instead */ + /* Add local 'IS_MAPPED' */ + /* TODO: use GUIDs here instead */ + if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, + LDB_FLAG_MOD_ADD, NULL) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + ac->remote_req->op.mod.message->dn); + if (ret != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the local operation */ + ret = ldb_build_add_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + /* Prepare the local operation */ + ret = ldb_build_mod_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * DELETE operations +*****************************************************************************/ + +/* Delete a record. */ +int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *search_req; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.del.dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified). + * Skip to next module */ + if (!ldb_dn_check_local(module, req->op.del.dn)) { + return ldb_next_request(module, req); + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the remote operation */ + ret = ldb_build_del_req(&ac->remote_req, ldb, ac, + ldb_dn_map_local(module, ac, req->op.del.dn), + req->controls, + ac, + map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* No local db, just run the remote request */ + if (!map_check_local_db(ac->module)) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the search operation */ + ret = map_search_self_req(&search_req, ac, req->op.del.dn); + if (ret != LDB_SUCCESS) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Delete the local record. */ +static int map_delete_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* No local record, continue remotely */ + if (ac->local_dn == NULL) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the local operation */ + ret = ldb_build_del_req(&local_req, ldb, ac, + ac->req->op.del.dn, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * RENAME operations +*****************************************************************************/ + +/* Rename a record. */ +int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *search_req; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.rename.olddn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified). + * Skip to next module */ + if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && + (!ldb_dn_check_local(module, req->op.rename.newdn))) { + return ldb_next_request(module, req); + } + + /* Rename into/out of the mapped partition requested, bail out */ + if (!ldb_dn_check_local(module, req->op.rename.olddn) || + !ldb_dn_check_local(module, req->op.rename.newdn)) { + return LDB_ERR_AFFECTS_MULTIPLE_DSAS; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the remote operation */ + ret = ldb_build_rename_req(&ac->remote_req, ldb, ac, + ldb_dn_map_local(module, ac, req->op.rename.olddn), + ldb_dn_map_local(module, ac, req->op.rename.newdn), + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* No local db, just run the remote request */ + if (!map_check_local_db(ac->module)) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the search operation */ + ret = map_search_self_req(&search_req, ac, req->op.rename.olddn); + if (ret != LDB_SUCCESS) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Rename the local record. */ +static int map_rename_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* No local record, continue remotely */ + if (ac->local_dn == NULL) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the local operation */ + ret = ldb_build_rename_req(&local_req, ldb, ac, + ac->req->op.rename.olddn, + ac->req->op.rename.newdn, + ac->req->controls, + ac, + map_rename_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, local_req); +} + +static int map_rename_local_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_set_errstring(ldb, "Invalid reply type!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* proceed with next step */ + ret = map_rename_do_fixup(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +/* Update the local 'IS_MAPPED' attribute. */ +static int map_rename_do_fixup(struct map_context *ac) +{ + struct ldb_request *local_req; + + /* Prepare the fixup operation */ + /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ + local_req = map_build_fixup_req(ac, + ac->req->op.rename.newdn, + ac->remote_req->op.rename.newdn, + ac, + map_op_local_callback); + if (local_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, local_req); +} diff --git a/lib/ldb/ldb_map/ldb_map_outbound.c b/lib/ldb/ldb_map/ldb_map_outbound.c new file mode 100644 index 00000000000..2c517a625dc --- /dev/null +++ b/lib/ldb/ldb_map/ldb_map_outbound.c @@ -0,0 +1,1407 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Andrew Bartlett 2006 + Copyright (C) Simo Sorce 2008 + + ** 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 . + +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + + +/* Mapping attributes + * ================== */ + +/* Select attributes that stay in the local partition. */ +static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) +{ + const struct ldb_map_context *data = map_get_context(module); + const char **result; + unsigned int i, last; + + if (attrs == NULL) + return NULL; + + last = 0; + result = talloc_array(mem_ctx, const char *, 1); + if (result == NULL) { + goto failed; + } + result[0] = NULL; + + for (i = 0; attrs[i]; i++) { + /* Wildcards and ignored attributes are kept locally */ + if ((ldb_attr_cmp(attrs[i], "*") == 0) || + (!map_attr_check_remote(data, attrs[i]))) { + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, attrs[i]); + result[last+1] = NULL; + last++; + } + } + + return result; + +failed: + talloc_free(result); + map_oom(module); + return NULL; +} + +/* Collect attributes that are mapped into the remote partition. */ +static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, + const char * const *attrs) +{ + const struct ldb_map_context *data = map_get_context(module); + const char **result; + const struct ldb_map_attribute *map; + const char *name=NULL; + unsigned int i, j, last; + int ret; + + last = 0; + result = talloc_array(mem_ctx, const char *, 1); + if (result == NULL) { + goto failed; + } + result[0] = NULL; + + for (i = 0; attrs[i]; i++) { + /* Wildcards are kept remotely, too */ + if (ldb_attr_cmp(attrs[i], "*") == 0) { + const char **new_attrs = NULL; + ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); + if (ret != LDB_SUCCESS) { + goto failed; + } + ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); + if (ret != LDB_SUCCESS) { + goto failed; + } + + attrs = new_attrs; + break; + } + } + + for (i = 0; attrs[i]; i++) { + /* Wildcards are kept remotely, too */ + if (ldb_attr_cmp(attrs[i], "*") == 0) { + /* Add all 'include in wildcard' attributes */ + name = attrs[i]; + goto named; + } + + /* Add remote names of mapped attrs */ + map = map_attr_find_local(data, attrs[i]); + if (map == NULL) { + continue; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + continue; + + case LDB_MAP_KEEP: + name = attrs[i]; + goto named; + + case LDB_MAP_RENAME: + case LDB_MAP_CONVERT: + name = map->u.rename.remote_name; + goto named; + + case LDB_MAP_GENERATE: + /* Add all remote names of "generate" attrs */ + for (j = 0; map->u.generate.remote_names[j]; j++) { + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); + result[last+1] = NULL; + last++; + } + continue; + } + + named: /* We found a single remote name, add that */ + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, name); + result[last+1] = NULL; + last++; + } + + return result; + +failed: + talloc_free(result); + map_oom(module); + return NULL; +} + +/* Split attributes that stay in the local partition from those that + * are mapped into the remote partition. */ +static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) +{ + *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); + *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); + + return 0; +} + +/* Mapping message elements + * ======================== */ + +/* Add an element to a message, overwriting any old identically named elements. */ +static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) +{ + struct ldb_message_element *old; + + old = ldb_msg_find_element(msg, el->name); + + /* no local result, add as new element */ + if (old == NULL) { + if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { + return -1; + } + talloc_free(discard_const_p(char, old->name)); + } + + /* copy new element */ + *old = *el; + + /* and make sure we reference the contents */ + if (!talloc_reference(msg->elements, el->name)) { + return -1; + } + if (!talloc_reference(msg->elements, el->values)) { + return -1; + } + + return 0; +} + +/* Map a message element back into the local partition. */ +static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, + void *mem_ctx, + const struct ldb_map_attribute *map, + const char *attr_name, + const struct ldb_message_element *old) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *local_attr_name = attr_name; + struct ldb_message_element *el; + unsigned int i; + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return NULL; + } + + el->values = talloc_array(el, struct ldb_val, old->num_values); + if (el->values == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + for (i = 0; data->attribute_maps[i].local_name; i++) { + struct ldb_map_attribute *am = &data->attribute_maps[i]; + if ((am->type == LDB_MAP_RENAME && + !strcmp(am->u.rename.remote_name, attr_name)) + || (am->type == LDB_MAP_CONVERT && + !strcmp(am->u.convert.remote_name, attr_name))) { + + local_attr_name = am->local_name; + break; + } + } + + el->name = talloc_strdup(el, local_attr_name); + if (el->name == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + for (i = 0; i < old->num_values; i++) { + el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); + /* Conversions might fail, in which case bail */ + if (!el->values[i].data) { + talloc_free(el); + return NULL; + } + el->num_values++; + } + + return el; +} + +/* Merge a remote message element into a local message. */ +static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, + struct ldb_message *remote, const char *attr_name) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map; + struct ldb_message_element *old, *el=NULL; + const char *remote_name = NULL; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(module); + + /* We handle wildcards in ldb_msg_el_merge_wildcard */ + if (ldb_attr_cmp(attr_name, "*") == 0) { + return LDB_SUCCESS; + } + + map = map_attr_find_local(data, attr_name); + + /* Unknown attribute in remote message: + * skip, attribute was probably auto-generated */ + if (map == NULL) { + return LDB_SUCCESS; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + break; + case LDB_MAP_CONVERT: + remote_name = map->u.convert.remote_name; + break; + case LDB_MAP_KEEP: + remote_name = attr_name; + break; + case LDB_MAP_RENAME: + remote_name = map->u.rename.remote_name; + break; + case LDB_MAP_GENERATE: + break; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + return LDB_SUCCESS; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Skipping attribute '%s': " + "'convert_remote' not set", + attr_name); + return LDB_SUCCESS; + } + /* fall through */ + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + old = ldb_msg_find_element(remote, remote_name); + if (old) { + el = ldb_msg_el_map_remote(module, local, map, attr_name, old); + } else { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + break; + + case LDB_MAP_GENERATE: + if (map->u.generate.generate_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Skipping attribute '%s': " + "'generate_local' not set", + attr_name); + return LDB_SUCCESS; + } + + el = map->u.generate.generate_local(module, local, attr_name, remote); + if (!el) { + /* Generation failure is probably due to lack of source attributes */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + break; + } + + if (el == NULL) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + return ldb_msg_replace(local, el); +} + +/* Handle wildcard parts of merging a remote message element into a local message. */ +static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, + struct ldb_message *remote) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); + struct ldb_message_element *el=NULL; + unsigned int i; + int ret; + + /* Perhaps we have a mapping for "*" */ + if (map && map->type == LDB_MAP_KEEP) { + /* We copy everything over, and hope that anything with a + more specific rule is overwritten */ + for (i = 0; i < remote->num_elements; i++) { + el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, + &remote->elements[i]); + if (el == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_msg_replace(local, el); + if (ret) { + return ret; + } + } + } + + /* Now walk the list of possible mappings, and apply each */ + for (i = 0; data->attribute_maps[i].local_name; i++) { + ret = ldb_msg_el_merge(module, local, remote, + data->attribute_maps[i].local_name); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + continue; + } else if (ret) { + return ret; + } else { + continue; + } + } + + return LDB_SUCCESS; +} + +/* Mapping messages + * ================ */ + +/* Merge two local messages into a single one. */ +static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) +{ + unsigned int i; + int ret; + + for (i = 0; i < msg2->num_elements; i++) { + ret = ldb_msg_replace(msg1, &msg2->elements[i]); + if (ret) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* Merge a local and a remote message into a single local one. */ +static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, + struct ldb_message *remote) +{ + unsigned int i; + int ret; + const char * const *attrs = ac->all_attrs; + if (!attrs) { + ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); + if (ret) { + return ret; + } + } + + for (i = 0; attrs && attrs[i]; i++) { + if (ldb_attr_cmp(attrs[i], "*") == 0) { + ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); + if (ret) { + return ret; + } + break; + } + } + + /* Try to map each attribute back; + * Add to local message is possible, + * Overwrite old local attribute if necessary */ + for (i = 0; attrs && attrs[i]; i++) { + ret = ldb_msg_el_merge(ac->module, local, remote, + attrs[i]); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + } else if (ret) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* Mapping search results + * ====================== */ + +/* Map a search result back into the local partition. */ +static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) +{ + struct ldb_message *msg; + struct ldb_dn *dn; + int ret; + + /* There is no result message, skip */ + if (ares->type != LDB_REPLY_ENTRY) { + return 0; + } + + /* Create a new result message */ + msg = ldb_msg_new(ares); + if (msg == NULL) { + map_oom(ac->module); + return -1; + } + + /* Merge remote message into new message */ + ret = ldb_msg_merge_remote(ac, msg, ares->message); + if (ret) { + talloc_free(msg); + return ret; + } + + /* Create corresponding local DN */ + dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); + if (dn == NULL) { + talloc_free(msg); + return -1; + } + msg->dn = dn; + + /* Store new message with new DN as the result */ + talloc_free(ares->message); + ares->message = msg; + + return 0; +} + +/* Mapping parse trees + * =================== */ + +/* Check whether a parse tree can safely be split in two. */ +static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) +{ + const struct ldb_parse_tree *subtree = tree; + bool negate = false; + + while (subtree) { + switch (subtree->operation) { + case LDB_OP_NOT: + negate = !negate; + subtree = subtree->u.isnot.child; + continue; + + case LDB_OP_AND: + return !negate; /* if negate: False */ + + case LDB_OP_OR: + return negate; /* if negate: True */ + + default: + return true; /* simple parse tree */ + } + } + + return true; /* no parse tree */ +} + +/* Collect a list of attributes required to match a given parse tree. */ +static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) +{ + const char **new_attrs; + unsigned int i; + int ret; + + if (tree == NULL) { + return 0; + } + + switch (tree->operation) { + case LDB_OP_OR: + case LDB_OP_AND: /* attributes stored in list of subtrees */ + for (i = 0; i < tree->u.list.num_elements; i++) { + ret = ldb_parse_tree_collect_attrs(module, mem_ctx, + attrs, tree->u.list.elements[i]); + if (ret) { + return ret; + } + } + return 0; + + case LDB_OP_NOT: /* attributes stored in single subtree */ + return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); + + default: /* single attribute in tree */ + new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); + talloc_free(*attrs); + *attrs = new_attrs; + return 0; + } +} + +static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); + +/* Select a negated subtree that queries attributes in the local partition */ +static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + struct ldb_parse_tree *child; + int ret; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return -1; + } + + /* Generate new subtree */ + ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); + if (ret) { + talloc_free(*new); + return ret; + } + + /* Prune tree without subtree */ + if (child == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + (*new)->u.isnot.child = child; + + return ret; +} + +/* Select a list of subtrees that query attributes in the local partition */ +static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + unsigned int i, j; + int ret=0; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return -1; + } + + /* Prepare list of subtrees */ + (*new)->u.list.num_elements = 0; + (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); + if ((*new)->u.list.elements == NULL) { + map_oom(module); + talloc_free(*new); + return -1; + } + + /* Generate new list of subtrees */ + j = 0; + for (i = 0; i < tree->u.list.num_elements; i++) { + struct ldb_parse_tree *child; + ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); + if (ret) { + talloc_free(*new); + return ret; + } + + if (child) { + (*new)->u.list.elements[j] = child; + j++; + } + } + + /* Prune tree without subtrees */ + if (j == 0) { + talloc_free(*new); + *new = NULL; + return 0; + } + + /* Fix subtree list size */ + (*new)->u.list.num_elements = j; + (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); + + return ret; +} + +/* Select a simple subtree that queries attributes in the local partition */ +static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return -1; + } + + return 0; +} + +/* Select subtrees that query attributes in the local partition */ +static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (tree == NULL) { + return 0; + } + + if (tree->operation == LDB_OP_NOT) { + return map_subtree_select_local_not(module, mem_ctx, new, tree); + } + + if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { + return map_subtree_select_local_list(module, mem_ctx, new, tree); + } + + if (map_attr_check_remote(data, tree->u.equality.attr)) { + *new = NULL; + return 0; + } + + return map_subtree_select_local_simple(module, mem_ctx, new, tree); +} + +static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); + +/* Collect a negated subtree that queries attributes in the remote partition */ +static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + struct ldb_parse_tree *child; + int ret; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return -1; + } + + /* Generate new subtree */ + ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); + if (ret) { + talloc_free(*new); + return ret; + } + + /* Prune tree without subtree */ + if (child == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + (*new)->u.isnot.child = child; + + return ret; +} + +/* Collect a list of subtrees that query attributes in the remote partition */ +static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + unsigned int i, j; + int ret=0; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return -1; + } + + /* Prepare list of subtrees */ + (*new)->u.list.num_elements = 0; + (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); + if ((*new)->u.list.elements == NULL) { + map_oom(module); + talloc_free(*new); + return -1; + } + + /* Generate new list of subtrees */ + j = 0; + for (i = 0; i < tree->u.list.num_elements; i++) { + struct ldb_parse_tree *child; + ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); + if (ret) { + talloc_free(*new); + return ret; + } + + if (child) { + (*new)->u.list.elements[j] = child; + j++; + } + } + + /* Prune tree without subtrees */ + if (j == 0) { + talloc_free(*new); + *new = NULL; + return 0; + } + + /* Fix subtree list size */ + (*new)->u.list.num_elements = j; + (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); + + return ret; +} + +/* Collect a simple subtree that queries attributes in the remote partition */ +int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) +{ + const char *attr; + + /* Prepare new tree */ + *new = talloc(mem_ctx, struct ldb_parse_tree); + if (*new == NULL) { + map_oom(module); + return -1; + } + **new = *tree; + + if (map->type == LDB_MAP_KEEP) { + /* Nothing to do here */ + return 0; + } + + /* Store attribute and value in new tree */ + switch (tree->operation) { + case LDB_OP_PRESENT: + attr = map_attr_map_local(*new, map, tree->u.present.attr); + (*new)->u.present.attr = attr; + break; + case LDB_OP_SUBSTRING: + { + attr = map_attr_map_local(*new, map, tree->u.substring.attr); + (*new)->u.substring.attr = attr; + break; + } + case LDB_OP_EQUALITY: + attr = map_attr_map_local(*new, map, tree->u.equality.attr); + (*new)->u.equality.attr = attr; + break; + case LDB_OP_LESS: + case LDB_OP_GREATER: + case LDB_OP_APPROX: + attr = map_attr_map_local(*new, map, tree->u.comparison.attr); + (*new)->u.comparison.attr = attr; + break; + case LDB_OP_EXTENDED: + attr = map_attr_map_local(*new, map, tree->u.extended.attr); + (*new)->u.extended.attr = attr; + break; + default: /* unknown kind of simple subtree */ + talloc_free(*new); + return -1; + } + + if (attr == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + if (map->type == LDB_MAP_RENAME) { + /* Nothing more to do here, the attribute has been renamed */ + return 0; + } + + /* Store attribute and value in new tree */ + switch (tree->operation) { + case LDB_OP_PRESENT: + break; + case LDB_OP_SUBSTRING: + { + int i; + /* Map value */ + (*new)->u.substring.chunks = NULL; + for (i=0; tree->u.substring.chunks[i]; i++) { + (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); + if (!(*new)->u.substring.chunks) { + talloc_free(*new); + *new = NULL; + return 0; + } + (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); + if (!(*new)->u.substring.chunks[i]) { + talloc_free(*new); + *new = NULL; + return 0; + } + *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); + (*new)->u.substring.chunks[i+1] = NULL; + } + break; + } + case LDB_OP_EQUALITY: + (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); + break; + case LDB_OP_LESS: + case LDB_OP_GREATER: + case LDB_OP_APPROX: + (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); + break; + case LDB_OP_EXTENDED: + (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); + (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); + break; + default: /* unknown kind of simple subtree */ + talloc_free(*new); + return -1; + } + + return 0; +} + +/* Collect subtrees that query attributes in the remote partition */ +static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(module); + + if (tree == NULL) { + return 0; + } + + if (tree->operation == LDB_OP_NOT) { + return map_subtree_collect_remote_not(module, mem_ctx, new, tree); + } + + if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { + return map_subtree_collect_remote_list(module, mem_ctx, new, tree); + } + + if (!map_attr_check_remote(data, tree->u.equality.attr)) { + *new = NULL; + return 0; + } + + map = map_attr_find_local(data, tree->u.equality.attr); + if (map->convert_operator) { + return map->convert_operator(module, mem_ctx, new, tree); + } + + if (map->type == LDB_MAP_GENERATE) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Skipping attribute '%s': " + "'convert_operator' not set", + tree->u.equality.attr); + *new = NULL; + return 0; + } + + return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); +} + +/* Split subtrees that query attributes in the local partition from + * those that query the remote partition. */ +static int ldb_parse_tree_partition(struct ldb_module *module, + void *mem_ctx, + struct ldb_parse_tree **local_tree, + struct ldb_parse_tree **remote_tree, + const struct ldb_parse_tree *tree) +{ + int ret; + + *local_tree = NULL; + *remote_tree = NULL; + + /* No original tree */ + if (tree == NULL) { + return 0; + } + + /* Generate local tree */ + ret = map_subtree_select_local(module, mem_ctx, local_tree, tree); + if (ret) { + return ret; + } + + /* Generate remote tree */ + ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree); + if (ret) { + talloc_free(*local_tree); + return ret; + } + + return 0; +} + +/* Collect a list of attributes required either explicitly from a + * given list or implicitly from a given parse tree; split the + * collected list into local and remote parts. */ +static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, + const char * const *search_attrs, + const struct ldb_parse_tree *tree) +{ + void *tmp_ctx; + const char **tree_attrs; + const char **remote_attrs; + const char **local_attrs; + int ret; + + /* There is no tree, just partition the searched attributes */ + if (tree == NULL) { + ret = map_attrs_partition(module, ac, + &local_attrs, &remote_attrs, search_attrs); + if (ret == 0) { + ac->local_attrs = local_attrs; + ac->remote_attrs = remote_attrs; + ac->all_attrs = search_attrs; + } + return ret; + } + + /* Create context for temporary memory */ + tmp_ctx = talloc_new(ac); + if (tmp_ctx == NULL) { + goto oom; + } + + /* Prepare list of attributes from tree */ + tree_attrs = talloc_array(tmp_ctx, const char *, 1); + if (tree_attrs == NULL) { + talloc_free(tmp_ctx); + goto oom; + } + tree_attrs[0] = NULL; + + /* Collect attributes from tree */ + ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); + if (ret) { + goto done; + } + + /* Merge attributes from search operation */ + ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); + if (ret) { + goto done; + } + + /* Split local from remote attributes */ + ret = map_attrs_partition(module, ac, &local_attrs, + &remote_attrs, tree_attrs); + + if (ret == 0) { + ac->local_attrs = local_attrs; + ac->remote_attrs = remote_attrs; + talloc_steal(ac, tree_attrs); + ac->all_attrs = tree_attrs; + } +done: + /* Free temporary memory */ + talloc_free(tmp_ctx); + return ret; + +oom: + map_oom(module); + return -1; +} + + +/* Outbound requests: search + * ========================= */ + +static int map_remote_search_callback(struct ldb_request *req, + struct ldb_reply *ares); +static int map_local_merge_callback(struct ldb_request *req, + struct ldb_reply *ares); +static int map_search_local(struct map_context *ac); + +static int map_save_entry(struct map_context *ac, struct ldb_reply *ares) +{ + struct map_reply *mr; + + mr = talloc_zero(ac, struct map_reply); + if (mr == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + mr->remote = talloc_steal(mr, ares); + if (ac->r_current) { + ac->r_current->next = mr; + } else { + /* first entry */ + ac->r_list = mr; + } + ac->r_current = mr; + + return LDB_SUCCESS; +} + +/* Pass a merged search result up the callback chain. */ +int map_return_entry(struct map_context *ac, struct ldb_reply *ares) +{ + struct ldb_message_element *el; + const char * const *attrs; + struct ldb_context *ldb; + unsigned int i; + int ret; + bool matched; + + ldb = ldb_module_get_ctx(ac->module); + + /* Merged result doesn't match original query, skip */ + ret = ldb_match_msg_error(ldb, ares->message, + ac->req->op.search.tree, + ac->req->op.search.base, + ac->req->op.search.scope, + &matched); + if (ret != LDB_SUCCESS) return ret; + if (!matched) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " + "Skipping record '%s': " + "doesn't match original search", + ldb_dn_get_linearized(ares->message->dn)); + return LDB_SUCCESS; + } + + /* Limit result to requested attrs */ + if (ac->req->op.search.attrs && + (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) { + + attrs = ac->req->op.search.attrs; + i = 0; + + while (i < ares->message->num_elements) { + + el = &ares->message->elements[i]; + if ( ! ldb_attr_in_list(attrs, el->name)) { + ldb_msg_remove_element(ares->message, el); + } else { + i++; + } + } + } + + return ldb_module_send_entry(ac->req, ares->message, ares->controls); +} + +/* Search a record. */ +int ldb_map_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_parse_tree *remote_tree; + struct ldb_parse_tree *local_tree; + struct ldb_request *remote_req; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + const char *wildcard[] = { "*", NULL }; + const char * const *attrs; + + ldb = ldb_module_get_ctx(module); + + /* if we're not yet initialized, go to the next module */ + if (!ldb_module_get_private(module)) + return ldb_next_request(module, req); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.search.base)) { + return ldb_next_request(module, req); + } + + /* No mapping requested, skip to next module */ + if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { + return ldb_next_request(module, req); + } + + /* TODO: How can we be sure about which partition we are + * targetting when there is no search base? */ + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* It is easier to deal with the two different ways of + * expressing the wildcard in the same codepath */ + attrs = req->op.search.attrs; + if (attrs == NULL) { + attrs = wildcard; + } + + /* Split local from remote attrs */ + ret = map_attrs_collect_and_partition(module, ac, + attrs, req->op.search.tree); + if (ret) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Split local from remote tree */ + ret = ldb_parse_tree_partition(module, ac, + &local_tree, &remote_tree, + req->op.search.tree); + if (ret) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (((local_tree != NULL) && (remote_tree != NULL)) && + (!ldb_parse_tree_check_splittable(req->op.search.tree))) { + /* The query can't safely be split, enumerate the remote partition */ + local_tree = NULL; + remote_tree = NULL; + } + + if (local_tree == NULL) { + /* Construct default local parse tree */ + local_tree = talloc_zero(ac, struct ldb_parse_tree); + if (local_tree == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + local_tree->operation = LDB_OP_PRESENT; + local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); + } + if (remote_tree == NULL) { + /* Construct default remote parse tree */ + remote_tree = ldb_parse_tree(ac, NULL); + if (remote_tree == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ac->local_tree = local_tree; + + /* Prepare the remote operation */ + ret = ldb_build_search_req_ex(&remote_req, ldb, ac, + req->op.search.base, + req->op.search.scope, + remote_tree, + ac->remote_attrs, + req->controls, + ac, map_remote_search_callback, + req); + LDB_REQ_SET_LOCATION(remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_remote_request(module, remote_req); +} + +/* Now, search the local part of a remote search result. */ +static int map_remote_search_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_REFERRAL: + + /* ignore referrals */ + talloc_free(ares); + return LDB_SUCCESS; + + case LDB_REPLY_ENTRY: + + /* Map result record into a local message */ + ret = map_reply_remote(ac, ares); + if (ret) { + talloc_free(ares); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* if we have no local db, then we can just return the reply to + * the upper layer, otherwise we must save it and process it + * when all replies ahve been gathered */ + if ( ! map_check_local_db(ac->module)) { + ret = map_return_entry(ac, ares); + } else { + ret = map_save_entry(ac,ares); + } + + if (ret != LDB_SUCCESS) { + talloc_free(ares); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + break; + + case LDB_REPLY_DONE: + + if ( ! map_check_local_db(ac->module)) { + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + } + + /* reset the pointer to the start of the list */ + ac->r_current = ac->r_list; + + /* no entry just return */ + if (ac->r_current == NULL) { + ret = ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + talloc_free(ares); + return ret; + } + + ac->remote_done_ares = talloc_steal(ac, ares); + + ret = map_search_local(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + } + + return LDB_SUCCESS; +} + +static int map_search_local(struct map_context *ac) +{ + struct ldb_request *search_req; + + if (ac->r_current == NULL || ac->r_current->remote == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare local search request */ + /* TODO: use GUIDs here instead? */ + search_req = map_search_base_req(ac, + ac->r_current->remote->message->dn, + NULL, NULL, + ac, map_local_merge_callback); + if (search_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, search_req); +} + +/* Merge the remote and local parts of a search result. */ +int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + /* We have already found a local record */ + if (ac->r_current->local) { + talloc_free(ares); + ldb_set_errstring(ldb, "ldb_map: Too many results!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Store local result */ + ac->r_current->local = talloc_steal(ac->r_current, ares); + + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + /* We don't need the local 'ares', but we will use the remote one from below */ + talloc_free(ares); + + /* No local record found, map and send remote record */ + if (ac->r_current->local != NULL) { + /* Merge remote into local message */ + ret = ldb_msg_merge_local(ac->module, + ac->r_current->local->message, + ac->r_current->remote->message); + if (ret == LDB_SUCCESS) { + ret = map_return_entry(ac, ac->r_current->local); + } + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + } else { + ret = map_return_entry(ac, ac->r_current->remote); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + } + + if (ac->r_current->next != NULL) { + ac->r_current = ac->r_current->next; + if (ac->r_current->remote->type == LDB_REPLY_ENTRY) { + ret = map_search_local(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + break; + } + } + + /* ok we are done with all search, finally it is time to + * finish operations for this module */ + return ldb_module_done(ac->req, + ac->remote_done_ares->controls, + ac->remote_done_ares->response, + ac->remote_done_ares->error); + } + + return LDB_SUCCESS; +} diff --git a/lib/ldb/ldb_map/ldb_map_private.h b/lib/ldb/ldb_map/ldb_map_private.h new file mode 100644 index 00000000000..7faaa997088 --- /dev/null +++ b/lib/ldb/ldb_map/ldb_map_private.h @@ -0,0 +1,96 @@ +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" + +/* A handy macro to report Out of Memory conditions */ +#define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); + +/* The type of search callback functions */ +typedef int (*ldb_map_callback_t)(struct ldb_request *, struct ldb_reply *); + +/* The special DN from which the local and remote base DNs are fetched */ +#define MAP_DN_NAME "@MAP" +#define MAP_DN_FROM "@FROM" +#define MAP_DN_TO "@TO" + +/* Private data structures + * ======================= */ + +struct map_reply { + struct map_reply *next; + struct ldb_reply *remote; + struct ldb_reply *local; +}; + +/* Context data for mapped requests */ +struct map_context { + + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_dn *local_dn; + const struct ldb_parse_tree *local_tree; + const char * const *local_attrs; + const char * const *remote_attrs; + const char * const *all_attrs; + + struct ldb_message *local_msg; + struct ldb_request *remote_req; + + struct map_reply *r_list; + struct map_reply *r_current; + + /* The response continaing any controls the remote server gave */ + struct ldb_reply *remote_done_ares; +}; + +/* Common operations + * ================= */ + +/* The following definitions come from lib/ldb/modules/ldb_map.c */ +const struct ldb_map_context *map_get_context(struct ldb_module *module); +struct map_context *map_init_context(struct ldb_module *module, + struct ldb_request *req); + +int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); + +bool map_check_local_db(struct ldb_module *module); +bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr); +bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn); + +const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); +const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); + +const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); +const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); +int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); + +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); + +struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); + +struct ldb_request *map_search_base_req(struct map_context *ac, + struct ldb_dn *dn, + const char * const *attrs, + const struct ldb_parse_tree *tree, + void *context, + ldb_map_callback_t callback); +struct ldb_request *map_build_fixup_req(struct map_context *ac, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + void *context, + ldb_map_callback_t callback); +int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, + struct ldb_parse_tree **new, + const struct ldb_parse_tree *tree, + const struct ldb_map_attribute *map); +int map_return_fatal_error(struct ldb_request *req, + struct ldb_reply *ares); +int map_return_normal_error(struct ldb_request *req, + struct ldb_reply *ares, + int error); + +int map_return_entry(struct map_context *ac, struct ldb_reply *ares); diff --git a/lib/ldb/ldb_sqlite3/README b/lib/ldb/ldb_sqlite3/README new file mode 100644 index 00000000000..6cda0a77595 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/README @@ -0,0 +1,7 @@ +trees.ps contains an explanation of the Genealogical Representation of Trees +in Databases which is being used in ldb_sqlite3. Note that we use fgID +representation with 4 bytes per level, so we can represent 6.5E+08 subclasses +of any object class. This should be adequate for our purposes. :-) + +The following document is the primary basis for the schema currently being +used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/lib/ldb/ldb_sqlite3/base160.c b/lib/ldb/ldb_sqlite3/base160.c new file mode 100644 index 00000000000..7ad39f7c2f5 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/base160.c @@ -0,0 +1,154 @@ +/* + base160 code used by ldb_sqlite3 + + Copyright (C) 2004 Derrell Lipman + + 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 . +*/ + + +/* + * ldb_sqlite3_base160() + * + * Convert an integer value to a string containing the base 160 representation + * of the integer. We always convert to a string representation that is 4 + * bytes in length, and we always null terminate. + * + * Parameters: + * val -- + * The value to be converted + * + * result -- + * Buffer in which the result is to be placed + * + * Returns: + * nothing + */ +static unsigned char base160tab[161] = +{ + 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ + 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ + 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ + 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ + 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ + 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ + '\0' +}; + + +/* + * lsqlite3_base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +void +lsqlite3_base160(unsigned long val, + unsigned char result[5]) +{ + int i; + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; +} + + +/* + * lsqlite3_base160Next() + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) are + * operated on. + * + * Parameters: + * base160 -- a character array containing either an empty string (in which + * case no operation is performed), or a string of base160 digits + * with a length of a multiple of four digits. + * + * Upon return, the trailing four digits (one tree level) will + * have been incremented by 1. + * + * Returns: + * base160 -- the modified array + */ +char * +lsqlite3_base160Next(char base160[]) +{ + int i; + int len; + unsigned char * pTab; + char * pBase160 = base160; + + /* + * We need a minimum of four digits, and we will always get a multiple of + * four digits. + */ + if ((len = strlen(pBase160)) >= 4) + { + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* Nope. Just increment this value and we're done. */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets base160tab[0], we + * decrement the buffer pointer to get the next higher-order + * digit, and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + } + + return base160; +} diff --git a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c new file mode 100644 index 00000000000..223868a6c0a --- /dev/null +++ b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -0,0 +1,1940 @@ +/* + ldb database library + + Copyright (C) Derrell Lipman 2005 + Copyright (C) Simo Sorce 2005-2009 + + ** 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 sqlite3 backend + * + * Description: core files for SQLITE3 backend + * + * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) + */ + +#include "ldb_module.h" + +#include + +struct lsqlite3_private { + int trans_count; + char **options; + sqlite3 *sqlite; +}; + +struct lsql_context { + struct ldb_module *module; + struct ldb_request *req; + + /* search stuff */ + long long current_eid; + const char * const * attrs; + struct ldb_reply *ares; + + bool callback_failed; + struct tevent_timer *timeout_event; +}; + +/* + * Macros used throughout + */ + +#ifndef FALSE +# define FALSE (0) +# define TRUE (! FALSE) +#endif + +#define RESULT_ATTR_TABLE "temp_result_attrs" + + +/* for testing, define to nothing, (create non-temporary table) */ +#define TEMPTAB "TEMPORARY" + +/* + * Static variables + */ +sqlite3_stmt * stmtGetEID = NULL; + +static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) +{ + char *str, *ret; + va_list ap; + + va_start(ap, fmt); + str = sqlite3_vmprintf(fmt, ap); + va_end(ap); + + if (str == NULL) return NULL; + + ret = talloc_strdup(mem_ctx, str); + if (ret == NULL) { + sqlite3_free(str); + return NULL; + } + + sqlite3_free(str); + return ret; +} + +static char base160tab[161] = { + 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ + 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ + 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ + 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ + 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ + 109,110,111,112,113,114,115,116,117,118, /* m-v */ + 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ + 166,167,168,169,170,171,172,173,174,175, /* latin1 */ + 176,177,178,179,180,181,182,183,184,185, /* latin1 */ + 186,187,188,189,190,191,192,193,194,195, /* latin1 */ + 196,197,198,199,200,201,202,203,204,205, /* latin1 */ + 206,207,208,209,210,211,212,213,214,215, /* latin1 */ + 216,217,218,219,220,221,222,223,224,225, /* latin1 */ + 226,227,228,229,230,231,232,233,234,235, /* latin1 */ + 236,237,238,239,240,241,242,243,244,245, /* latin1 */ + 246,247,248,249,250,251,252,253,254,255, /* latin1 */ + '\0' +}; + + +/* + * base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +static void +base160_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + long long val; + char result[5]; + + val = sqlite3_value_int64(argv[0]); + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; + + sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); +} + + +/* + * base160next_sql() + * + * This function enhances sqlite by adding a "base160_next()" function which is + * accessible via queries. + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) is + * operated on. + * + * Input: + * A character string: either an empty string (in which case no operation is + * performed), or a string of base160 digits with a length of a multiple of + * four digits. + * + * Output: + * Upon return, the trailing four digits (one tree level) will have been + * incremented by 1. + */ +static void +base160next_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + int len; + char * pTab; + char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); + char * pStart = pBase160; + + /* + * We need a minimum of four digits, and we will always get a multiple + * of four digits. + */ + if (pBase160 != NULL && + (len = strlen(pBase160)) >= 4 && + len % 4 == 0) { + + if (pBase160 == NULL) { + + sqlite3_result_null(hContext); + return; + } + + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* + * Nope. Just increment this value and we're + * done. + */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets + * base160tab[0], we decrement the buffer + * pointer to get the next higher-order digit, + * and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + + sqlite3_result_text(hContext, + pStart, + strlen(pStart), + free); + } else { + sqlite3_result_value(hContext, argv[0]); + if (pBase160 != NULL) { + free(pBase160); + } + } +} + +static char *parsetree_to_sql(struct ldb_module *module, + void *mem_ctx, + const struct ldb_parse_tree *t) +{ + struct ldb_context *ldb; + const struct ldb_schema_attribute *a; + struct ldb_val value, subval; + char *wild_card_string; + char *child, *tmp; + char *ret = NULL; + char *attr; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + switch(t->operation) { + case LDB_OP_AND: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); + if (tmp == NULL) return NULL; + } + + ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); + + return ret; + + case LDB_OP_OR: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " UNION %s ", child); + if (tmp == NULL) return NULL; + } + + return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); + + case LDB_OP_NOT: + + child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); + if (child == NULL) return NULL; + + return talloc_asprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE eid NOT IN ( %s ) ", child); + + case LDB_OP_EQUALITY: + /* + * For simple searches, we want to retrieve the list of EIDs that + * match the criteria. + */ + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + if (strcasecmp(t->u.equality.attr, "dn") == 0) { + /* DN query is a special ldb case */ + const char *cdn = ldb_dn_get_casefold( + ldb_dn_new(mem_ctx, ldb, + (const char *)value.data)); + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE norm_dn = '%q'", cdn); + + } else { + /* A normal query. */ + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value = '%q'", + attr, + value.data); + + } + + case LDB_OP_SUBSTRING: + + wild_card_string = talloc_strdup(mem_ctx, + (t->u.substring.start_with_wildcard)?"*":""); + if (wild_card_string == NULL) return NULL; + + for (i = 0; t->u.substring.chunks[i]; i++) { + wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", + t->u.substring.chunks[i]->data); + if (wild_card_string == NULL) return NULL; + } + + if ( ! t->u.substring.end_with_wildcard ) { + /* remove last wildcard */ + wild_card_string[strlen(wild_card_string) - 1] = '\0'; + } + + attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + subval.data = (void *)wild_card_string; + subval.length = strlen(wild_card_string) + 1; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value GLOB '%q'", + attr, + value.data); + + case LDB_OP_GREATER: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_LESS: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_PRESENT: + if (strcasecmp(t->u.present.attr, "dn") == 0) { + return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); + } + + attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); + if (attr == NULL) return NULL; + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' ", + attr); + + case LDB_OP_APPROX: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_EXTENDED: +#warning "work out how to handle bitops" + return NULL; + + default: + break; + }; + + /* should never occur */ + abort(); + return NULL; +} + +/* + * query_int() + * + * This function is used for the common case of queries that return a single + * integer value. + * + * NOTE: If more than one value is returned by the query, all but the first + * one will be ignored. + */ +static int +query_int(const struct lsqlite3_private * lsqlite3, + long long * pRet, + const char * pSql, + ...) +{ + int ret; + int bLoop; + char * p; + sqlite3_stmt * pStmt; + va_list args; + + /* Begin access to variable argument list */ + va_start(args, pSql); + + /* Format the query */ + if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { + va_end(args); + return SQLITE_NOMEM; + } + + /* + * Prepare and execute the SQL statement. Loop allows retrying on + * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, + * requiring retrying the operation. + */ + for (bLoop = TRUE; bLoop; ) { + + /* Compile the SQL statement into sqlite virtual machine */ + if ((ret = sqlite3_prepare(lsqlite3->sqlite, + p, + -1, + &pStmt, + NULL)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + break; + } + + /* One row expected */ + if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + (void) sqlite3_finalize(pStmt); + continue; + } else if (ret != SQLITE_ROW) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* Get the value to be returned */ + *pRet = sqlite3_column_int64(pStmt, 0); + + /* Free the virtual machine */ + if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* + * Normal condition is only one time through loop. Loop is + * rerun in error conditions, via "continue", above. + */ + bLoop = FALSE; + } + + /* All done with variable argument list */ + va_end(args); + + + /* Free the memory we allocated for our query string */ + sqlite3_free(p); + + return ret; +} + +/* + * This is a bad hack to support ldap style comparisons within sqlite. + * val is the attribute in the row currently under test + * func is the desired test "<=" ">=" "~" ":" + * cmp is the value to compare against (eg: "test") + * attr is the attribute name the value of which we want to test + */ + +static void lsqlite3_compare(sqlite3_context *ctx, int argc, + sqlite3_value **argv) +{ + struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); + const char *val = (const char *)sqlite3_value_text(argv[0]); + const char *func = (const char *)sqlite3_value_text(argv[1]); + const char *cmp = (const char *)sqlite3_value_text(argv[2]); + const char *attr = (const char *)sqlite3_value_text(argv[3]); + const struct ldb_schema_attribute *a; + struct ldb_val valX; + struct ldb_val valY; + int ret; + + switch (func[0]) { + /* greater */ + case '>': /* >= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret >= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* lesser */ + case '<': /* <= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret <= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* approx */ + case '~': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + /* bitops */ + case ':': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + default: + break; + } + + sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); + return; +} + + +/* rename a record */ +static int lsqlite3_safe_rollback(sqlite3 *sqlite) +{ + char *errmsg; + int ret; + + /* execute */ + ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return 0; +} + +/* return an eid as result */ +static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) +{ + long long *eid = (long long *)result; + + if (col_num != 1) return SQLITE_ABORT; + if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; + + *eid = atoll(cols[0]); + return SQLITE_OK; +} + +/* + * add a single set of ldap message values to a ldb_message + */ +static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) +{ + struct ldb_context *ldb; + struct lsql_context *ac; + struct ldb_message *msg; + long long eid; + unsigned int i; + int ret; + + ac = talloc_get_type(result, struct lsql_context); + ldb = ldb_module_get_ctx(ac->module); + + /* eid, dn, attr_name, attr_value */ + if (col_num != 4) return SQLITE_ABORT; + + eid = atoll(cols[0]); + + if (ac->ares) { + msg = ac->ares->message; + } + + if (eid != ac->current_eid) { /* here begin a new entry */ + + /* call the async callback for the last entry + * except the first time */ + if (ac->current_eid != 0) { + ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); + if (ret != LDB_SUCCESS) { + return SQLITE_ABORT; + } + + ret = ldb_module_send_entry(ac->req, msg, NULL); + if (ret != LDB_SUCCESS) { + ac->callback_failed = true; + /* free msg object */ + TALLOC_FREE(msg); + return SQLITE_ABORT; + } + + /* free msg object */ + TALLOC_FREE(msg); + } + + /* start over */ + ac->ares = talloc_zero(ac, struct ldb_reply); + if (!ac->ares) return SQLITE_ABORT; + + msg = ldb_msg_new(ac->ares); + if (!msg) return SQLITE_ABORT; + + ac->ares->type = LDB_REPLY_ENTRY; + ac->current_eid = eid; + } + + if (msg->dn == NULL) { + msg->dn = ldb_dn_new(msg, ldb, cols[1]); + if (msg->dn == NULL) + return SQLITE_ABORT; + } + + if (ac->attrs) { + int found = 0; + for (i = 0; ac->attrs[i]; i++) { + if (strcasecmp(cols[2], ac->attrs[i]) == 0) { + found = 1; + break; + } + } + if (!found) goto done; + } + + if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { + return SQLITE_ABORT; + } + +done: + ac->ares->message = msg; + return SQLITE_OK; +} + + +/* + * lsqlite3_get_eid() + * lsqlite3_get_eid_ndn() + * + * These functions are used for the very common case of retrieving an EID value + * given a (normalized) DN. + */ + +static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) +{ + char *errmsg; + char *query; + long long eid = -1; + long long ret; + + /* get object eid */ + query = lsqlite3_tprintf(mem_ctx, "SELECT eid " + "FROM ldb_entry " + "WHERE norm_dn = '%q';", norm_dn); + if (query == NULL) return -1; + + ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return eid; +} + +static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, + struct ldb_dn *dn) +{ + TALLOC_CTX *local_ctx; + long long eid = -1; + char *cdn; + + /* ignore ltdb specials */ + if (ldb_dn_is_special(dn)) { + return -1; + } + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); + if (local_ctx == NULL) { + return -1; + } + + cdn = ldb_dn_alloc_casefold(local_ctx, dn); + if (!cdn) goto done; + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); + +done: + talloc_free(local_ctx); + return eid; +} + +/* + * Interface functions referenced by lsqlite3_ops + */ + +/* search for matching records, by tree */ +int lsql_search(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *norm_basedn; + char *sqlfilter; + char *errmsg; + char *query = NULL; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if ((( ! ldb_dn_is_valid(req->op.search.base)) || + ldb_dn_is_null(req->op.search.base)) && + (req->op.search.scope == LDB_SCOPE_BASE || + req->op.search.scope == LDB_SCOPE_ONELEVEL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.base) { + norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); + if (norm_basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } else norm_basedn = talloc_strdup(ctx, ""); + + /* Convert filter into a series of SQL conditions (constraints) */ + sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); + + switch(req->op.search.scope) { + case LDB_SCOPE_DEFAULT: + case LDB_SCOPE_SUBTREE: + if (*norm_basedn != '\0') { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" + " OR ldb_entry.norm_dn = '%q')\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + } else { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + sqlfilter); + } + + break; + + case LDB_SCOPE_BASE: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.norm_dn = '%q'\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + sqlfilter); + break; + + case LDB_SCOPE_ONELEVEL: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE norm_dn GLOB('*,%q')\n" + " AND NOT norm_dn GLOB('*,*,%q')\n" + " AND ldb_entry.eid IN\n(%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + break; + } + + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* * / + printf ("%s\n", query); + / * */ + + ctx->current_eid = 0; + ctx->attrs = req->op.search.attrs; + ctx->ares = NULL; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* complete the last message if any */ + if (ctx->ares) { + ret = ldb_msg_normalize(ldb, ctx->ares, + ctx->ares->message, + &ctx->ares->message); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_send_entry(req, ctx->ares->message, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + + return LDB_SUCCESS; +} + +/* add a record */ +static int lsql_add(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.add.message; + long long eid; + char *dn, *ndn; + char *errmsg; + char *query; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { +/* + struct ldb_dn *c; + c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); + if (ldb_dn_compare(ldb, msg->dn, c) == 0) { +#warning "should we handle indexes somehow ?" + ret = LDB_ERR_UNWILLING_TO_PERFORM; + goto done; + } +*/ + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* create linearized and normalized dns */ + dn = ldb_dn_alloc_linearized(ctx, msg->dn); + ndn = ldb_dn_alloc_casefold(ctx, msg->dn); + if (dn == NULL || ndn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Add new entry */ + "INSERT OR ABORT INTO ldb_entry " + "('dn', 'norm_dn') " + "VALUES ('%q', '%q');", + dn, ndn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + char *attr; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + if (el->num_value == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + char *insert; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + insert = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + if (insert == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + } + + return LDB_SUCCESS; +} + +/* modify a record */ +static int lsql_modify(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.mod.message; + long long eid; + char *errmsg; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + eid = lsqlite3_get_eid(lsqlite3, msg->dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; + char *attr; + char *mod; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + switch (flags) { + + case LDB_FLAG_MOD_REPLACE: + + for (j=0; jnum_values; j++) { + if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { + ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + } + + /* remove all attributes before adding the replacements */ + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* MISSING break is INTENTIONAL */ + + case LDB_FLAG_MOD_ADD: + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + + case LDB_FLAG_MOD_DELETE: +#warning "We should throw an error if the attribute we are trying to delete does not exist!" + if (el->num_values == 0) { + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q' " + "AND norm_attr_value = '%q';", + eid, attr, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + } + } + + return LDB_SUCCESS; +} + +/* delete a record */ +static int lsql_delete(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + long long eid; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Delete entry */ + "DELETE FROM ldb_entry WHERE eid = %lld; " + /* Delete attributes */ + "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", + eid, eid); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* rename a record */ +static int lsql_rename(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *new_dn, *new_cdn, *old_cdn; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* create linearized and normalized dns */ + old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); + new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); + new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); + if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* build the SQL query */ + query = lsqlite3_tprintf(ctx, + "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " + "WHERE norm_dn = '%q';", + new_dn, new_cdn, old_cdn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* execute */ + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static int lsql_start_trans(struct ldb_module * module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_start_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + }; + + lsqlite3->trans_count++; + + return 0; +} + +static int lsql_end_trans(struct ldb_module *module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_end_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + } + + return 0; +} + +static int lsql_del_trans(struct ldb_module *module) +{ + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + return lsqlite3_safe_rollback(lsqlite3->sqlite); + } + + return -1; +} + +static int destructor(struct lsqlite3_private *lsqlite3) +{ + if (lsqlite3->sqlite) { + sqlite3_close(lsqlite3->sqlite); + } + return 0; +} + +static void lsql_request_done(struct lsql_context *ctx, int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->error = error; + + req->callback(req, ares); +} + +static void lsql_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + ctx = talloc_get_type(private_data, struct lsql_context); + + lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void lsql_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + int ret; + + ctx = talloc_get_type(private_data, struct lsql_context); + + switch (ctx->req->operation) { + case LDB_SEARCH: + ret = lsql_search(ctx); + break; + case LDB_ADD: + ret = lsql_add(ctx); + break; + case LDB_MODIFY: + ret = lsql_modify(ctx); + break; + case LDB_DELETE: + ret = lsql_delete(ctx); + break; + case LDB_RENAME: + ret = lsql_rename(ctx); + break; +/* TODO: + case LDB_EXTENDED: + ret = lsql_extended(ctx); + break; + */ + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + } + + if (!ctx->callback_failed) { + /* Once we are done, we do not need timeout events */ + talloc_free(ctx->timeout_event); + lsql_request_done(ctx, ret); + } +} + +static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct tevent_context *ev; + struct lsql_context *ac; + struct tevent_timer *te; + struct timeval tv; + + if (ldb_check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ldb = ldb_module_get_ctx(module); + ev = ldb_get_event_context(ldb); + + ac = talloc_zero(req, struct lsql_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + tv.tv_sec = req->starttime + req->timeout; + ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); + if (NULL == ac->timeout_event) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* + * Table of operations for the sqlite3 backend + */ +static const struct ldb_module_ops lsqlite3_ops = { + .name = "sqlite", + .search = lsql_handle_request, + .add = lsql_handle_request, + .modify = lsql_handle_request, + .del = lsql_handle_request, + .rename = lsql_handle_request, + .extended = lsql_handle_request, + .start_transaction = lsql_start_trans, + .end_transaction = lsql_end_trans, + .del_transaction = lsql_del_trans, +}; + +/* + * Static functions + */ + +static int initialize(struct lsqlite3_private *lsqlite3, + struct ldb_context *ldb, const char *url, + unsigned int flags) +{ + TALLOC_CTX *local_ctx; + long long queryInt; + int rollback = 0; + char *errmsg; + char *schema; + int ret; + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); + if (local_ctx == NULL) { + return -1; + } + + schema = lsqlite3_tprintf(local_ctx, + + + "CREATE TABLE ldb_info AS " + " SELECT 'LDB' AS database_type," + " '1.0' AS version;" + + /* + * The entry table holds the information about an entry. + * This table is used to obtain the EID of the entry and to + * support scope=one and scope=base. The parent and child + * table is included in the entry table since all the other + * attributes are dependent on EID. + */ + "CREATE TABLE ldb_entry " + "(" + " eid INTEGER PRIMARY KEY AUTOINCREMENT," + " dn TEXT UNIQUE NOT NULL," + " norm_dn TEXT UNIQUE NOT NULL" + ");" + + + "CREATE TABLE ldb_object_classes" + "(" + " class_name TEXT PRIMARY KEY," + " parent_class_name TEXT," + " tree_key TEXT UNIQUE," + " max_child_num INTEGER DEFAULT 0" + ");" + + /* + * We keep a full listing of attribute/value pairs here + */ + "CREATE TABLE ldb_attribute_values" + "(" + " eid INTEGER REFERENCES ldb_entry," + " attr_name TEXT," + " norm_attr_name TEXT," + " attr_value TEXT," + " norm_attr_value TEXT " + ");" + + + /* + * Indexes + */ + "CREATE INDEX ldb_attribute_values_eid_idx " + " ON ldb_attribute_values (eid);" + + "CREATE INDEX ldb_attribute_values_name_value_idx " + " ON ldb_attribute_values (attr_name, norm_attr_value);" + + + + /* + * Triggers + */ + + "CREATE TRIGGER ldb_object_classes_insert_tr" + " AFTER INSERT" + " ON ldb_object_classes" + " FOR EACH ROW" + " BEGIN" + " UPDATE ldb_object_classes" + " SET tree_key = COALESCE(tree_key, " + " (" + " SELECT tree_key || " + " (SELECT base160(max_child_num + 1)" + " FROM ldb_object_classes" + " WHERE class_name = " + " new.parent_class_name)" + " FROM ldb_object_classes " + " WHERE class_name = new.parent_class_name " + " ));" + " UPDATE ldb_object_classes " + " SET max_child_num = max_child_num + 1" + " WHERE class_name = new.parent_class_name;" + " END;" + + /* + * Table initialization + */ + + "INSERT INTO ldb_object_classes " + " (class_name, tree_key) " + " VALUES " + " ('TOP', '0001');"); + + /* Skip protocol indicator of url */ + if (strncmp(url, "sqlite3://", 10) != 0) { + return SQLITE_MISUSE; + } + + /* Update pointer to just after the protocol indicator */ + url += 10; + + /* Try to open the (possibly empty/non-existent) database */ + if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { + return ret; + } + + /* In case this is a new database, enable auto_vacuum */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + if (flags & LDB_FLG_NOSYNC) { + /* DANGEROUS */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } + + /* */ + + /* Establish a busy timeout of 30 seconds */ + if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, + 30000)) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to increment a tree_key */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160_next", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160next_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to convert int to base160 */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to perform various comparisons */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite, /* handle */ + "ldap_compare", /* function name */ + 4, /* number of args */ + SQLITE_ANY, /* preferred text type */ + ldb , /* user data */ + lsqlite3_compare, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Begin a transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: initialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + rollback = 1; + + /* Determine if this is a new database. No tables means it is. */ + if (query_int(lsqlite3, + &queryInt, + "SELECT COUNT(*)\n" + " FROM sqlite_master\n" + " WHERE type = 'table';") != 0) { + goto failed; + } + + if (queryInt == 0) { + /* + * Create the database schema + */ + ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } else { + /* + * Ensure that the database we opened is one of ours + */ + if (query_int(lsqlite3, + &queryInt, + "SELECT " + " (SELECT COUNT(*) = 2" + " FROM sqlite_master " + " WHERE type = 'table' " + " AND name IN " + " (" + " 'ldb_entry', " + " 'ldb_object_classes' " + " ) " + " ) " + " AND " + " (SELECT 1 " + " FROM ldb_info " + " WHERE database_type = 'LDB' " + " AND version = '1.0'" + " );") != 0 || + queryInt != 1) { + + /* It's not one that we created. See ya! */ + goto failed; + } + } + + /* Commit the transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: iniialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + return SQLITE_OK; + +failed: + if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); + sqlite3_close(lsqlite3->sqlite); + return -1; +} + +/* + * connect to the database + */ +static int lsqlite3_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct lsqlite3_private *lsqlite3; + unsigned int i; + int ret; + + module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + lsqlite3 = talloc(module, struct lsqlite3_private); + if (!lsqlite3) { + goto failed; + } + + lsqlite3->sqlite = NULL; + lsqlite3->options = NULL; + lsqlite3->trans_count = 0; + + ret = initialize(lsqlite3, ldb, url, flags); + if (ret != SQLITE_OK) { + goto failed; + } + + talloc_set_destructor(lsqlite3, destructor); + + ldb_module_set_private(module, lsqlite3); + + if (options) { + /* + * take a copy of the options array, so we don't have to rely + * on the caller keeping it around (it might be dynamic) + */ + for (i=0;options[i];i++) ; + + lsqlite3->options = talloc_array(lsqlite3, char *, i+1); + if (!lsqlite3->options) { + goto failed; + } + + for (i=0;options[i];i++) { + + lsqlite3->options[i+1] = NULL; + lsqlite3->options[i] = + talloc_strdup(lsqlite3->options, options[i]); + if (!lsqlite3->options[i]) { + goto failed; + } + } + } + + *_module = module; + return LDB_SUCCESS; + +failed: + if (lsqlite3 && lsqlite3->sqlite != NULL) { + (void) sqlite3_close(lsqlite3->sqlite); + } + talloc_free(lsqlite3); + return LDB_ERR_OPERATIONS_ERROR; +} + +int ldb_sqlite3_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("sqlite3", lsqlite3_connect, false); +} diff --git a/lib/ldb/ldb_sqlite3/schema b/lib/ldb/ldb_sqlite3/schema new file mode 100644 index 00000000000..ab7c5cc406f --- /dev/null +++ b/lib/ldb/ldb_sqlite3/schema @@ -0,0 +1,328 @@ + -- ------------------------------------------------------ + + PRAGMA auto_vacuum=1; + + -- ------------------------------------------------------ + + BEGIN EXCLUSIVE; + + -- ------------------------------------------------------ + + CREATE TABLE ldb_info AS + SELECT 'LDB' AS database_type, + '1.0' AS version; + + /* + * Get the next USN value with: + * BEGIN EXCLUSIVE; + * UPDATE usn SET value = value + 1; + * SELECT value FROM usn; + * COMMIT; + */ + CREATE TABLE usn + ( + value INTEGER + ); + + CREATE TABLE ldb_object + ( + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT PRIMARY KEY, + + parent_tree_key TEXT, + dn TEXT, + + attr_name TEXT REFERENCES ldb_attributes, + attr_value TEXT, + + /* + * object_type can take on these values (to date): + * 1: object is a node of a DN + * 2: object is an attribute/value pair of its parent DN + */ + object_type INTEGER, + + /* + * if object_type is 1, the node can have children. + * this tracks the maximum previously assigned child + * number so we can generate a new unique tree key for + * a new child object. note that this is always incremented, + * so if children are deleted, this will not represent + * the _number_ of children. + */ + max_child_num INTEGER, + + /* + * Automatically maintained meta-data (a gift for metze) + */ + object_guid TEXT UNIQUE, + timestamp INTEGER, -- originating_time + invoke_id TEXT, -- GUID: originating_invocation_id + usn INTEGER, -- hyper: originating_usn + + /* do not allow duplicate name/value pairs */ + UNIQUE (parent_tree_key, attr_name, attr_value, object_type) + ); + + CREATE TABLE ldb_attributes + ( + attr_name TEXT PRIMARY KEY, + parent_tree_key TEXT, + + objectclass_p BOOLEAN DEFAULT 0, + + case_insensitive_p BOOLEAN DEFAULT 0, + wildcard_p BOOLEAN DEFAULT 0, + hidden_p BOOLEAN DEFAULT 0, + integer_p BOOLEAN DEFAULT 0, + + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT, -- null if not a object/sub class + -- level 1 if an objectclass + -- level 1-n if a subclass + max_child_num INTEGER + ); + + -- ------------------------------------------------------ + + CREATE INDEX ldb_object_dn_idx + ON ldb_object (dn); + + CREATE INDEX ldb_attributes_tree_key_ids + ON ldb_attributes (tree_key); + + -- ------------------------------------------------------ + + /* Gifts for metze. Automatically updated meta-data */ + CREATE TRIGGER ldb_object_insert_tr + AFTER INSERT + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE ldb_object + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_object + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0, + object_guid = random_guid(), + timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_object_update_tr + AFTER UPDATE + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_attributes_insert_tr + AFTER INSERT + ON ldb_attributes + FOR EACH ROW + BEGIN + UPDATE ldb_attributes + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE ldb_attributes + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_attributes + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0 + WHERE tree_key = new.tree_key; + END; + + + -- ------------------------------------------------------ + + /* Initialize usn */ + INSERT INTO usn (value) VALUES (0); + + /* Create root object */ + INSERT INTO ldb_object + (tree_key, parent_tree_key, + dn, + object_type, max_child_num) + VALUES ('', NULL, + '', + 1, 0); + + /* We need an implicit "top" level object class */ + INSERT INTO ldb_attributes (attr_name, + parent_tree_key) + SELECT 'top', ''; + + -- ------------------------------------------------------ + + COMMIT; + + -- ------------------------------------------------------ + +/* + * dn: o=University of Michigan,c=US + * objectclass: organization + * objectclass: domainRelatedObject + */ +-- newDN +BEGIN; + +INSERT OR IGNORE INTO ldb_object + (parent_tree_key + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('', + 'c=US', + 'c', 'US', 1, 0); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('0001', + 'o=University of Michigan,c=US', + 'o', 'University of Michigan', 1, 0); + +-- newObjectClass +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'organization', 2, 0); + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'domainRelatedObject', 2, 0); + +COMMIT; + + +/* + * dn: o=University of Michigan,c=US + * l: Ann Arbor, Michigan + * st: Michigan + * o: University of Michigan + * o: UMICH + * seeAlso: + * telephonenumber: +1 313 764-1817 + */ +-- addAttrValuePair +BEGIN; + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'l', 'Ann Arbor, Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'st', 'Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'University of Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'UMICH', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'seeAlso', '', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'telephonenumber', '+1 313 764-1817', 2, 0); + +COMMIT; + +-- ---------------------------------------------------------------------- + +/* + * dn: @ATTRIBUTES + * uid: CASE_INSENSITIVE WILDCARD + * cn: CASE_INSENSITIVE + * ou: CASE_INSENSITIVE + * dn: CASE_INSENSITIVE + */ +-- newAttribute + +BEGIN; + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('uid', '', 0); + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 1, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'uid' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'cn' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'ou' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'dn' + diff --git a/lib/ldb/ldb_sqlite3/trees.ps b/lib/ldb/ldb_sqlite3/trees.ps new file mode 100644 index 00000000000..433a064816c --- /dev/null +++ b/lib/ldb/ldb_sqlite3/trees.ps @@ -0,0 +1,1760 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: trees.dvi +%%Pages: 7 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -f trees.dvi +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2000.05.06:2055 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) +@start +%DVIPSBitmapFont: Fa cmr10 10 6 +/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B +120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 +6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 +D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F +A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 +5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 +F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DI54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmr7 7 3 +/Fb 3 55 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 +15267BA521>I54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmmi10 10 1 +/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 +0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 +0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 +7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 +49EC7FC0B8C8FC16FC16C03E397DB845>68 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd ectt1000 10 73 +/Fd 73 126 df37 +D39 +D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F +5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F +12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> +I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 +A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F +1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< +EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 +E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB +07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 +12E0B712F8A4C700F8C7FCB0147025267DAB2C>II<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 +D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F +92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 +7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 +7021417BB92C>II<1307497EA2131F +A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 +E01C3477B32C>II<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 +9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E +B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C +000114C06C6C90C7FCEB0FF823347CB22C>53 DI<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A +5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A +A5133F91C8FCAA131E23357CB32C>I59 D<1502ED0F80151F157F15 +FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 +C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 +6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED +0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 +25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 +FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC +0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F +F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 +A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 +4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC +497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 +03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F +E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 +E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 +13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 +7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C +130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 +25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED +0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 +153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 +B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC +A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 +F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C +7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC +01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE +5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D +137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 +7DB32C>II<007FB512F8B612FCA36C14 +F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 +ED01F8A8007FB6FCB7FCA36C15F025337DB22C>IIII<007FB512C0B612 +F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 +ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E +B22C>II<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 +6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F +81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 +381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE +143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C +14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC +A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 +D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 +B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C +13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC +E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>III<3A3FFF03FFE0484913F0148714076C6D13E03A01 +F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D +90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB +7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE +6C15FC497E27337EB22C>II<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC +17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 +7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E +A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED +070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 +7DB92C>II<007FB6FCB71280A46C150021067B7D +2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC +5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 +000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF +FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 +383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>II<90 +3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC +5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A +6C5C6C6C5B011F13E0010390C7FC21247AA32C>III103 +DI< +1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F +B512FCB612FEA36C14FC1F3479B32C>I107 D<387FFFE0B57EA37EEA0003B3B3A5007F +B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 +7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 +3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F +F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B +5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>II<397FF01FE0 +39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 +5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 +9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 +7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 +48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F +6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A +1480A36E140029367DA32C>II<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB +00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 +FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 +148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 +ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 +2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 +00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 +8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 +3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 +E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC +140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F +806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D +A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 +14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 +27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F +E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E +1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe ecti1000 10 33 +/Fe 33 122 df28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 +495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC +A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 +001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C +AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 +A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC +120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 +18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 +140E140CA3141C1418A2333275AD40>43 DI<120E +EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 +F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 +5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F +4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 +7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 +D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC +A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 +7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 +1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 +0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 +1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 +D79 +D81 D<92383FC00E913901FFF01C020713FC91 +391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F +15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 +80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A +A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 +8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A +D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F +C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C +A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F +871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F +5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF +076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 +D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F +80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 +0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 +C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 +70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F +90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 +380F81F83803FFE0C690C7FC1D2677A426>II<147F903803FFC090380FC1E09038 +3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 +FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C +EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>IIIII108 +DII<147F903803FFC090380FC1F090381F00F8 +017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A +4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E +6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 +3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C +A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A +6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 +03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A +3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 +015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 +D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 +15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 +0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC +1C267AA422>II<01F013 +0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 +0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 +0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 +D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 +13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C +A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E +EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 +D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 +1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D +A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 +133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 +3679A428>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmsy10 10 1 +/Ff 1 16 df15 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg ecbx1000 10 36 +/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF +8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 +C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D45 +DI<141E143E +14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 +DI54 D58 D66 DII73 +D76 DII< +EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 +6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 +3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C +4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 +C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>III83 D85 DII<13 +FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB +3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 +C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 +35>98 D100 +D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC +1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F +6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 +257DA42C>II<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 +8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 +FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 +6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C +6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< +EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 +A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED +1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 +6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 +D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 +FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA +CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 +A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 +13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 +FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 +491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C +6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB +0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC +91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F +383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C +14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 +F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B +5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 +3FFFC06D1380903803FE001D357EB425>I118 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh ecrm1000 10 89 +/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 +0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 +A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 +3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 +12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I21 D27 +DI30 D36 D<141FEC7FC0903801F0 +E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 +5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED +0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F +1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 +3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 +6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 +26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 +1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 +C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E +A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E +7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E +6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F +80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A +5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 +D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A +12600A19798817>II<121C127FEAFF80A5EA7F00121C09097988 +17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 +0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 +91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 +90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A +>II +III<1538A2157815F8A214011403 +1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 +1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA +4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 +92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C +7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A +5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A +>II<12301238123E003FB612E0A316C05A168016 +000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C +1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A +7BB72A>III<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A +1206120E5A5A5A12600A3479A317>II<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 +EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 +1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 +ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 +1ECBFC127812E0322E79AB41>II<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 +0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 +7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E +A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 +DI<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 +FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 +48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 +3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 +5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D +7BBA3C>IIIIIII<013FB512 +E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C +5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>IIIIIIIII< +D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F +003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 +F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 +151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D +EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< +003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 +A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>IIII89 D<003FB7FCA39039FC0001FE +01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 +FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB +0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 +48495A49130FB8FCA329397BB833>II93 D<007FB81280B912C0A26C17 +803204797041>95 D97 DIIII<147E903803FF8090 +380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC +B3AB487E387FFFF8A31C3B7FBA19>IIIIIII<2703F00FF0EB1FE000FFD93FFCEB +7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC +49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 +>I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E +A25BA35BB3A3486C497EB500C1B51280A329257EA42E>II<3903F01F +E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 +49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 +C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> +II<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 +9038FC0080491300A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F812011203 +1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE +EB01F81A347FB220>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038 +EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A +A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 +EB03FC90B5FCA21F247EA325>II<126012F0B3B3B3 +B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 +07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C +133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi ecbx1440 14.4 34 +/Fi 34 118 df28 D45 D<151E153E15FE1403140F147FEB07FF00 +03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 +DI<913807FFC0027F13FC0103B67E010F15E090 +261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 +17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 +030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 +138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 +FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F +FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 +>I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 +FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C +49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 +FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A +5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 +B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 +16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 +E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF +E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I58 +D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF +5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F +498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 +98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F +7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F +01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 +801303040301F8CAFC595479D267>71 D73 D76 +D78 D80 D<93381FFF800303B512FC033FECFFC0 +92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E +7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 +86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 +A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 +EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 +7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 +C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB +83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 +1C00735B735B735B735B9638003FC0556A79D263>III<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 +49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 +B912C0A550517BD05B>I97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB +07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 +C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E +6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 +138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 +49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 +4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D +5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F +010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 +076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 +90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 +3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A +D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C +>IIII<133FEBFFC0 +487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 +12F0A51C547CD324>I108 +DII<913801FFC0023F13FE91B67E010315E001 +0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 +488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F +A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE +6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>II<90393FF001FCB590 +380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 +80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 +D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 +1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C +14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 +150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 +39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 +14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F +FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F +1380DA03FEC7FC294D7ECB33>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj ecrm0900 9 5 +/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D97 DI104 +D108 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk ecbx0900 9 7 +/Fk 7 117 df65 D97 DI<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 +A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 +07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF +EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 +1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 +5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB +007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 +E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 +FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl ecrm1200 12 25 +/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 +80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 +3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 +F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 +6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 +F8903807FFE0010090C7FC28447CC131>48 D50 D54 D<16C04B7EA34B7EA34B7EA34B7EA3ED +19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 +06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 +C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 +D80FFF03037FB500E0027FEBFFC0A342477DC649>65 DI68 D77 +D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 +181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 +D +I97 +D99 D<167FED3FFFA315018182B3EC7F80903803 +FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 +127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C +010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>II103 D105 D108 D<3901FC01FE00FF903807FFC091381E +07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 +486CECFF80B5D8F83F13FEA32F2C7DAB36>110 DI<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 +7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 +D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 +1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 +011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 +F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E +A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C +017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 +>III< +B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 +6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 +FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 +06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 +F02E3F7EAA33>121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm ecbx1200 12 47 +/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A +001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 +F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 +006C486D5AD801F0EB00F82A2283C427>16 DI28 D46 D48 DIII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 +C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B +485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 +7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 +FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E +01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 +F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB +FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 +027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 +5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F +FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 +5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D +4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 +3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 +7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A +5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A +6D5A2F447AC238>I58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 +FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA +07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 +EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 +007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 +FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 +19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB +3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF +9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 +0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF +80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED +1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE +CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 +0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 +D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D +7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 +E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 +007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E +6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C +6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C +7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC +49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 +DIIII73 D77 D<923807FFC092B512FE0207ECFFC0021F15F0 +91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 +6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 +82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 +F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D +6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 +004AC8FC030713C047467AC454>79 D83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D +7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 +90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B +127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 +6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 DIIIIIII<137C48B4FC4813804813C0A24813E0A56C13 +C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> +I108 D<90277F8007FEEC0FFC +B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D +8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E +A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 +3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 +F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>II<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F +FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF +3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F +FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>II<90387F807FB53881FFE002 +8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED +01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F +381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F +FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 +F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A +00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>II< +D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 +13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I +I120 +D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 +3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 +48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 +292C7DAB32>122 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn ecrm1728 17.28 8 +/Fn 8 117 df68 D70 D97 D102 D<1378EA01FE487E487FA66C +90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F +B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 +3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB +0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 +D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 +1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE +381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F +13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 +077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 +12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 +0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 +80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 +FC2A597ED734>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo ecbx1728 17.28 18 +/Fo 18 117 df68 D<942603FFF8151C94B66C +143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 +B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF +91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 +075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F +B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F +6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 +C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B +C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 +D82 D<001FBD12F0A59126F8000191C7123F4801C0 +060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC +A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 +D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 +6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC +90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 +FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF +6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 +C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B +C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 +12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B +6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F +1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F +C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 +4C657CE356>II101 DII105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 +12E0A523647CE32A>108 D110 D<92381FFF804AB512F8020F +14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 +486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 +C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F +6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D +9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF +8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF +806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 +851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B +6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 +3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I114 DII E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 +b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 +1063 y Fm(Miguel)36 b(Sofer)i()1359 1179 +y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 +b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 +1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 +2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 +b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f +(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g +(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 +2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h +(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 +b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i +(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 +2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n +(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 +b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 +2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g +(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e +(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h +(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h +(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) +220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 +b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h +(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 +3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g +(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g +(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 +b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 +b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r +(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f +(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h +(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h +(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g +(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g +(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 +4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n +(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i +(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 +b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r +(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h +(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n +(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 +b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r +(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f +(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e +(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r +(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 +b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f +(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 +b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h +(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n +(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f +(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 +b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n +(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) +49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 +5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f +(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop +%%Page: 2 2 +2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f +(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y +Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j +Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 +b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f +(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 +908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h +(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 +1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f +(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 +b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 +b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g +(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n +(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) +h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 +1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 +b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g +(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 +y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 +b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g +(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 +b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 +1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 +y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h +(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) +h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 +2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) +n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) +n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 +2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g +(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 +b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 +2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 +2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) +g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g +(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 +y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i +(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g +(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f +(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f +(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 +y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g +(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 +b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i +(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h +(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 +2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) +243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g +(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 +b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 +b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 +3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r +(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f +(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) +h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h +(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 +4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 +4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n +(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h +(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f +(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) +k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 +4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) +h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) +40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r +(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 +y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) +243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f +(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f +(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h +(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) +n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h +(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 +5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) +g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 +5653 y(2)p eop +%%Page: 3 3 +3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 +b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 +b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 +b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g +(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g +(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 +b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f +(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 +b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 +b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 +b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g +(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h +(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h +(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 +942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h +(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) +h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 +y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g +(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h +Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g +(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d +(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 +1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 +b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n +(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 +y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f +(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f +(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 +y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y +Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i +(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g +(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 +y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h +(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f +(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 +b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n +(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) +f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i +(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 +b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r +(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 +2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h +(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e +(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 +2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f +(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g +(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 +3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f +(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h +(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h +(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 +b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 +3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f +(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n +(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f +(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g +(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g +(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j +(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e +(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h +(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e +(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 +b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g +(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h +Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h +(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) +h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e +Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 +b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r +(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g +Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 +4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f +(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g +(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g +(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i +(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) +67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 +b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f +(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 +4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 +b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g +(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h +(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 +b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f +(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f +(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h +(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n +(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f +(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f +(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 +b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h +(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g +(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h +(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 +b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f +(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g +(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h +(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f +(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h +(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 +y(forest.)1987 5653 y(3)p eop +%%Page: 4 4 +4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h +(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g +(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 +b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h +(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n +(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f +(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 +771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g +(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 +1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 +b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f +(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 +1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 +b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n +(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b +Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r +(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 +1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h +(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 +2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) +118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g +(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r +(eration,)f(no)i(table)f(access)g(is)g(required.)243 +2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f +(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y +Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f +(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f +(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 +b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 +y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 +3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i +(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y +Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 +3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 +b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 +4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g +('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 +b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n +(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 +b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 +5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 +b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 +5653 y Fh(4)p eop +%%Page: 5 5 +5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h +(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l +(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 +543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 +b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g +(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r +(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 +b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 +743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f +(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d +(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 +b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 +b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f +(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k +(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 +1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) +g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h +(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 +b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f +(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i +(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 +b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h +(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 +b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j +(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r +(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 +b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r +(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f +(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 +2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) +118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f +(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h +(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g +(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y +Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e +(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 +b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 +2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e +(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j +(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 +3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 +3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 +b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 +y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 +b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 +b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g +(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 +b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 +4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l +(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f +(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 +b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 +b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y +Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o +(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 +b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 +b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g +(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f()243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) +r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n +(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 +b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h +(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f +(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop +%%Page: 6 6 +6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 +444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f +(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 +b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d +(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 +b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 +b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) +413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 +y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o +(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f +('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g +(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h +(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 +1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f +(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e +(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 +b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 +1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 +2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o +(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 +2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y +Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g +(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n +(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n +(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o +(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 +2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 +b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h +(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 +3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e +(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h +(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 +y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 +b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 +b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 +4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 +y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 +b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r +(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h +(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h +(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n +(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 +b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g +(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 +4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h +(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h +(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n +(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n +(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g +(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 +5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p +eop +%%Page: 7 7 +7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n +(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n +(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 +556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e +(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n +(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g +(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 +822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i +(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h +(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 +1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 +y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) +r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f +(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 +b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 +1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 +b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p +Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 +y Fh()160 2200 +y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p +Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) +289 2299 y()289 +2399 y()289 +2498 y()289 +2598 y()160 +2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 +b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 +y()1987 5653 +y(7)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/lib/ldb/ldb_tdb/ldb_cache.c b/lib/ldb/ldb_tdb/ldb_cache.c new file mode 100644 index 00000000000..e54ceaaa98a --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_cache.c @@ -0,0 +1,490 @@ +/* + 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 tdb cache functions + * + * Description: cache special records in a ldb/tdb + * + * Author: Andrew Tridgell + */ + +#include "ldb_tdb.h" +#include "ldb_private.h" + +#define LTDB_FLAG_CASE_INSENSITIVE (1<<0) +#define LTDB_FLAG_INTEGER (1<<1) +#define LTDB_FLAG_HIDDEN (1<<2) + +/* valid attribute flags */ +static const struct { + const char *name; + int value; +} ltdb_valid_attr_flags[] = { + { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE }, + { "INTEGER", LTDB_FLAG_INTEGER }, + { "HIDDEN", LTDB_FLAG_HIDDEN }, + { "NONE", 0 }, + { NULL, 0 } +}; + + +/* + de-register any special handlers for @ATTRIBUTES +*/ +static void ltdb_attributes_unload(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + struct ldb_message *msg; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + if (ltdb->cache->attributes == NULL) { + /* no previously loaded attributes */ + return; + } + + msg = ltdb->cache->attributes; + for (i=0;inum_elements;i++) { + ldb_schema_attribute_remove(ldb, msg->elements[i].name); + } + + talloc_free(ltdb->cache->attributes); + ltdb->cache->attributes = NULL; +} + +/* + add up the attrib flags for a @ATTRIBUTES element +*/ +static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) +{ + unsigned int i; + unsigned value = 0; + for (i=0;inum_values;i++) { + unsigned int j; + for (j=0;ltdb_valid_attr_flags[j].name;j++) { + if (strcmp(ltdb_valid_attr_flags[j].name, + (char *)el->values[i].data) == 0) { + value |= ltdb_valid_attr_flags[j].value; + break; + } + } + if (ltdb_valid_attr_flags[j].name == NULL) { + return -1; + } + } + *v = value; + return 0; +} + +/* + register any special handlers from @ATTRIBUTES +*/ +static int ltdb_attributes_load(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + struct ldb_message *msg = ltdb->cache->attributes; + struct ldb_dn *dn; + unsigned int i; + int r; + + ldb = ldb_module_get_ctx(module); + + if (ldb->schema.attribute_handler_override) { + /* we skip loading the @ATTRIBUTES record when a module is supplying + its own attribute handling */ + return 0; + } + + dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES); + if (dn == NULL) goto failed; + + r = ltdb_search_dn1(module, dn, msg); + talloc_free(dn); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } + if (r == LDB_ERR_NO_SUCH_OBJECT) { + return 0; + } + /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, + but its close enough for now */ + for (i=0;inum_elements;i++) { + unsigned flags; + const char *syntax; + const struct ldb_schema_syntax *s; + + if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name); + goto failed; + } + switch (flags & ~LTDB_FLAG_HIDDEN) { + case 0: + syntax = LDB_SYNTAX_OCTET_STRING; + break; + case LTDB_FLAG_CASE_INSENSITIVE: + syntax = LDB_SYNTAX_DIRECTORY_STRING; + break; + case LTDB_FLAG_INTEGER: + syntax = LDB_SYNTAX_INTEGER; + break; + default: + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES", + flags, msg->elements[i].name); + goto failed; + } + + s = ldb_standard_syntax_by_name(ldb, syntax); + if (s == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES", + syntax, msg->elements[i].name); + goto failed; + } + + flags |= LDB_ATTR_FLAG_ALLOCATED; + if (ldb_schema_attribute_add_with_syntax(ldb, msg->elements[i].name, flags, s) != 0) { + goto failed; + } + } + + return 0; +failed: + return -1; +} + + +/* + initialise the baseinfo record +*/ +static int ltdb_baseinfo_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + struct ldb_message *msg; + struct ldb_message_element el; + struct ldb_val val; + int ret; + /* the initial sequence number must be different from the one + set in ltdb_cache_free(). Thanks to Jon for pointing this + out. */ + const char *initial_sequence_number = "1"; + + ldb = ldb_module_get_ctx(module); + + ltdb->sequence_number = atof(initial_sequence_number); + + msg = ldb_msg_new(ltdb); + if (msg == NULL) { + goto failed; + } + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO); + if (!msg->dn) { + goto failed; + } + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); + if (!el.name) { + goto failed; + } + el.values = &val; + el.num_values = 1; + el.flags = 0; + val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); + if (!val.data) { + goto failed; + } + val.length = 1; + + ret = ltdb_store(module, msg, TDB_INSERT); + + talloc_free(msg); + + return ret; + +failed: + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + free any cache records + */ +static void ltdb_cache_free(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + + ltdb->sequence_number = 0; + talloc_free(ltdb->cache); + ltdb->cache = NULL; +} + +/* + force a cache reload +*/ +int ltdb_cache_reload(struct ldb_module *module) +{ + ltdb_attributes_unload(module); + ltdb_cache_free(module); + return ltdb_cache_load(module); +} + +/* + load the cache records +*/ +int ltdb_cache_load(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL; + struct ldb_dn *indexlist_dn = NULL; + uint64_t seq; + struct ldb_message *baseinfo = NULL, *options = NULL; + int r; + + ldb = ldb_module_get_ctx(module); + + /* a very fast check to avoid extra database reads */ + if (ltdb->cache != NULL && + tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) { + return 0; + } + + if (ltdb->cache == NULL) { + ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); + if (ltdb->cache == NULL) goto failed; + ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); + ltdb->cache->attributes = ldb_msg_new(ltdb->cache); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + } + + baseinfo = ldb_msg_new(ltdb->cache); + if (baseinfo == NULL) goto failed; + + baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO); + if (baseinfo_dn == NULL) goto failed; + + r= ltdb_search_dn1(module, baseinfo_dn, baseinfo); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } + + /* possibly initialise the baseinfo */ + if (r == LDB_ERR_NO_SUCH_OBJECT) { + if (ltdb_baseinfo_init(module) != LDB_SUCCESS) { + goto failed; + } + if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) != LDB_SUCCESS) { + goto failed; + } + } + + ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); + + /* if the current internal sequence number is the same as the one + in the database then assume the rest of the cache is OK */ + seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0); + if (seq == ltdb->sequence_number) { + goto done; + } + ltdb->sequence_number = seq; + + /* Read an interpret database options */ + options = ldb_msg_new(ltdb->cache); + if (options == NULL) goto failed; + + options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS); + if (options_dn == NULL) goto failed; + + r= ltdb_search_dn1(module, options_dn, options); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } + + /* set flag for checking base DN on searches */ + if (r == LDB_SUCCESS) { + ltdb->check_base = ldb_msg_find_attr_as_bool(options, LTDB_CHECK_BASE, false); + } else { + ltdb->check_base = false; + } + + talloc_free(ltdb->cache->indexlist); + ltdb_attributes_unload(module); /* calls internally "talloc_free" */ + + ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); + ltdb->cache->attributes = ldb_msg_new(ltdb->cache); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + ltdb->cache->one_level_indexes = false; + ltdb->cache->attribute_indexes = false; + + indexlist_dn = ldb_dn_new(module, ldb, LTDB_INDEXLIST); + if (indexlist_dn == NULL) goto failed; + + r = ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } + + if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) { + ltdb->cache->one_level_indexes = true; + } + if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) { + ltdb->cache->attribute_indexes = true; + } + + if (ltdb_attributes_load(module) == -1) { + goto failed; + } + +done: + talloc_free(options); + talloc_free(baseinfo); + talloc_free(indexlist_dn); + return 0; + +failed: + talloc_free(options); + talloc_free(baseinfo); + talloc_free(indexlist_dn); + return -1; +} + + +/* + increase the sequence number to indicate a database change +*/ +int ltdb_increase_sequence_number(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + struct ldb_message *msg; + struct ldb_message_element el[2]; + struct ldb_val val; + struct ldb_val val_time; + time_t t = time(NULL); + char *s = NULL; + int ret; + + ldb = ldb_module_get_ctx(module); + + msg = ldb_msg_new(ltdb); + if (msg == NULL) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1); + if (!s) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->num_elements = ARRAY_SIZE(el); + msg->elements = el; + msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO); + if (msg->dn == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); + if (el[0].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[0].values = &val; + el[0].num_values = 1; + el[0].flags = LDB_FLAG_MOD_REPLACE; + val.data = (uint8_t *)s; + val.length = strlen(s); + + el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP); + if (el[1].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[1].values = &val_time; + el[1].num_values = 1; + el[1].flags = LDB_FLAG_MOD_REPLACE; + + s = ldb_timestring(msg, t); + if (s == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + val_time.data = (uint8_t *)s; + val_time.length = strlen(s); + + ret = ltdb_modify_internal(module, msg, NULL); + + talloc_free(msg); + + if (ret == LDB_SUCCESS) { + ltdb->sequence_number += 1; + } + + /* updating the tdb_seqnum here avoids us reloading the cache + records due to our own modification */ + ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); + + return ret; +} + +int ltdb_check_at_attributes_values(const struct ldb_val *value) +{ + unsigned int i; + + for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) { + if ((strcmp(ltdb_valid_attr_flags[i].name, (char *)value->data) == 0)) { + return 0; + } + } + + return -1; +} + diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c new file mode 100644 index 00000000000..24cc93feb94 --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -0,0 +1,1599 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004-2009 + + ** 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 tdb backend - indexing + * + * Description: indexing routines for ldb tdb backend + * + * Author: Andrew Tridgell + */ + +#include "ldb_tdb.h" + +struct dn_list { + unsigned int count; + struct ldb_val *dn; +}; + +struct ltdb_idxptr { + struct tdb_context *itdb; + int error; +}; + +/* we put a @IDXVERSION attribute on index entries. This + allows us to tell if it was written by an older version +*/ +#define LTDB_INDEXING_VERSION 2 + +/* enable the idxptr mode when transactions start */ +int ltdb_index_transaction_start(struct ldb_module *module) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr); + return LDB_SUCCESS; +} + +/* compare two DN entries in a dn_list. Take account of possible + * differences in string termination */ +static int dn_list_cmp(const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length > v2->length && v1->data[v2->length] != 0) { + return -1; + } + if (v1->length < v2->length && v2->data[v1->length] != 0) { + return 1; + } + return strncmp((char *)v1->data, (char *)v2->data, v1->length); +} + + +/* + find a entry in a dn_list, using a ldb_val. Uses a case sensitive + comparison with the dn returns -1 if not found + */ +static int ltdb_dn_list_find_val(const struct dn_list *list, const struct ldb_val *v) +{ + unsigned int i; + for (i=0; icount; i++) { + if (dn_list_cmp(&list->dn[i], v) == 0) return i; + } + return -1; +} + +/* + find a entry in a dn_list. Uses a case sensitive comparison with the dn + returns -1 if not found + */ +static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn) +{ + struct ldb_val v; + v.data = discard_const_p(unsigned char, dn); + v.length = strlen(dn); + return ltdb_dn_list_find_val(list, &v); +} + +/* + this is effectively a cast function, but with lots of paranoia + checks and also copes with CPUs that are fussy about pointer + alignment + */ +static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent) +{ + struct dn_list *list; + if (rec.dsize != sizeof(void *)) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Bad data size for idxptr %u", (unsigned)rec.dsize); + return NULL; + } + /* note that we can't just use a cast here, as rec.dptr may + not be aligned sufficiently for a pointer. A cast would cause + platforms like some ARM CPUs to crash */ + memcpy(&list, rec.dptr, sizeof(void *)); + list = talloc_get_type(list, struct dn_list); + if (list == NULL) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Bad type '%s' for idxptr", + talloc_get_name(list)); + return NULL; + } + if (check_parent && list->dn && talloc_parent(list->dn) != list) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Bad parent '%s' for idxptr", + talloc_get_name(talloc_parent(list->dn))); + return NULL; + } + return list; +} + +/* + return the @IDX list in an index entry for a dn as a + struct dn_list + */ +static int ltdb_dn_list_load(struct ldb_module *module, + struct ldb_dn *dn, struct dn_list *list) +{ + struct ldb_message *msg; + int ret; + struct ldb_message_element *el; + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + TDB_DATA rec; + struct dn_list *list2; + TDB_DATA key; + + list->dn = NULL; + list->count = 0; + + /* see if we have any in-memory index entries */ + if (ltdb->idxptr == NULL || + ltdb->idxptr->itdb == NULL) { + goto normal_index; + } + + key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); + key.dsize = strlen((char *)key.dptr); + + rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); + if (rec.dptr == NULL) { + goto normal_index; + } + + /* we've found an in-memory index entry */ + list2 = ltdb_index_idxptr(module, rec, true); + if (list2 == NULL) { + free(rec.dptr); + return LDB_ERR_OPERATIONS_ERROR; + } + free(rec.dptr); + + *list = *list2; + return LDB_SUCCESS; + +normal_index: + msg = ldb_msg_new(list); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_search_dn1(module, dn, msg); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + + /* TODO: check indexing version number */ + + el = ldb_msg_find_element(msg, LTDB_IDX); + if (!el) { + talloc_free(msg); + return LDB_SUCCESS; + } + + /* we avoid copying the strings by stealing the list */ + list->dn = talloc_steal(list, el->values); + list->count = el->num_values; + + return LDB_SUCCESS; +} + + +/* + save a dn_list into a full @IDX style record + */ +static int ltdb_dn_list_store_full(struct ldb_module *module, struct ldb_dn *dn, + struct dn_list *list) +{ + struct ldb_message *msg; + int ret; + + if (list->count == 0) { + ret = ltdb_delete_noindex(module, dn); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return LDB_SUCCESS; + } + return ret; + } + + msg = ldb_msg_new(module); + if (!msg) { + return ldb_module_oom(module); + } + + ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ldb_module_oom(module); + } + + msg->dn = dn; + if (list->count > 0) { + struct ldb_message_element *el; + + ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ldb_module_oom(module); + } + el->values = list->dn; + el->num_values = list->count; + } + + ret = ltdb_store(module, msg, TDB_REPLACE); + talloc_free(msg); + return ret; +} + +/* + save a dn_list into the database, in either @IDX or internal format + */ +static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, + struct dn_list *list) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + TDB_DATA rec, key; + int ret; + struct dn_list *list2; + + if (ltdb->idxptr == NULL) { + return ltdb_dn_list_store_full(module, dn, list); + } + + if (ltdb->idxptr->itdb == NULL) { + ltdb->idxptr->itdb = tdb_open_compat(NULL, 1000, TDB_INTERNAL, O_RDWR, 0, NULL, NULL); + if (ltdb->idxptr->itdb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); + key.dsize = strlen((char *)key.dptr); + + rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); + if (rec.dptr != NULL) { + list2 = ltdb_index_idxptr(module, rec, false); + if (list2 == NULL) { + free(rec.dptr); + return LDB_ERR_OPERATIONS_ERROR; + } + free(rec.dptr); + list2->dn = talloc_steal(list2, list->dn); + list2->count = list->count; + return LDB_SUCCESS; + } + + list2 = talloc(ltdb->idxptr, struct dn_list); + if (list2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + list2->dn = talloc_steal(list2, list->dn); + list2->count = list->count; + + rec.dptr = (uint8_t *)&list2; + rec.dsize = sizeof(void *); + + ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT); + if (ret != 0) { + return ltdb_err_map(tdb_error(ltdb->idxptr->itdb)); + } + return LDB_SUCCESS; +} + +/* + traverse function for storing the in-memory index entries on disk + */ +static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct ldb_module *module = state; + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + struct ldb_dn *dn; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_val v; + struct dn_list *list; + + list = ltdb_index_idxptr(module, data, true); + if (list == NULL) { + ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + v.data = key.dptr; + v.length = strnlen((char *)key.dptr, key.dsize); + + dn = ldb_dn_from_ldb_val(module, ldb, &v); + if (dn == NULL) { + ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); + ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + ltdb->idxptr->error = ltdb_dn_list_store_full(module, dn, list); + talloc_free(dn); + if (ltdb->idxptr->error != 0) { + return -1; + } + return 0; +} + +/* cleanup the idxptr mode when transaction commits */ +int ltdb_index_transaction_commit(struct ldb_module *module) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + int ret; + + struct ldb_context *ldb = ldb_module_get_ctx(module); + + ldb_reset_err_string(ldb); + + if (ltdb->idxptr->itdb) { + tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module); + tdb_close(ltdb->idxptr->itdb); + } + + ret = ltdb->idxptr->error; + if (ret != LDB_SUCCESS) { + if (!ldb_errstring(ldb)) { + ldb_set_errstring(ldb, ldb_strerror(ret)); + } + ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); + } + + talloc_free(ltdb->idxptr); + ltdb->idxptr = NULL; + return ret; +} + +/* cleanup the idxptr mode when transaction cancels */ +int ltdb_index_transaction_cancel(struct ldb_module *module) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + if (ltdb->idxptr && ltdb->idxptr->itdb) { + tdb_close(ltdb->idxptr->itdb); + } + talloc_free(ltdb->idxptr); + ltdb->idxptr = NULL; + return LDB_SUCCESS; +} + + +/* + return the dn key to be used for an index + the caller is responsible for freeing +*/ +static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb, + const char *attr, const struct ldb_val *value, + const struct ldb_schema_attribute **ap) +{ + struct ldb_dn *ret; + struct ldb_val v; + const struct ldb_schema_attribute *a; + char *attr_folded; + int r; + + attr_folded = ldb_attr_casefold(ldb, attr); + if (!attr_folded) { + return NULL; + } + + a = ldb_schema_attribute_by_name(ldb, attr); + if (ap) { + *ap = a; + } + r = a->syntax->canonicalise_fn(ldb, ldb, value, &v); + if (r != LDB_SUCCESS) { + const char *errstr = ldb_errstring(ldb); + /* canonicalisation can be refused. For example, + a attribute that takes wildcards will refuse to canonicalise + if the value contains a wildcard */ + ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s", + attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:"")); + talloc_free(attr_folded); + return NULL; + } + if (ldb_should_b64_encode(ldb, &v)) { + char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); + if (!vstr) { + talloc_free(attr_folded); + return NULL; + } + ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); + talloc_free(vstr); + } else { + ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); + } + + if (v.data != value->data) { + talloc_free(v.data); + } + talloc_free(attr_folded); + + return ret; +} + +/* + see if a attribute value is in the list of indexed attributes +*/ +static bool ltdb_is_indexed(const struct ldb_message *index_list, const char *attr) +{ + unsigned int i; + struct ldb_message_element *el; + + el = ldb_msg_find_element(index_list, LTDB_IDXATTR); + if (el == NULL) { + return false; + } + + /* TODO: this is too expensive! At least use a binary search */ + for (i=0; inum_values; i++) { + if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { + return true; + } + } + return false; +} + +/* + in the following logic functions, the return value is treated as + follows: + + LDB_SUCCESS: we found some matching index values + + LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches + + LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, + we'll need a full search + */ + +/* + return a list of dn's that might match a simple indexed search (an + equality search only) + */ +static int ltdb_index_dn_simple(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb; + struct ldb_dn *dn; + int ret; + + ldb = ldb_module_get_ctx(module); + + list->count = 0; + list->dn = NULL; + + /* if the attribute isn't in the list of indexed attributes then + this node needs a full search */ + if (!ltdb_is_indexed(index_list, tree->u.equality.attr)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* the attribute is indexed. Pull the list of DNs that match the + search criterion */ + dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL); + if (!dn) return LDB_ERR_OPERATIONS_ERROR; + + ret = ltdb_dn_list_load(module, dn, list); + talloc_free(dn); + return ret; +} + + +static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); + +/* + return a list of dn's that might match a leaf indexed search + */ +static int ltdb_index_dn_leaf(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + if (ldb_attr_dn(tree->u.equality.attr) == 0) { + list->dn = talloc_array(list, struct ldb_val, 1); + if (list->dn == NULL) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + list->dn[0] = tree->u.equality.value; + list->count = 1; + return LDB_SUCCESS; + } + return ltdb_index_dn_simple(module, tree, index_list, list); +} + + +/* + list intersection + list = list & list2 +*/ +static bool list_intersect(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) +{ + struct dn_list *list3; + unsigned int i; + + if (list->count == 0) { + /* 0 & X == 0 */ + return true; + } + if (list2->count == 0) { + /* X & 0 == 0 */ + list->count = 0; + list->dn = NULL; + return true; + } + + /* the indexing code is allowed to return a longer list than + what really matches, as all results are filtered by the + full expression at the end - this shortcut avoids a lot of + work in some cases */ + if (list->count < 2 && list2->count > 10) { + return true; + } + if (list2->count < 2 && list->count > 10) { + list->count = list2->count; + list->dn = list2->dn; + /* note that list2 may not be the parent of list2->dn, + as list2->dn may be owned by ltdb->idxptr. In that + case we expect this reparent call to fail, which is + OK */ + talloc_reparent(list2, list, list2->dn); + return true; + } + + list3 = talloc_zero(list, struct dn_list); + if (list3 == NULL) { + return false; + } + + list3->dn = talloc_array(list3, struct ldb_val, list->count); + if (!list3->dn) { + talloc_free(list3); + return false; + } + list3->count = 0; + + for (i=0;icount;i++) { + if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) { + list3->dn[list3->count] = list->dn[i]; + list3->count++; + } + } + + list->dn = talloc_steal(list, list3->dn); + list->count = list3->count; + talloc_free(list3); + + return true; +} + + +/* + list union + list = list | list2 +*/ +static bool list_union(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) +{ + struct ldb_val *dn3; + + if (list2->count == 0) { + /* X | 0 == X */ + return true; + } + + if (list->count == 0) { + /* 0 | X == X */ + list->count = list2->count; + list->dn = list2->dn; + /* note that list2 may not be the parent of list2->dn, + as list2->dn may be owned by ltdb->idxptr. In that + case we expect this reparent call to fail, which is + OK */ + talloc_reparent(list2, list, list2->dn); + return true; + } + + dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); + if (!dn3) { + ldb_oom(ldb); + return false; + } + + /* we allow for duplicates here, and get rid of them later */ + memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count); + memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count); + + list->dn = dn3; + list->count += list2->count; + + return true; +} + +static int ltdb_index_dn(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list); + + +/* + process an OR list (a union) + */ +static int ltdb_index_dn_or(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + list->dn = NULL; + list->count = 0; + + for (i=0; iu.list.num_elements; i++) { + struct dn_list *list2; + int ret; + + list2 = talloc_zero(list, struct dn_list); + if (list2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* X || 0 == X */ + talloc_free(list2); + continue; + } + + if (ret != LDB_SUCCESS) { + /* X || * == * */ + talloc_free(list2); + return ret; + } + + if (!list_union(ldb, list, list2)) { + talloc_free(list2); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + if (list->count == 0) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + return LDB_SUCCESS; +} + + +/* + NOT an index results + */ +static int ltdb_index_dn_not(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + /* the only way to do an indexed not would be if we could + negate the not via another not or if we knew the total + number of database elements so we could know that the + existing expression covered the whole database. + + instead, we just give up, and rely on a full index scan + (unless an outer & manages to reduce the list) + */ + return LDB_ERR_OPERATIONS_ERROR; +} + + +static bool ltdb_index_unique(struct ldb_context *ldb, + const char *attr) +{ + const struct ldb_schema_attribute *a; + a = ldb_schema_attribute_by_name(ldb, attr); + if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { + return true; + } + return false; +} + +/* + process an AND expression (intersection) + */ +static int ltdb_index_dn_and(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb; + unsigned int i; + bool found; + + ldb = ldb_module_get_ctx(module); + + list->dn = NULL; + list->count = 0; + + /* in the first pass we only look for unique simple + equality tests, in the hope of avoiding having to look + at any others */ + for (i=0; iu.list.num_elements; i++) { + const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; + int ret; + + if (subtree->operation != LDB_OP_EQUALITY || + !ltdb_index_unique(ldb, subtree->u.equality.attr)) { + continue; + } + + ret = ltdb_index_dn(module, subtree, index_list, list); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* 0 && X == 0 */ + return LDB_ERR_NO_SUCH_OBJECT; + } + if (ret == LDB_SUCCESS) { + /* a unique index match means we can + * stop. Note that we don't care if we return + * a few too many objects, due to later + * filtering */ + return LDB_SUCCESS; + } + } + + /* now do a full intersection */ + found = false; + + for (i=0; iu.list.num_elements; i++) { + const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; + struct dn_list *list2; + int ret; + + list2 = talloc_zero(list, struct dn_list); + if (list2 == NULL) { + return ldb_module_oom(module); + } + + ret = ltdb_index_dn(module, subtree, index_list, list2); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* X && 0 == 0 */ + list->dn = NULL; + list->count = 0; + talloc_free(list2); + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (ret != LDB_SUCCESS) { + /* this didn't adding anything */ + talloc_free(list2); + continue; + } + + if (!found) { + talloc_reparent(list2, list, list->dn); + list->dn = list2->dn; + list->count = list2->count; + found = true; + } else if (!list_intersect(ldb, list, list2)) { + talloc_free(list2); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (list->count == 0) { + list->dn = NULL; + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (list->count < 2) { + /* it isn't worth loading the next part of the tree */ + return LDB_SUCCESS; + } + } + + if (!found) { + /* none of the attributes were indexed */ + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* + return a list of matching objects using a one-level index + */ +static int ltdb_index_dn_one(struct ldb_module *module, + struct ldb_dn *parent_dn, + struct dn_list *list) +{ + struct ldb_context *ldb; + struct ldb_dn *key; + struct ldb_val val; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* work out the index key from the parent DN */ + val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn)); + val.length = strlen((char *)val.data); + key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL); + if (!key) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_dn_list_load(module, key, list); + talloc_free(key); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (list->count == 0) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + return LDB_SUCCESS; +} + +/* + return a list of dn's that might match a indexed search or + an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches + */ +static int ltdb_index_dn(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + int ret = LDB_ERR_OPERATIONS_ERROR; + + switch (tree->operation) { + case LDB_OP_AND: + ret = ltdb_index_dn_and(module, tree, index_list, list); + break; + + case LDB_OP_OR: + ret = ltdb_index_dn_or(module, tree, index_list, list); + break; + + case LDB_OP_NOT: + ret = ltdb_index_dn_not(module, tree, index_list, list); + break; + + case LDB_OP_EQUALITY: + ret = ltdb_index_dn_leaf(module, tree, index_list, list); + break; + + case LDB_OP_SUBSTRING: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_PRESENT: + case LDB_OP_APPROX: + case LDB_OP_EXTENDED: + /* we can't index with fancy bitops yet */ + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + + return ret; +} + +/* + filter a candidate dn_list from an indexed search into a set of results + extracting just the given attributes +*/ +static int ltdb_index_filter(const struct dn_list *dn_list, + struct ltdb_context *ac, + uint32_t *match_count) +{ + struct ldb_context *ldb; + struct ldb_message *msg; + unsigned int i; + + ldb = ldb_module_get_ctx(ac->module); + + for (i = 0; i < dn_list->count; i++) { + struct ldb_dn *dn; + int ret; + bool matched; + + msg = ldb_msg_new(ac); + if (!msg) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]); + if (dn == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_search_dn1(ac->module, dn, msg); + talloc_free(dn); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* the record has disappeared? yes, this can happen */ + talloc_free(msg); + continue; + } + + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { + /* an internal error */ + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_match_msg_error(ldb, msg, + ac->tree, ac->base, ac->scope, &matched); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + if (!matched) { + talloc_free(msg); + continue; + } + + /* filter the attributes that the user wants */ + ret = ltdb_filter_attrs(msg, ac->attrs); + + if (ret == -1) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_send_entry(ac->req, msg, NULL); + if (ret != LDB_SUCCESS) { + /* Regardless of success or failure, the msg + * is the callbacks responsiblity, and should + * not be talloc_free()'ed */ + ac->request_terminated = true; + return ret; + } + + (*match_count)++; + } + + return LDB_SUCCESS; +} + +/* + remove any duplicated entries in a indexed result + */ +static void ltdb_dn_list_remove_duplicates(struct dn_list *list) +{ + unsigned int i, new_count; + + if (list->count < 2) { + return; + } + + TYPESAFE_QSORT(list->dn, list->count, dn_list_cmp); + + new_count = 1; + for (i=1; icount; i++) { + if (dn_list_cmp(&list->dn[i], &list->dn[new_count-1]) != 0) { + if (new_count != i) { + list->dn[new_count] = list->dn[i]; + } + new_count++; + } + } + + list->count = new_count; +} + +/* + search the database with a LDAP-like expression using indexes + returns -1 if an indexed search is not possible, in which + case the caller should call ltdb_search_full() +*/ +int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private); + struct dn_list *dn_list; + int ret; + + /* see if indexing is enabled */ + if (!ltdb->cache->attribute_indexes && + !ltdb->cache->one_level_indexes && + ac->scope != LDB_SCOPE_BASE) { + /* fallback to a full search */ + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_list = talloc_zero(ac, struct dn_list); + if (dn_list == NULL) { + return ldb_module_oom(ac->module); + } + + switch (ac->scope) { + case LDB_SCOPE_BASE: + dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); + if (dn_list->dn == NULL) { + talloc_free(dn_list); + return ldb_module_oom(ac->module); + } + dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base)); + if (dn_list->dn[0].data == NULL) { + talloc_free(dn_list); + return ldb_module_oom(ac->module); + } + dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); + dn_list->count = 1; + break; + + case LDB_SCOPE_ONELEVEL: + if (!ltdb->cache->one_level_indexes) { + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ltdb_index_dn_one(ac->module, ac->base, dn_list); + if (ret != LDB_SUCCESS) { + talloc_free(dn_list); + return ret; + } + break; + + case LDB_SCOPE_SUBTREE: + case LDB_SCOPE_DEFAULT: + if (!ltdb->cache->attribute_indexes) { + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); + if (ret != LDB_SUCCESS) { + talloc_free(dn_list); + return ret; + } + ltdb_dn_list_remove_duplicates(dn_list); + break; + } + + ret = ltdb_index_filter(dn_list, ac, match_count); + talloc_free(dn_list); + return ret; +} + +/* + add an index entry for one message element +*/ +static int ltdb_index_add1(struct ldb_module *module, const char *dn, + struct ldb_message_element *el, int v_idx) +{ + struct ldb_context *ldb; + struct ldb_dn *dn_key; + int ret; + const struct ldb_schema_attribute *a; + struct dn_list *list; + unsigned alloc_len; + + ldb = ldb_module_get_ctx(module); + + list = talloc_zero(module, struct dn_list); + if (list == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a); + if (!dn_key) { + talloc_free(list); + return LDB_ERR_OPERATIONS_ERROR; + } + talloc_steal(list, dn_key); + + ret = ltdb_dn_list_load(module, dn_key, list); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { + talloc_free(list); + return ret; + } + + if (ltdb_dn_list_find_str(list, dn) != -1) { + talloc_free(list); + return LDB_SUCCESS; + } + + if (list->count > 0 && + a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { + talloc_free(list); + ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s", + el->name, dn); + return LDB_ERR_ENTRY_ALREADY_EXISTS; + } + + /* overallocate the list a bit, to reduce the number of + * realloc trigered copies */ + alloc_len = ((list->count+1)+7) & ~7; + list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); + if (list->dn == NULL) { + talloc_free(list); + return LDB_ERR_OPERATIONS_ERROR; + } + list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn); + list->dn[list->count].length = strlen(dn); + list->count++; + + ret = ltdb_dn_list_store(module, dn_key, list); + + talloc_free(list); + + return ret; +} + +/* + add index entries for one elements in a message + */ +static int ltdb_index_add_el(struct ldb_module *module, const char *dn, + struct ldb_message_element *el) +{ + unsigned int i; + for (i = 0; i < el->num_values; i++) { + int ret = ltdb_index_add1(module, dn, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* + add index entries for all elements in a message + */ +static int ltdb_index_add_all(struct ldb_module *module, const char *dn, + struct ldb_message_element *elements, int num_el) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + unsigned int i; + + if (dn[0] == '@') { + return LDB_SUCCESS; + } + + if (ltdb->cache->indexlist->num_elements == 0) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + for (i = 0; i < num_el; i++) { + int ret; + if (!ltdb_is_indexed(ltdb->cache->indexlist, elements[i].name)) { + continue; + } + ret = ltdb_index_add_el(module, dn, &elements[i]); + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, + __location__ ": Failed to re-index %s in %s - %s", + elements[i].name, dn, ldb_errstring(ldb)); + return ret; + } + } + + return LDB_SUCCESS; +} + + +/* + insert a one level index for a message +*/ +static int ltdb_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + struct ldb_message_element el; + struct ldb_val val; + struct ldb_dn *pdn; + const char *dn; + int ret; + + /* We index for ONE Level only if requested */ + if (!ltdb->cache->one_level_indexes) { + return LDB_SUCCESS; + } + + pdn = ldb_dn_get_parent(module, msg->dn); + if (pdn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_get_linearized(msg->dn); + if (dn == NULL) { + talloc_free(pdn); + return LDB_ERR_OPERATIONS_ERROR; + } + + val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn)); + if (val.data == NULL) { + talloc_free(pdn); + return LDB_ERR_OPERATIONS_ERROR; + } + + val.length = strlen((char *)val.data); + el.name = LTDB_IDXONE; + el.values = &val; + el.num_values = 1; + + if (add) { + ret = ltdb_index_add1(module, dn, &el, 0); + } else { /* delete */ + ret = ltdb_index_del_value(module, msg->dn, &el, 0); + } + + talloc_free(pdn); + + return ret; +} + +/* + add the index entries for a new element in a record + The caller guarantees that these element values are not yet indexed +*/ +int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + if (ldb_dn_is_special(dn)) { + return LDB_SUCCESS; + } + if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { + return LDB_SUCCESS; + } + return ltdb_index_add_el(module, ldb_dn_get_linearized(dn), el); +} + +/* + add the index entries for a new record +*/ +int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg) +{ + const char *dn; + int ret; + + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + + dn = ldb_dn_get_linearized(msg->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ltdb_index_onelevel(module, msg, 1); +} + + +/* + delete an index entry for one message element +*/ +int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el, unsigned int v_idx) +{ + struct ldb_context *ldb; + struct ldb_dn *dn_key; + const char *dn_str; + int ret, i; + unsigned int j; + struct dn_list *list; + + ldb = ldb_module_get_ctx(module); + + dn_str = ldb_dn_get_linearized(dn); + if (dn_str == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (dn_str[0] == '@') { + return LDB_SUCCESS; + } + + dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL); + if (!dn_key) { + return LDB_ERR_OPERATIONS_ERROR; + } + + list = talloc_zero(dn_key, struct dn_list); + if (list == NULL) { + talloc_free(dn_key); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_dn_list_load(module, dn_key, list); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* it wasn't indexed. Did we have an earlier error? If we did then + its gone now */ + talloc_free(dn_key); + return LDB_SUCCESS; + } + + if (ret != LDB_SUCCESS) { + talloc_free(dn_key); + return ret; + } + + i = ltdb_dn_list_find_str(list, dn_str); + if (i == -1) { + /* nothing to delete */ + talloc_free(dn_key); + return LDB_SUCCESS; + } + + j = (unsigned int) i; + if (j != list->count - 1) { + memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); + } + list->count--; + list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); + + ret = ltdb_dn_list_store(module, dn_key, list); + + talloc_free(dn_key); + + return ret; +} + +/* + delete the index entries for a element + return -1 on failure +*/ +int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + const char *dn_str; + int ret; + unsigned int i; + + if (!ltdb->cache->attribute_indexes) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + dn_str = ldb_dn_get_linearized(dn); + if (dn_str == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (dn_str[0] == '@') { + return LDB_SUCCESS; + } + + if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { + return LDB_SUCCESS; + } + for (i = 0; i < el->num_values; i++) { + ret = ltdb_index_del_value(module, dn, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* + delete the index entries for a record + return -1 on failure +*/ +int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + int ret; + unsigned int i; + + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + + ret = ltdb_index_onelevel(module, msg, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (!ltdb->cache->attribute_indexes) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + for (i = 0; i < msg->num_elements; i++) { + ret = ltdb_index_del_element(module, msg->dn, &msg->elements[i]); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + + +/* + traversal function that deletes all @INDEX records +*/ +static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct ldb_module *module = state; + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + const char *dnstr = "DN=" LTDB_INDEX ":"; + struct dn_list list; + struct ldb_dn *dn; + struct ldb_val v; + int ret; + + if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) { + return 0; + } + /* we need to put a empty list in the internal tdb for this + * index entry */ + list.dn = NULL; + list.count = 0; + + /* the offset of 3 is to remove the DN= prefix. */ + v.data = key.dptr + 3; + v.length = strnlen((char *)key.dptr, key.dsize) - 3; + + dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v); + ret = ltdb_dn_list_store(module, dn, &list); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Unable to store null index for %s\n", + ldb_dn_get_linearized(dn)); + talloc_free(dn); + return -1; + } + talloc_free(dn); + return 0; +} + +struct ltdb_reindex_context { + struct ldb_module *module; + int error; +}; + +/* + traversal function that adds @INDEX records during a re index +*/ +static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct ldb_context *ldb; + struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state; + struct ldb_module *module = ctx->module; + struct ldb_message *msg; + const char *dn = NULL; + int ret; + TDB_DATA key2; + + ldb = ldb_module_get_ctx(module); + + if (strncmp((char *)key.dptr, "DN=@", 4) == 0 || + strncmp((char *)key.dptr, "DN=", 3) != 0) { + return 0; + } + + msg = ldb_msg_new(module); + if (msg == NULL) { + return -1; + } + + ret = ltdb_unpack_data(module, &data, msg); + if (ret != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); + talloc_free(msg); + return -1; + } + + /* check if the DN key has changed, perhaps due to the + case insensitivity of an element changing */ + key2 = ltdb_key(module, msg->dn); + if (key2.dptr == NULL) { + /* probably a corrupt record ... darn */ + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", + ldb_dn_get_linearized(msg->dn)); + talloc_free(msg); + return 0; + } + if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) { + tdb_delete(tdb, key); + tdb_store(tdb, key2, data, 0); + } + talloc_free(key2.dptr); + + if (msg->dn == NULL) { + dn = (char *)key.dptr + 3; + } else { + dn = ldb_dn_get_linearized(msg->dn); + } + + ret = ltdb_index_onelevel(module, msg, 1); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Adding special ONE LEVEL index failed (%s)!", + ldb_dn_get_linearized(msg->dn)); + talloc_free(msg); + return -1; + } + + ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); + + if (ret != LDB_SUCCESS) { + ctx->error = ret; + talloc_free(msg); + return -1; + } + + talloc_free(msg); + + return 0; +} + +/* + force a complete reindex of the database +*/ +int ltdb_reindex(struct ldb_module *module) +{ + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + int ret; + struct ltdb_reindex_context ctx; + + if (ltdb_cache_reload(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* first traverse the database deleting any @INDEX records by + * putting NULL entries in the in-memory tdb + */ + ret = tdb_traverse(ltdb->tdb, delete_index, module); + if (ret < 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* if we don't have indexes we have nothing todo */ + if (ltdb->cache->indexlist->num_elements == 0) { + return LDB_SUCCESS; + } + + ctx.module = module; + ctx.error = 0; + + /* now traverse adding any indexes for normal LDB records */ + ret = tdb_traverse(ltdb->tdb, re_index, &ctx); + if (ret < 0) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ctx.error != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); + return ctx.error; + } + + return LDB_SUCCESS; +} diff --git a/lib/ldb/ldb_tdb/ldb_pack.c b/lib/ldb/ldb_tdb/ldb_pack.c new file mode 100644 index 00000000000..7c13065aeef --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_pack.c @@ -0,0 +1,292 @@ +/* + 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 --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c new file mode 100644 index 00000000000..46e2d749984 --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -0,0 +1,618 @@ +/* + 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 search functions + * + * Description: functions to search ldb+tdb databases + * + * Author: Andrew Tridgell + */ + +#include "ldb_tdb.h" +#include + +/* + add one element to a message +*/ +static int msg_add_element(struct ldb_message *ret, + const struct ldb_message_element *el, + int check_duplicates) +{ + unsigned int i; + struct ldb_message_element *e2, *elnew; + + if (check_duplicates && ldb_msg_find_element(ret, el->name)) { + /* its already there */ + return 0; + } + + e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); + if (!e2) { + return -1; + } + ret->elements = e2; + + elnew = &e2[ret->num_elements]; + + elnew->name = talloc_strdup(ret->elements, el->name); + if (!elnew->name) { + return -1; + } + + if (el->num_values) { + elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values); + if (!elnew->values) { + return -1; + } + } else { + elnew->values = NULL; + } + + for (i=0;inum_values;i++) { + elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); + if (elnew->values[i].length != el->values[i].length) { + return -1; + } + } + + elnew->num_values = el->num_values; + elnew->flags = el->flags; + + ret->num_elements++; + + return 0; +} + +/* + add the special distinguishedName element +*/ +static int msg_add_distinguished_name(struct ldb_message *msg) +{ + struct ldb_message_element el; + struct ldb_val val; + int ret; + + el.flags = 0; + el.name = "distinguishedName"; + el.num_values = 1; + el.values = &val; + el.flags = 0; + val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn); + val.length = strlen((char *)val.data); + + ret = msg_add_element(msg, &el, 1); + return ret; +} + +/* + add all elements from one message into another + */ +static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *ret, + const struct ldb_message *msg) +{ + struct ldb_context *ldb; + unsigned int i; + int check_duplicates = (ret->num_elements != 0); + + ldb = ldb_module_get_ctx(module); + + if (msg_add_distinguished_name(ret) != 0) { + return -1; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + if (a->flags & LDB_ATTR_FLAG_HIDDEN) { + continue; + } + if (msg_add_element(ret, &msg->elements[i], + check_duplicates) != 0) { + return -1; + } + } + + return 0; +} + + +/* + pull the specified list of attributes from a message + */ +static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char * const *attrs) +{ + struct ldb_message *ret; + unsigned int i; + + ret = talloc(mem_ctx, struct ldb_message); + if (!ret) { + return NULL; + } + + ret->dn = ldb_dn_copy(ret, msg->dn); + if (!ret->dn) { + talloc_free(ret); + return NULL; + } + + ret->num_elements = 0; + ret->elements = NULL; + + if (!attrs) { + if (msg_add_all_elements(module, ret, msg) != 0) { + talloc_free(ret); + return NULL; + } + return ret; + } + + for (i=0;attrs[i];i++) { + struct ldb_message_element *el; + + if (strcmp(attrs[i], "*") == 0) { + if (msg_add_all_elements(module, ret, msg) != 0) { + talloc_free(ret); + return NULL; + } + continue; + } + + if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { + if (msg_add_distinguished_name(ret) != 0) { + return NULL; + } + continue; + } + + el = ldb_msg_find_element(msg, attrs[i]); + if (!el) { + continue; + } + if (msg_add_element(ret, el, 1) != 0) { + talloc_free(ret); + return NULL; + } + } + + return ret; +} + +/* + search the database for a single simple dn. + return LDB_ERR_NO_SUCH_OBJECT on record-not-found + and LDB_SUCCESS on success +*/ +static int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + TDB_DATA tdb_key, tdb_data; + + if (ldb_dn_is_null(dn)) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + /* form the key */ + tdb_key = ltdb_key(module, dn); + if (!tdb_key.dptr) { + return LDB_ERR_OPERATIONS_ERROR; + } + + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); + talloc_free(tdb_key.dptr); + if (!tdb_data.dptr) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + free(tdb_data.dptr); + return LDB_SUCCESS; +} + +/* + search the database for a single simple dn, returning all attributes + in a single message + + return LDB_ERR_NO_SUCH_OBJECT on record-not-found + and LDB_SUCCESS on success +*/ +int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + int ret; + TDB_DATA tdb_key, tdb_data; + + memset(msg, 0, sizeof(*msg)); + + /* form the key */ + tdb_key = ltdb_key(module, dn); + if (!tdb_key.dptr) { + return LDB_ERR_OPERATIONS_ERROR; + } + + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); + talloc_free(tdb_key.dptr); + if (!tdb_data.dptr) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + msg->num_elements = 0; + msg->elements = NULL; + + ret = ltdb_unpack_data(module, &tdb_data, msg); + free(tdb_data.dptr); + if (ret == -1) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (!msg->dn) { + msg->dn = ldb_dn_copy(msg, dn); + } + if (!msg->dn) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* + add a set of attributes from a record to a set of results + return 0 on success, -1 on failure +*/ +int ltdb_add_attr_results(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + const char * const attrs[], + unsigned int *count, + struct ldb_message ***res) +{ + struct ldb_message *msg2; + struct ldb_message **res2; + + /* pull the attributes that the user wants */ + msg2 = ltdb_pull_attrs(module, mem_ctx, msg, attrs); + if (!msg2) { + return -1; + } + + /* add to the results list */ + res2 = talloc_realloc(mem_ctx, *res, struct ldb_message *, (*count)+2); + if (!res2) { + talloc_free(msg2); + return -1; + } + + (*res) = res2; + + (*res)[*count] = talloc_move(*res, &msg2); + (*res)[(*count)+1] = NULL; + (*count)++; + + return 0; +} + + + +/* + filter the specified list of attributes from a message + removing not requested attrs. + */ +int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs) +{ + unsigned int i; + int keep_all = 0; + struct ldb_message_element *el2; + uint32_t num_elements; + + if (attrs) { + /* check for special attrs */ + for (i = 0; attrs[i]; i++) { + if (strcmp(attrs[i], "*") == 0) { + keep_all = 1; + break; + } + + if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { + if (msg_add_distinguished_name(msg) != 0) { + return -1; + } + } + } + } else { + keep_all = 1; + } + + if (keep_all) { + if (msg_add_distinguished_name(msg) != 0) { + return -1; + } + return 0; + } + + el2 = talloc_array(msg, struct ldb_message_element, msg->num_elements); + if (el2 == NULL) { + return -1; + } + num_elements = 0; + + for (i = 0; i < msg->num_elements; i++) { + unsigned int j; + int found = 0; + + for (j = 0; attrs[j]; j++) { + if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) { + found = 1; + break; + } + } + + if (found) { + el2[num_elements] = msg->elements[i]; + talloc_steal(el2, el2[num_elements].name); + talloc_steal(el2, el2[num_elements].values); + num_elements++; + } + } + + talloc_free(msg->elements); + msg->elements = talloc_realloc(msg, el2, struct ldb_message_element, msg->num_elements); + if (msg->elements == NULL) { + return -1; + } + msg->num_elements = num_elements; + + return 0; +} + +/* + search function for a non-indexed search + */ +static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct ldb_context *ldb; + struct ltdb_context *ac; + struct ldb_message *msg; + int ret; + bool matched; + + ac = talloc_get_type(state, struct ltdb_context); + ldb = ldb_module_get_ctx(ac->module); + + if (key.dsize < 4 || + strncmp((char *)key.dptr, "DN=", 3) != 0) { + return 0; + } + + msg = ldb_msg_new(ac); + if (!msg) { + return -1; + } + + /* unpack the record */ + ret = ltdb_unpack_data(ac->module, &data, msg); + if (ret == -1) { + talloc_free(msg); + return -1; + } + + if (!msg->dn) { + msg->dn = ldb_dn_new(msg, ldb, + (char *)key.dptr + 3); + if (msg->dn == NULL) { + talloc_free(msg); + return -1; + } + } + + /* see if it matches the given expression */ + ret = ldb_match_msg_error(ldb, msg, + ac->tree, ac->base, ac->scope, &matched); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return -1; + } + if (!matched) { + talloc_free(msg); + return 0; + } + + /* filter the attributes that the user wants */ + ret = ltdb_filter_attrs(msg, ac->attrs); + + if (ret == -1) { + talloc_free(msg); + return -1; + } + + ret = ldb_module_send_entry(ac->req, msg, NULL); + if (ret != LDB_SUCCESS) { + ac->request_terminated = true; + /* the callback failed, abort the operation */ + return -1; + } + + return 0; +} + + +/* + search the database with a LDAP-like expression. + this is the "full search" non-indexed variant +*/ +static int ltdb_search_full(struct ltdb_context *ctx) +{ + void *data = ldb_module_get_private(ctx->module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + int ret; + + if (ltdb->in_transaction != 0) { + ret = tdb_traverse(ltdb->tdb, search_func, ctx); + } else { + ret = tdb_traverse_read(ltdb->tdb, search_func, ctx); + } + + if (ret < 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* + search the database with a LDAP-like expression. + choses a search method +*/ +int ltdb_search(struct ltdb_context *ctx) +{ + struct ldb_context *ldb; + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_lock_read(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ltdb_cache_load(module) != 0) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { + + /* Check what we should do with a NULL dn */ + switch (req->op.search.scope) { + case LDB_SCOPE_BASE: + ldb_asprintf_errstring(ldb, + "NULL Base DN invalid for a base search"); + ret = LDB_ERR_INVALID_DN_SYNTAX; + break; + case LDB_SCOPE_ONELEVEL: + ldb_asprintf_errstring(ldb, + "NULL Base DN invalid for a one-level search"); + ret = LDB_ERR_INVALID_DN_SYNTAX; + break; + case LDB_SCOPE_SUBTREE: + default: + /* We accept subtree searches from a NULL base DN, ie over the whole DB */ + ret = LDB_SUCCESS; + } + } else if (ldb_dn_is_valid(req->op.search.base) == false) { + + /* We don't want invalid base DNs here */ + ldb_asprintf_errstring(ldb, + "Invalid Base DN: %s", + ldb_dn_get_linearized(req->op.search.base)); + ret = LDB_ERR_INVALID_DN_SYNTAX; + + } else if (ltdb->check_base) { + /* This database has been marked as 'checkBaseOnSearch', so do a spot check of the base dn */ + ret = ltdb_search_base(module, req->op.search.base); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_asprintf_errstring(ldb, + "No such Base DN: %s", + ldb_dn_get_linearized(req->op.search.base)); + } + + } else { + /* If we are not checking the base DN life is easy */ + ret = LDB_SUCCESS; + } + + ctx->tree = req->op.search.tree; + ctx->scope = req->op.search.scope; + ctx->base = req->op.search.base; + ctx->attrs = req->op.search.attrs; + + if (ret == LDB_SUCCESS) { + uint32_t match_count = 0; + + ret = ltdb_search_indexed(ctx, &match_count); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* Not in the index, therefore OK! */ + ret = LDB_SUCCESS; + + } + /* Check if we got just a normal error. + * In that case proceed to a full search unless we got a + * callback error */ + if ( ! ctx->request_terminated && ret != LDB_SUCCESS) { + /* Not indexed, so we need to do a full scan */ + if (ltdb->warn_unindexed) { + /* useful for debugging when slow performance + * is caused by unindexed searches */ + char *expression = ldb_filter_from_tree(ctx, ctx->tree); + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb FULL SEARCH: %s SCOPE: %s DN: %s\n", + expression, + req->op.search.scope==LDB_SCOPE_BASE?"base": + req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": + req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", + ldb_dn_get_linearized(req->op.search.base)); + + talloc_free(expression); + } + if (match_count != 0) { + /* the indexing code gave an error + * after having returned at least one + * entry. This means the indexes are + * corrupt or a database record is + * corrupt. We cannot continue with a + * full search or we may return + * duplicate entries + */ + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ltdb_search_full(ctx); + if (ret != LDB_SUCCESS) { + ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); + } + } + } + + ltdb_unlock_read(module); + + return ret; +} + diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c new file mode 100644 index 00000000000..0d4be491235 --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -0,0 +1,1519 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + + ** 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_tdb + * + * Component: ldb tdb backend + * + * Description: core functions for tdb backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * Author: Simo Sorce + * + * - description: make it possible to use event contexts + * date: Jan 2008 + * Author: Simo Sorce + * + * - description: fix up memory leaks and small bugs + * date: Oct 2009 + * Author: Matthias Dieter Wallnöfer + */ + +#include "ldb_tdb.h" +#include + + +/* + map a tdb error code to a ldb error code +*/ +int ltdb_err_map(enum TDB_ERROR tdb_code) +{ + switch (tdb_code) { + case TDB_SUCCESS: + return LDB_SUCCESS; + case TDB_ERR_CORRUPT: + case TDB_ERR_OOM: + case TDB_ERR_EINVAL: + return LDB_ERR_OPERATIONS_ERROR; + case TDB_ERR_IO: + return LDB_ERR_PROTOCOL_ERROR; + case TDB_ERR_LOCK: +#ifndef BUILD_TDB2 + case TDB_ERR_NOLOCK: +#endif + return LDB_ERR_BUSY; +#ifndef BUILD_TDB2 + case TDB_ERR_LOCK_TIMEOUT: +#endif + return LDB_ERR_TIME_LIMIT_EXCEEDED; + case TDB_ERR_EXISTS: + return LDB_ERR_ENTRY_ALREADY_EXISTS; + case TDB_ERR_NOEXIST: + return LDB_ERR_NO_SUCH_OBJECT; + case TDB_ERR_RDONLY: + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + default: + break; + } + return LDB_ERR_OTHER; +} + +/* + lock the database for read - use by ltdb_search and ltdb_sequence_number +*/ +int ltdb_lock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + int ret = 0; + + if (ltdb->in_transaction == 0 && + ltdb->read_lock_count == 0) { + ret = tdb_lockall_read(ltdb->tdb); + } + if (ret == 0) { + ltdb->read_lock_count++; + } + return ret; +} + +/* + unlock the database after a ltdb_lock_read() +*/ +int ltdb_unlock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) { + tdb_unlockall_read(ltdb->tdb); + return 0; + } + ltdb->read_lock_count--; + return 0; +} + + +/* + form a TDB_DATA for a record key + caller frees + + note that the key for a record can depend on whether the + dn refers to a case sensitive index record or not +*/ +TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + TDB_DATA key; + char *key_str = NULL; + const char *dn_folded = NULL; + + /* + most DNs are case insensitive. The exception is index DNs for + case sensitive attributes + + there are 3 cases dealt with in this code: + + 1) if the dn doesn't start with @ then uppercase the attribute + names and the attributes values of case insensitive attributes + 2) if the dn starts with @ then leave it alone - + the indexing code handles the rest + */ + + dn_folded = ldb_dn_get_casefold(dn); + if (!dn_folded) { + goto failed; + } + + key_str = talloc_strdup(ldb, "DN="); + if (!key_str) { + goto failed; + } + + key_str = talloc_strdup_append_buffer(key_str, dn_folded); + if (!key_str) { + goto failed; + } + + key.dptr = (uint8_t *)key_str; + key.dsize = strlen(key_str) + 1; + + return key; + +failed: + errno = ENOMEM; + key.dptr = NULL; + key.dsize = 0; + return key; +} + +/* + check special dn's have valid attributes + currently only @ATTRIBUTES is checked +*/ +static int ltdb_check_special_dn(struct ldb_module *module, + const struct ldb_message *msg) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + unsigned int i, j; + + if (! ldb_dn_is_special(msg->dn) || + ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { + return LDB_SUCCESS; + } + + /* we have @ATTRIBUTES, let's check attributes are fine */ + /* should we check that we deny multivalued attributes ? */ + for (i = 0; i < msg->num_elements; i++) { + if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; + + for (j = 0; j < msg->elements[i].num_values; j++) { + if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { + ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return LDB_SUCCESS; +} + + +/* + we've made a modification to a dn - possibly reindex and + update sequence number +*/ +static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn) +{ + int ret = LDB_SUCCESS; + struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); + + /* only allow modifies inside a transaction, otherwise the + * ldb is unsafe */ + if (ltdb->in_transaction == 0) { + ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LTDB_INDEXLIST) || + ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) { + ret = ltdb_reindex(module); + } + + /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ + if (ret == LDB_SUCCESS && + !(ldb_dn_is_special(dn) && + ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { + ret = ltdb_increase_sequence_number(module); + } + + /* If the modify was to @OPTIONS, reload the cache */ + if (ret == LDB_SUCCESS && + ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) { + ret = ltdb_cache_reload(module); + } + + return ret; +} + +/* + store a record into the db +*/ +int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + TDB_DATA tdb_key, tdb_data; + int ret = LDB_SUCCESS; + + tdb_key = ltdb_key(module, msg->dn); + if (tdb_key.dptr == NULL) { + return LDB_ERR_OTHER; + } + + ret = ltdb_pack_data(module, msg, &tdb_data); + if (ret == -1) { + talloc_free(tdb_key.dptr); + return LDB_ERR_OTHER; + } + + ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); + if (ret != 0) { + ret = ltdb_err_map(tdb_error(ltdb->tdb)); + goto done; + } + +done: + talloc_free(tdb_key.dptr); + talloc_free(tdb_data.dptr); + + return ret; +} + + +/* + check if a attribute is a single valued, for a given element + */ +static bool ldb_tdb_single_valued(const struct ldb_schema_attribute *a, + struct ldb_message_element *el) +{ + if (!a) return false; + if (el != NULL) { + if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { + /* override from a ldb module, for example + used for the description field, which is + marked multi-valued in the schema but which + should not actually accept multiple + values */ + return true; + } + if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { + /* override from a ldb module, for example used for + deleted linked attribute entries */ + return false; + } + } + if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { + return true; + } + return false; +} + +static int ltdb_add_internal(struct ldb_module *module, + const struct ldb_message *msg) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret = LDB_SUCCESS; + unsigned int i; + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + } + + ret = ltdb_store(module, msg, TDB_INSERT); + if (ret != LDB_SUCCESS) { + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + ldb_asprintf_errstring(ldb, + "Entry %s already exists", + ldb_dn_get_linearized(msg->dn)); + } + return ret; + } + + ret = ltdb_index_add_new(module, msg); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ltdb_modified(module, msg->dn); + + return ret; +} + +/* + add a record to the database +*/ +static int ltdb_add(struct ltdb_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + int ret = LDB_SUCCESS; + + ret = ltdb_check_special_dn(module, req->op.add.message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_add_internal(module, req->op.add.message); + + return ret; +} + +/* + delete a record from the database, not updating indexes (used for deleting + index records) +*/ +int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + TDB_DATA tdb_key; + int ret; + + tdb_key = ltdb_key(module, dn); + if (!tdb_key.dptr) { + return LDB_ERR_OTHER; + } + + ret = tdb_delete(ltdb->tdb, tdb_key); + talloc_free(tdb_key.dptr); + + if (ret != 0) { + ret = ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return ret; +} + +static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn) +{ + struct ldb_message *msg; + int ret = LDB_SUCCESS; + + msg = ldb_msg_new(module); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* in case any attribute of the message was indexed, we need + to fetch the old record */ + ret = ltdb_search_dn1(module, dn, msg); + if (ret != LDB_SUCCESS) { + /* not finding the old record is an error */ + goto done; + } + + ret = ltdb_delete_noindex(module, dn); + if (ret != LDB_SUCCESS) { + goto done; + } + + /* remove any indexed attributes */ + ret = ltdb_index_delete(module, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ltdb_modified(module, dn); + if (ret != LDB_SUCCESS) { + goto done; + } + +done: + talloc_free(msg); + return ret; +} + +/* + delete a record from the database +*/ +static int ltdb_delete(struct ltdb_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + int ret = LDB_SUCCESS; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_delete_internal(module, req->op.del.dn); + + return ret; +} + +/* + find an element by attribute name. At the moment this does a linear search, + it should be re-coded to use a binary search once all places that modify + records guarantee sorted order + + return the index of the first matching element if found, otherwise -1 +*/ +static int find_element(const struct ldb_message *msg, const char *name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { + return i; + } + } + return -1; +} + + +/* + add an element to an existing record. Assumes a elements array that we + can call re-alloc on, and assumed that we can re-use the data pointers from + the passed in additional values. Use with care! + + returns 0 on success, -1 on failure (and sets errno) +*/ +static int ltdb_msg_add_element(struct ldb_context *ldb, + struct ldb_message *msg, + struct ldb_message_element *el) +{ + struct ldb_message_element *e2; + unsigned int i; + + if (el->num_values == 0) { + /* nothing to do here - we don't add empty elements */ + return 0; + } + + e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, + msg->num_elements+1); + if (!e2) { + errno = ENOMEM; + return -1; + } + + msg->elements = e2; + + e2 = &msg->elements[msg->num_elements]; + + e2->name = el->name; + e2->flags = el->flags; + e2->values = talloc_array(msg->elements, + struct ldb_val, el->num_values); + if (!e2->values) { + errno = ENOMEM; + return -1; + } + for (i=0;inum_values;i++) { + e2->values[i] = el->values[i]; + } + e2->num_values = el->num_values; + + ++msg->num_elements; + + return 0; +} + +/* + delete all elements having a specified attribute name +*/ +static int msg_delete_attribute(struct ldb_module *module, + struct ldb_context *ldb, + struct ldb_message *msg, const char *name) +{ + unsigned int i; + int ret; + struct ldb_message_element *el; + + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + i = el - msg->elements; + + ret = ltdb_index_del_element(module, msg->dn, el); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_free(el->values); + if (msg->num_elements > (i+1)) { + memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1))); + } + msg->num_elements--; + msg->elements = talloc_realloc(msg, msg->elements, + struct ldb_message_element, + msg->num_elements); + return LDB_SUCCESS; +} + +/* + delete all elements matching an attribute name/value + + return LDB Error on failure +*/ +static int msg_delete_element(struct ldb_module *module, + struct ldb_message *msg, + const char *name, + const struct ldb_val *val) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + unsigned int i; + int found, ret; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + + found = find_element(msg, name); + if (found == -1) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + i = (unsigned int) found; + el = &(msg->elements[i]); + + a = ldb_schema_attribute_by_name(ldb, el->name); + + for (i=0;inum_values;i++) { + bool matched; + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &el->values[i], val, &matched); + if (ret != LDB_SUCCESS) return ret; + } else { + matched = (a->syntax->comparison_fn(ldb, ldb, + &el->values[i], val) == 0); + } + if (matched) { + if (el->num_values == 1) { + return msg_delete_attribute(module, ldb, msg, name); + } + + ret = ltdb_index_del_value(module, msg->dn, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (inum_values-1) { + memmove(&el->values[i], &el->values[i+1], + sizeof(el->values[i])* + (el->num_values-(i+1))); + } + el->num_values--; + + /* per definition we find in a canonicalised message an + attribute value only once. So we are finished here */ + return LDB_SUCCESS; + } + } + + /* Not found */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; +} + + +/* + modify a record - internal interface + + yuck - this is O(n^2). Luckily n is usually small so we probably + get away with it, but if we ever have really large attribute lists + then we'll need to look at this again + + 'req' is optional, and is used to specify controls if supplied +*/ +int ltdb_modify_internal(struct ldb_module *module, + const struct ldb_message *msg, + struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + TDB_DATA tdb_key, tdb_data; + struct ldb_message *msg2; + unsigned int i, j, k; + int ret = LDB_SUCCESS, idx; + struct ldb_control *control_permissive = NULL; + + if (req) { + control_permissive = ldb_request_get_control(req, + LDB_CONTROL_PERMISSIVE_MODIFY_OID); + } + + tdb_key = ltdb_key(module, msg->dn); + if (!tdb_key.dptr) { + return LDB_ERR_OTHER; + } + + tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); + if (!tdb_data.dptr) { + talloc_free(tdb_key.dptr); + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + msg2 = ldb_msg_new(tdb_key.dptr); + if (msg2 == NULL) { + free(tdb_data.dptr); + ret = LDB_ERR_OTHER; + goto done; + } + + ret = ltdb_unpack_data(module, &tdb_data, msg2); + free(tdb_data.dptr); + if (ret == -1) { + ret = LDB_ERR_OTHER; + goto done; + } + + if (!msg2->dn) { + msg2->dn = msg->dn; + } + + for (i=0; inum_elements; i++) { + struct ldb_message_element *el = &msg->elements[i], *el2; + struct ldb_val *vals; + const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); + const char *dn; + + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, + "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_CONSTRAINT_VIOLATION; + goto done; + } + + /* make a copy of the array so that a permissive + * control can remove duplicates without changing the + * original values, but do not copy data as we do not + * need to keep it around once the operation is + * finished */ + if (control_permissive) { + el = talloc(msg2, struct ldb_message_element); + if (!el) { + ret = LDB_ERR_OTHER; + goto done; + } + *el = msg->elements[i]; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + ret = LDB_ERR_OTHER; + goto done; + } + for (j = 0; j < el->num_values; j++) { + el->values[j] = msg->elements[i].values[j]; + } + } + + if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* Checks if element already exists */ + idx = find_element(msg2, el->name); + if (idx == -1) { + if (ltdb_msg_add_element(ldb, msg2, el) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + ret = ltdb_index_add_element(module, msg2->dn, + el); + if (ret != LDB_SUCCESS) { + goto done; + } + } else { + j = (unsigned int) idx; + el2 = &(msg2->elements[j]); + + /* We cannot add another value on a existing one + if the attribute is single-valued */ + if (ldb_tdb_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* Check that values don't exist yet on multi- + valued attributes or aren't provided twice */ + for (j = 0; j < el->num_values; j++) { + if (ldb_msg_find_val(el2, &el->values[j]) != NULL) { + if (control_permissive) { + /* remove this one as if it was never added */ + el->num_values--; + for (k = j; k < el->num_values; k++) { + el->values[k] = el->values[k + 1]; + } + j--; /* rewind */ + + continue; + } + + ldb_asprintf_errstring(ldb, + "attribute '%s': value #%u on '%s' already exists", + el->name, j, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { + ldb_asprintf_errstring(ldb, + "attribute '%s': value #%u on '%s' provided more than once", + el->name, j, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + } + + /* Now combine existing and new values to a new + attribute record */ + vals = talloc_realloc(msg2->elements, + el2->values, struct ldb_val, + el2->num_values + el->num_values); + if (vals == NULL) { + ldb_oom(ldb); + ret = LDB_ERR_OTHER; + goto done; + } + + for (j=0; jnum_values; j++) { + vals[el2->num_values + j] = + ldb_val_dup(vals, &el->values[j]); + } + + el2->values = vals; + el2->num_values += el->num_values; + + ret = ltdb_index_add_element(module, msg2->dn, el); + if (ret != LDB_SUCCESS) { + goto done; + } + } + + break; + + case LDB_FLAG_MOD_REPLACE: + + if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* TODO: This is O(n^2) - replace with more efficient check */ + for (j=0; jnum_values; j++) { + if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { + ldb_asprintf_errstring(ldb, + "attribute '%s': value #%u on '%s' provided more than once", + el->name, j, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + } + + /* Checks if element already exists */ + idx = find_element(msg2, el->name); + if (idx != -1) { + j = (unsigned int) idx; + el2 = &(msg2->elements[j]); + if (ldb_msg_element_compare(el, el2) == 0) { + /* we are replacing with the same values */ + continue; + } + + /* Delete the attribute if it exists in the DB */ + if (msg_delete_attribute(module, ldb, msg2, + el->name) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + } + + /* Recreate it with the new values */ + if (ltdb_msg_add_element(ldb, msg2, el) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + + ret = ltdb_index_add_element(module, msg2->dn, el); + if (ret != LDB_SUCCESS) { + goto done; + } + + break; + + case LDB_FLAG_MOD_DELETE: + dn = ldb_dn_get_linearized(msg2->dn); + if (dn == NULL) { + ret = LDB_ERR_OTHER; + goto done; + } + + if (msg->elements[i].num_values == 0) { + /* Delete the whole attribute */ + ret = msg_delete_attribute(module, ldb, msg2, + msg->elements[i].name); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && + control_permissive) { + ret = LDB_SUCCESS; + } else { + ldb_asprintf_errstring(ldb, + "attribute '%s': no such attribute for delete on '%s'", + msg->elements[i].name, dn); + } + if (ret != LDB_SUCCESS) { + goto done; + } + } else { + /* Delete specified values from an attribute */ + for (j=0; j < msg->elements[i].num_values; j++) { + ret = msg_delete_element(module, + msg2, + msg->elements[i].name, + &msg->elements[i].values[j]); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && + control_permissive) { + ret = LDB_SUCCESS; + } else { + ldb_asprintf_errstring(ldb, + "attribute '%s': no matching attribute value while deleting attribute on '%s'", + msg->elements[i].name, dn); + } + if (ret != LDB_SUCCESS) { + goto done; + } + } + } + break; + default: + ldb_asprintf_errstring(ldb, + "attribute '%s': invalid modify flags on '%s': 0x%x", + msg->elements[i].name, ldb_dn_get_linearized(msg->dn), + msg->elements[i].flags & LDB_FLAG_MOD_MASK); + ret = LDB_ERR_PROTOCOL_ERROR; + goto done; + } + } + + ret = ltdb_store(module, msg2, TDB_MODIFY); + if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ltdb_modified(module, msg2->dn); + if (ret != LDB_SUCCESS) { + goto done; + } + +done: + talloc_free(tdb_key.dptr); + return ret; +} + +/* + modify a record +*/ +static int ltdb_modify(struct ltdb_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + int ret = LDB_SUCCESS; + + ret = ltdb_check_special_dn(module, req->op.mod.message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_modify_internal(module, req->op.mod.message, req); + + return ret; +} + +/* + rename a record +*/ +static int ltdb_rename(struct ltdb_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct ldb_message *msg; + int ret = LDB_SUCCESS; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_cache_load(ctx->module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = ldb_msg_new(ctx); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* in case any attribute of the message was indexed, we need + to fetch the old record */ + ret = ltdb_search_dn1(module, req->op.rename.olddn, msg); + if (ret != LDB_SUCCESS) { + /* not finding the old record is an error */ + return ret; + } + + /* Always delete first then add, to avoid conflicts with + * unique indexes. We rely on the transaction to make this + * atomic + */ + ret = ltdb_delete_internal(module, msg->dn); + if (ret != LDB_SUCCESS) { + return ret; + } + + msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); + if (msg->dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_add_internal(module, msg); + + return ret; +} + +static int ltdb_start_trans(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + + if (tdb_transaction_start(ltdb->tdb) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + ltdb->in_transaction++; + + ltdb_index_transaction_start(module); + + return LDB_SUCCESS; +} + +static int ltdb_prepare_commit(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + + if (ltdb->in_transaction != 1) { + return LDB_SUCCESS; + } + + if (ltdb_index_transaction_commit(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); + ltdb->in_transaction--; + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) { + ltdb->in_transaction--; + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + ltdb->prepared_commit = true; + + return LDB_SUCCESS; +} + +static int ltdb_end_trans(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + + if (!ltdb->prepared_commit) { + int ret = ltdb_prepare_commit(module); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + ltdb->in_transaction--; + ltdb->prepared_commit = false; + + if (tdb_transaction_commit(ltdb->tdb) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return LDB_SUCCESS; +} + +static int ltdb_del_trans(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); + + ltdb->in_transaction--; + + if (ltdb_index_transaction_cancel(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + tdb_transaction_cancel(ltdb->tdb); + return LDB_SUCCESS; +} + +/* + return sequenceNumber from @BASEINFO +*/ +static int ltdb_sequence_number(struct ltdb_context *ctx, + struct ldb_extended **ext) +{ + struct ldb_context *ldb; + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *res; + struct ldb_message *msg = NULL; + struct ldb_dn *dn; + const char *date; + int ret = LDB_SUCCESS; + + ldb = ldb_module_get_ctx(module); + + seq = talloc_get_type(req->op.extended.data, + struct ldb_seqnum_request); + if (seq == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ltdb_lock_read(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + res = talloc_zero(req, struct ldb_seqnum_result); + if (res == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + tmp_ctx = talloc_new(req); + if (tmp_ctx == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO); + if (dn == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + ret = ltdb_search_dn1(module, dn, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + + switch (seq->type) { + case LDB_SEQ_HIGHEST_SEQ: + res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); + break; + case LDB_SEQ_NEXT: + res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); + res->seq_num++; + break; + case LDB_SEQ_HIGHEST_TIMESTAMP: + date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL); + if (date) { + res->seq_num = ldb_string_to_time(date); + } else { + res->seq_num = 0; + /* zero is as good as anything when we don't know */ + } + break; + } + + *ext = talloc_zero(req, struct ldb_extended); + if (*ext == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; + (*ext)->data = talloc_steal(*ext, res); + +done: + talloc_free(tmp_ctx); + ltdb_unlock_read(module); + return ret; +} + +static void ltdb_request_done(struct ltdb_context *ctx, int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->error = error; + + req->callback(req, ares); +} + +static void ltdb_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct ltdb_context *ctx; + ctx = talloc_get_type(private_data, struct ltdb_context); + + if (!ctx->request_terminated) { + /* request is done now */ + ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); + } + + if (!ctx->request_terminated) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + } + talloc_free(ctx); +} + +static void ltdb_request_extended_done(struct ltdb_context *ctx, + struct ldb_extended *ext, + int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->response = ext; + ares->error = error; + + req->callback(req, ares); +} + +static void ltdb_handle_extended(struct ltdb_context *ctx) +{ + struct ldb_extended *ext = NULL; + int ret; + + if (strcmp(ctx->req->op.extended.oid, + LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { + /* get sequence number */ + ret = ltdb_sequence_number(ctx, &ext); + } else { + /* not recognized */ + ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + ltdb_request_extended_done(ctx, ext, ret); +} + +static void ltdb_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct ltdb_context *ctx; + int ret; + + ctx = talloc_get_type(private_data, struct ltdb_context); + + if (ctx->request_terminated) { + goto done; + } + + switch (ctx->req->operation) { + case LDB_SEARCH: + ret = ltdb_search(ctx); + break; + case LDB_ADD: + ret = ltdb_add(ctx); + break; + case LDB_MODIFY: + ret = ltdb_modify(ctx); + break; + case LDB_DELETE: + ret = ltdb_delete(ctx); + break; + case LDB_RENAME: + ret = ltdb_rename(ctx); + break; + case LDB_EXTENDED: + ltdb_handle_extended(ctx); + goto done; + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + } + + if (!ctx->request_terminated) { + /* request is done now */ + ltdb_request_done(ctx, ret); + } + +done: + if (!ctx->request_terminated) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + } + talloc_free(ctx); +} + +static int ltdb_request_destructor(void *ptr) +{ + struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy); + + if (spy->ctx != NULL) { + spy->ctx->request_terminated = true; + } + + return 0; +} + +static int ltdb_handle_request(struct ldb_module *module, + struct ldb_request *req) +{ + struct ldb_control *control_permissive; + struct ldb_context *ldb; + struct tevent_context *ev; + struct ltdb_context *ac; + struct tevent_timer *te; + struct timeval tv; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + control_permissive = ldb_request_get_control(req, + LDB_CONTROL_PERMISSIVE_MODIFY_OID); + + for (i = 0; req->controls && req->controls[i]; i++) { + if (req->controls[i]->critical && + req->controls[i] != control_permissive) { + ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", + req->controls[i]->oid); + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ev = ldb_get_event_context(ldb); + + ac = talloc_zero(ldb, struct ltdb_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac); + if (NULL == te) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + + tv.tv_sec = req->starttime + req->timeout; + ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac); + if (NULL == ac->timeout_event) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* set a spy so that we do not try to use the request context + * if it is freed before ltdb_callback fires */ + ac->spy = talloc(req, struct ltdb_req_spy); + if (NULL == ac->spy) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->spy->ctx = ac; + + talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor); + + return LDB_SUCCESS; +} + +static int ltdb_init_rootdse(struct ldb_module *module) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, + LDB_CONTROL_PERMISSIVE_MODIFY_OID); + /* ignore errors on this - we expect it for non-sam databases */ + + /* there can be no module beyond the backend, just return */ + return LDB_SUCCESS; +} + +static const struct ldb_module_ops ltdb_ops = { + .name = "tdb", + .init_context = ltdb_init_rootdse, + .search = ltdb_handle_request, + .add = ltdb_handle_request, + .modify = ltdb_handle_request, + .del = ltdb_handle_request, + .rename = ltdb_handle_request, + .extended = ltdb_handle_request, + .start_transaction = ltdb_start_trans, + .end_transaction = ltdb_end_trans, + .prepare_commit = ltdb_prepare_commit, + .del_transaction = ltdb_del_trans, +}; + +/* + connect to the database +*/ +static int ltdb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + const char *path; + int tdb_flags, open_flags; + struct ltdb_private *ltdb; + + /* parse the url */ + if (strchr(url, ':')) { + if (strncmp(url, "tdb://", 6) != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid tdb URL '%s'", url); + return LDB_ERR_OPERATIONS_ERROR; + } + path = url+6; + } else { + path = url; + } + + tdb_flags = TDB_DEFAULT | TDB_SEQNUM; + + /* check for the 'nosync' option */ + if (flags & LDB_FLG_NOSYNC) { + tdb_flags |= TDB_NOSYNC; + } + + /* and nommap option */ + if (flags & LDB_FLG_NOMMAP) { + tdb_flags |= TDB_NOMMAP; + } + + if (flags & LDB_FLG_RDONLY) { + open_flags = O_RDONLY; + } else { + open_flags = O_CREAT | O_RDWR; + } + + ltdb = talloc_zero(ldb, struct ltdb_private); + if (!ltdb) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* note that we use quite a large default hash size */ + ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, + tdb_flags, open_flags, + ldb_get_create_perms(ldb), ldb); + if (!ltdb->tdb) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Unable to open tdb '%s'", path); + talloc_free(ltdb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (getenv("LDB_WARN_UNINDEXED")) { + ltdb->warn_unindexed = true; + } + + ltdb->sequence_number = 0; + + module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops); + if (!module) { + talloc_free(ltdb); + return LDB_ERR_OPERATIONS_ERROR; + } + ldb_module_set_private(module, ltdb); + talloc_steal(module, ltdb); + + if (ltdb_cache_load(module) != 0) { + talloc_free(module); + talloc_free(ltdb); + return LDB_ERR_OPERATIONS_ERROR; + } + + *_module = module; + return LDB_SUCCESS; +} + +int ldb_tdb_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("tdb", ltdb_connect, false); +} diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h new file mode 100644 index 00000000000..96ad43fbd6c --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -0,0 +1,139 @@ +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "tdb_compat.h" +#include "ldb_module.h" + +/* this private structure is used by the ltdb backend in the + ldb_context */ +struct ltdb_private { + TDB_CONTEXT *tdb; + unsigned int connect_flags; + + unsigned long long sequence_number; + + /* the low level tdb seqnum - used to avoid loading BASEINFO when + possible */ + int tdb_seqnum; + + struct ltdb_cache { + struct ldb_message *indexlist; + struct ldb_message *attributes; + bool one_level_indexes; + bool attribute_indexes; + } *cache; + + int in_transaction; + + bool check_base; + struct ltdb_idxptr *idxptr; + bool prepared_commit; + int read_lock_count; + + bool warn_unindexed; +}; + +/* + the async local context + holds also internal search state during a full db search +*/ +struct ltdb_req_spy { + struct ltdb_context *ctx; +}; + +struct ltdb_context { + struct ldb_module *module; + struct ldb_request *req; + + bool request_terminated; + struct ltdb_req_spy *spy; + + /* search stuff */ + const struct ldb_parse_tree *tree; + struct ldb_dn *base; + enum ldb_scope scope; + const char * const *attrs; + struct tevent_timer *timeout_event; +}; + +/* special record types */ +#define LTDB_INDEX "@INDEX" +#define LTDB_INDEXLIST "@INDEXLIST" +#define LTDB_IDX "@IDX" +#define LTDB_IDXVERSION "@IDXVERSION" +#define LTDB_IDXATTR "@IDXATTR" +#define LTDB_IDXONE "@IDXONE" +#define LTDB_BASEINFO "@BASEINFO" +#define LTDB_OPTIONS "@OPTIONS" +#define LTDB_ATTRIBUTES "@ATTRIBUTES" + +/* special attribute types */ +#define LTDB_SEQUENCE_NUMBER "sequenceNumber" +#define LTDB_CHECK_BASE "checkBaseOnSearch" +#define LTDB_MOD_TIMESTAMP "whenChanged" +#define LTDB_OBJECTCLASS "objectClass" + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ + +int ltdb_cache_reload(struct ldb_module *module); +int ltdb_cache_load(struct ldb_module *module); +int ltdb_increase_sequence_number(struct ldb_module *module); +int ltdb_check_at_attributes_values(const struct ldb_val *value); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_index.c */ + +struct ldb_parse_tree; + +int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *); +int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg); +int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg); +int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el); +int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el); +int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, + struct ldb_message_element *el, unsigned int v_idx); +int ltdb_reindex(struct ldb_module *module); +int ltdb_index_transaction_start(struct ldb_module *module); +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, + const struct ldb_val *val); +void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); +int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg); +int ltdb_add_attr_results(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + const char * const attrs[], + unsigned int *count, + struct ldb_message ***res); +int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs); +int ltdb_search(struct ltdb_context *ctx); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ +int ltdb_lock_read(struct ldb_module *module); +int ltdb_unlock_read(struct ldb_module *module); +TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); +int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); +int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req); +int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn); +int ltdb_err_map(enum TDB_ERROR tdb_code); + +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb); diff --git a/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/lib/ldb/ldb_tdb/ldb_tdb_wrap.c new file mode 100644 index 00000000000..16a037a6c33 --- /dev/null +++ b/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -0,0 +1,165 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** 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 . +*/ + +#include "ldb_tdb.h" +#include "dlinklist.h" + +/* FIXME: TDB2 does this internally, so no need to wrap multiple opens! */ +#if BUILD_TDB2 +static void ltdb_log_fn(struct tdb_context *tdb, + enum tdb_log_level level, + const char *message, + struct ldb_context *ldb) +{ + enum ldb_debug_level ldb_level; + const char *name = tdb_name(tdb); + + switch (level) { + case TDB_LOG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + case TDB_LOG_USE_ERROR: + case TDB_LOG_ERROR: + ldb_level = LDB_DEBUG_FATAL; + break; + default: + ldb_level = LDB_DEBUG_FATAL; + } + + ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); +} +#else /* !TDB2 */ +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); + enum ldb_debug_level ldb_level; + char *message; + + if (ldb == NULL) + return; + + va_start(ap, fmt); + message = talloc_vasprintf(ldb, fmt, ap); + va_end(ap); + + switch (level) { + case TDB_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TDB_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TDB_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TDB_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + default: + ldb_level = LDB_DEBUG_FATAL; + } + + ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); + talloc_free(message); +} +#endif + +/* + the purpose of this code is to work around the braindead posix locking + rules, to allow us to have a ldb open more than once while allowing + locking to work + + TDB2 handles multiple opens, so we don't have this problem there. +*/ + +struct ltdb_wrap { + struct ltdb_wrap *next, *prev; + struct tdb_context *tdb; + dev_t device; + ino_t inode; +}; + +static struct ltdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int ltdb_wrap_destructor(struct ltdb_wrap *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} + +/* + wrapped connection to a tdb database. The caller should _not_ free + this as it is not a talloc structure (as tdb does not use talloc + yet). It will auto-close when the caller frees the mem_ctx that is + passed to this call + */ +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, + int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb) +{ + struct ltdb_wrap *w; + struct stat st; + + if (stat(path, &st) == 0) { + for (w=tdb_list;w;w=w->next) { + if (st.st_dev == w->device && st.st_ino == w->inode) { + if (!talloc_reference(mem_ctx, w)) { + return NULL; + } + return w->tdb; + } + } + } + + w = talloc(mem_ctx, struct ltdb_wrap); + if (w == NULL) { + return NULL; + } + + w->tdb = tdb_open_compat(path, hash_size, tdb_flags, open_flags, mode, ltdb_log_fn, ldb); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + if (fstat(tdb_fd(w->tdb), &st) != 0) { + tdb_close(w->tdb); + talloc_free(w); + return NULL; + } + + w->device = st.st_dev; + w->inode = st.st_ino; + + talloc_set_destructor(w, ltdb_wrap_destructor); + + DLIST_ADD(tdb_list, w); + + return w->tdb; +} diff --git a/lib/ldb/mainpage.dox b/lib/ldb/mainpage.dox new file mode 100644 index 00000000000..bbd8d9c5025 --- /dev/null +++ b/lib/ldb/mainpage.dox @@ -0,0 +1,80 @@ +/** + +\mainpage ldb + +\section Overview + +ldb is a LDAP-like embedded database. It is not at all LDAP standards +compliant, so if you want a standards compliant database then please +see the excellent OpenLDAP +project.

+ +What ldb does is provide a fast database with an LDAP-like API +designed to be used within an application. In some ways it can be seen +as a intermediate solution between key-value pair databases and a real +LDAP database.

+ +ldb is the database engine used in Samba4. + +\section Features + +The main features that separate ldb from other solutions are: + - Safe multi-reader, multi-writer, using byte range locking + - LDAP-like API + - fast operation + - choice of local tdb, local sqlite3 or remote LDAP backends + - integration with talloc + - schema-less operation, for trivial setup + - modules for extensions (such as schema support) + - easy setup of indexes and attribute properties + - ldbedit tool for database editing (reminiscent of 'vipw') + - ldif for import/export + +\section Documentation + +ldb has limited programmer and administrator documentation: + - a list of functions + - a list of examples + - a list of data structures + - a list of constants + +If you need more information than is presented in this document, you +may wish to look at the source code, especially the source code in the +tools directory. + +ldb makes use of the LDAP Data Interchange Format (LDIF), which is +documented in RFC +2849. + +\section Support + +ldb does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +\section Download + +You can download the latest release either via rsync or anonymous +svn. To fetch via svn use the following commands: + +\verbatim + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc +\endverbatim + +To fetch via rsync use these commands: + +\verbatim + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . +\endverbatim + +\section Credits + +ldb is another product of the prolific Andrew Tridgell. + +*/ diff --git a/lib/ldb/man/ldb.3.xml b/lib/ldb/man/ldb.3.xml new file mode 100644 index 00000000000..19d9a89e102 --- /dev/null +++ b/lib/ldb/man/ldb.3.xml @@ -0,0 +1,262 @@ + + + + + + ldb + 3 + + + + ldb + The Samba Project + A light-weight database library + + + + #include <ldb.h> + + + + description + + +ldb is a light weight embedded database library and API. With a +programming interface that is very similar to LDAP, ldb can store its +data either in a tdb(3) database or in a real LDAP database. + + + +When used with the tdb backend ldb does not require any database +daemon. Instead, ldb function calls are processed immediately by the +ldb library, which does IO directly on the database, while allowing +multiple readers/writers using operating system byte range locks. This +leads to an API with very low overheads, often resulting in speeds of +more than 10x what can be achieved with a more traditional LDAP +architecture. + + + +In a taxonomy of databases ldb would sit half way between key/value +pair databases (such as berkley db or tdb) and a full LDAP +database. With a structured attribute oriented API like LDAP and good +indexing capabilities, ldb can be used for quite sophisticated +applications that need a light weight database, without the +administrative overhead of a full LDAP installation. + + + +Included with ldb are a number of useful command line tools for +manipulating a ldb database. These tools are similar in style to the +equivalent ldap command line tools. + + + +In its default mode of operation with a tdb backend, ldb can also be +seen as a "schema-less LDAP". By default ldb does not require a +schema, which greatly reduces the complexity of getting started with +ldb databases. As the complexity of you application grows you can take +advantage of some of the optional schema-like attributes that ldb +offers, or you can migrate to using the full LDAP api while keeping +your exiting ldb code. + + + +If you are new to ldb, then I suggest starting with the manual pages +for ldbsearch(1) and ldbedit(1), and experimenting with a local +database. Then I suggest you look at the ldb_connect(3) and +ldb_search(3) manual pages. + + + + + TOOLS + + + + ldbsearch(1) + - command line ldb search utility + + + + ldbedit(1) + - edit all or part of a ldb database using your favourite editor + + + + ldbadd(1) + - add records to a ldb database using LDIF formatted input + + + + ldbdel(1) + - delete records from a ldb database + + + + ldbmodify(1) + - modify records in a ldb database using LDIF formatted input + + + + + + FUNCTIONS + + + + ldb_connect(3) + - connect to a ldb backend + + + + ldb_search(3) + - perform a database search + + + + ldb_add(3) + - add a record to the database + + + + ldb_delete(3) + - delete a record from the database + + + + ldb_modify(3) + - modify a record in the database + + + + ldb_errstring(3) + - retrieve extended error information from the last operation + + + + ldb_ldif_write(3) + - write a LDIF formatted message + + + + ldb_ldif_write_file(3) + - write a LDIF formatted message to a file + + + + ldb_ldif_read(3) + - read a LDIF formatted message + + + + ldb_ldif_read_free(3) + - free the result of a ldb_ldif_read() + + + + ldb_ldif_read_file(3) + - read a LDIF message from a file + + + + ldb_ldif_read_string(3) + - read a LDIF message from a string + + + + ldb_msg_find_element(3) + - find an element in a ldb_message + + + + ldb_val_equal_exact(3) + - compare two ldb_val structures + + + + ldb_msg_find_val(3) + - find an element by value + + + + ldb_msg_add_empty(3) + - add an empty message element to a ldb_message + + + + + ldb_msg_add(3) + - add a non-empty message element to a ldb_message + + + + + ldb_msg_element_compare(3) + - compare two ldb_message_element structures + + + + + ldb_msg_find_int(3) + - return an integer value from a ldb_message + + + + + ldb_msg_find_uint(3) + - return an unsigned integer value from a ldb_message + + + + + ldb_msg_find_double(3) + - return a double value from a ldb_message + + + + + ldb_msg_find_string(3) + - return a string value from a ldb_message + + + + + ldb_set_alloc(3) + - set the memory allocation function to be used by ldb + + + + + ldb_set_debug(3) + - set a debug handler to be used by ldb + + + + + ldb_set_debug_stderr(3) + - set a debug handler for stderr output + + + + + + Author + + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + +ldb is released under the GNU Lesser General Public License version 2 +or later. Please see the file COPYING for license details. + + + diff --git a/lib/ldb/man/ldbadd.1.xml b/lib/ldb/man/ldbadd.1.xml new file mode 100644 index 00000000000..b77b151e2df --- /dev/null +++ b/lib/ldb/man/ldbadd.1.xml @@ -0,0 +1,105 @@ + + + + + + ldbadd + 1 + + + + + ldbadd + Command-line utility for adding records to an LDB + + + + + ldbadd + -h + -H LDB-URL + ldif-file1 + ldif-file2 + ... + + + + + DESCRIPTION + + ldbadd adds records to an ldb(3) database. It reads + the ldif(5) files specified on the command line and adds + the records from these files to the LDB database, which is specified + by the -H option or the LDB_URL environment variable. + + + If - is specified as a ldb file, the ldif input is read from + standard input. + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbdel, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/lib/ldb/man/ldbdel.1.xml b/lib/ldb/man/ldbdel.1.xml new file mode 100644 index 00000000000..41da3bc9845 --- /dev/null +++ b/lib/ldb/man/ldbdel.1.xml @@ -0,0 +1,105 @@ + + + + + + ldbdel + 1 + + + + + ldbdel + Command-line program for deleting LDB records + + + + + ldbdel + -h + -H LDB-URL + dn + ... + + + + + DESCRIPTION + + ldbdel deletes records from an ldb(3) database. + It deletes the records identified by the dn's specified + on the command-line. + + ldbdel uses either the database that is specified with + the -H option or the database specified by the LDB_URL environment + variable. + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbadd, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + ldbdel was written by Andrew Tridgell. + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/lib/ldb/man/ldbedit.1.xml b/lib/ldb/man/ldbedit.1.xml new file mode 100644 index 00000000000..a2eec0579c2 --- /dev/null +++ b/lib/ldb/man/ldbedit.1.xml @@ -0,0 +1,200 @@ + + + + + + ldbedit + 1 + + + + + ldbedit + Edit LDB databases using your preferred editor + + + + + ldbedit + -? + --usage + -s base|one|sub + -b basedn + -a + -e editor + -H LDB-URL + expression + attributes + + + + + DESCRIPTION + + ldbedit is a utility that allows you to edit LDB entries (in + tdb files, sqlite files or LDAP servers) using your preferred editor. + ldbedit generates an LDIF file based on your query, allows you to edit + the LDIF, and then merges that LDIF back into the LDB backend. + + + + + + + OPTIONS + + + + -? + --help + + + Show list of available options, and a phrase describing what that option + does. + + + + + + --usage + + + Show list of available options. This is similar to the help option, + however it does not provide any description, and is hence shorter. + + + + + + -H <ldb-url> + + + LDB URL to connect to. For a tdb database, + this will be of the form + tdb://filename. + For a LDAP connection over unix domain + sockets, this will be of the form + ldapi://socket. For + a (potentially remote) LDAP connection over + TCP, this will be of the form + ldap://hostname. For + an SQLite database, this will be of the form + sqlite://filename. + + + + + + -s one|sub|base + Search scope to use. One-level, subtree or base. + + + + -a + -all + + Edit all records. This allows you to + apply the same change to a number of records + at once. You probably want to combine this + with an expression of the form + "objectclass=*". + + + + + + -e editor + --editor editor + + Specify the editor that should be used (overrides + the VISUAL and EDITOR environment + variables). If this option is not used, and + neither VISUAL nor EDITOR environment variables + are set, then the vi editor will be used. + + + + + + -b basedn + Specify Base Distinguished Name to use. + + + + -v + --verbose + + Make ldbedit more verbose about the + operations that are being performed. Without + this option, ldbedit will only provide a + summary change line. + + + + + + + + + + ENVIRONMENT + + + + LDB_URL + + LDB URL to connect to. This can be + overridden by using the -H command-line option.) + + + + + VISUAL and EDITOR + + + Environment variables used to determine what + editor to use. VISUAL takes precedence over + EDITOR, and both are overridden by the + -e command-line option. + + + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1) + + + + + AUTHOR + + + ldb was written by + Andrew Tridgell. + + + + If you wish to report a problem or make a suggestion then please see + the web site for + current contact and maintainer information. + + + + This manpage was written by Jelmer Vernooij and updated + by Brad Hards. + + + + + diff --git a/lib/ldb/man/ldbmodify.1.xml b/lib/ldb/man/ldbmodify.1.xml new file mode 100644 index 00000000000..9bb492ab1bb --- /dev/null +++ b/lib/ldb/man/ldbmodify.1.xml @@ -0,0 +1,93 @@ + + + + + + ldbmodify + 1 + + + + + ldbmodify + Modify records in a LDB database + + + + + ldbmodify + -H LDB-URL + ldif-file + + + + + DESCRIPTION + + + ldbmodify changes, adds and deletes records in a LDB database. + The changes that should be made to the LDB database are read from + the specified LDIF-file. If - is specified as the filename, input is read from stdin. + + + For now, see ldapmodify(1) for details on the LDIF file format. + + + + + + OPTIONS + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbedit + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/lib/ldb/man/ldbrename.1.xml b/lib/ldb/man/ldbrename.1.xml new file mode 100644 index 00000000000..3576bc27bbc --- /dev/null +++ b/lib/ldb/man/ldbrename.1.xml @@ -0,0 +1,107 @@ + + + + + + ldbrename + 1 + + + + + ldbrename + Edit LDB databases using your favorite editor + + + + + ldbrename + -h + -o options + olddn + newdb + + + + + DESCRIPTION + + ldbrename is a utility that allows you to rename trees in + an LDB database based by DN. This utility takes + two arguments: the original + DN name of the top element and the DN to change it to. + + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + -o options + Extra ldb options, such as + modules. + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbdel, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/lib/ldb/man/ldbsearch.1.xml b/lib/ldb/man/ldbsearch.1.xml new file mode 100644 index 00000000000..623a5992e5e --- /dev/null +++ b/lib/ldb/man/ldbsearch.1.xml @@ -0,0 +1,119 @@ + + + + + + ldbsearch + 1 + + + + + ldbsearch + Search for records in a LDB database + + + + + ldbsearch + -h + -s base|one|sub + -b basedn + -i + -H LDB-URL + expression + attributes + + + + + DESCRIPTION + + ldbsearch searches a LDB database for records matching the + specified expression (see the ldapsearch(1) manpage for + a description of the expression format). For each + record, the specified attributes are printed. + + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + -s one|sub|base + Search scope to use. One-level, subtree or base. + + + + -i + Read search expressions from stdin. + + + + -b basedn + Specify Base DN to use. + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(3), ldbedit(1) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/lib/ldb/modules/asq.c b/lib/ldb/modules/asq.c new file mode 100644 index 00000000000..7482de826f0 --- /dev/null +++ b/lib/ldb/modules/asq.c @@ -0,0 +1,416 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + + ** 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 attribute scoped query control module + * + * Description: this module searches all the objects pointed by + * the DNs contained in the references attribute + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct asq_context { + + enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; + + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_asq_control *asq_ctrl; + + const char * const *req_attrs; + char *req_attribute; + enum { + ASQ_CTRL_SUCCESS = 0, + ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, + ASQ_CTRL_UNWILLING_TO_PERFORM = 53, + ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 + } asq_ret; + + struct ldb_reply *base_res; + + struct ldb_request **reqs; + unsigned int num_reqs; + unsigned int cur_req; + + struct ldb_control **controls; +}; + +static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct asq_context *ac; + + ldb = ldb_module_get_ctx(module); + + ac = talloc_zero(req, struct asq_context); + if (ac == NULL) { + ldb_oom(ldb); + return NULL; + } + + ac->module = module; + ac->req = req; + + return ac; +} + +static int asq_search_continue(struct asq_context *ac); + +static int asq_search_terminate(struct asq_context *ac) +{ + struct ldb_asq_control *asq; + unsigned int i; + + if (ac->controls) { + for (i = 0; ac->controls[i]; i++) /* count em */ ; + } else { + i = 0; + } + + ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); + + if (ac->controls == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i] = talloc(ac->controls, struct ldb_control); + if (ac->controls[i] == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; + ac->controls[i]->critical = 0; + + asq = talloc_zero(ac->controls[i], struct ldb_asq_control); + if (asq == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + asq->result = ac->asq_ret; + + ac->controls[i]->data = asq; + + ac->controls[i + 1] = NULL; + + return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); +} + +static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct asq_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct asq_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ac->base_res = talloc_move(ac, &ares); + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + + talloc_free(ares); + + /* next step */ + ret = asq_search_continue(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + } + return LDB_SUCCESS; +} + +static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct asq_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct asq_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + /* pass the message up to the original callback as we + * do not have to elaborate on it any further */ + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + talloc_free(ares); + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + + talloc_free(ares); + + ret = asq_search_continue(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + } + + return LDB_SUCCESS; +} + +static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) +{ + struct ldb_context *ldb; + const char **base_attrs; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + ac->req_attrs = ac->req->op.search.attrs; + ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); + if (ac->req_attribute == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + base_attrs = talloc_array(ac, const char *, 2); + if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; + + base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); + if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; + + base_attrs[1] = NULL; + + ret = ldb_build_search_req(base_req, ldb, ac, + ac->req->op.search.base, + LDB_SCOPE_BASE, + NULL, + (const char * const *)base_attrs, + NULL, + ac, asq_base_callback, + ac->req); + if (ret != LDB_SUCCESS) { + return ret; + } + + return LDB_SUCCESS; +} + +static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) +{ + struct ldb_context *ldb; + struct ldb_control **saved_controls; + struct ldb_control *control; + struct ldb_dn *dn; + struct ldb_message_element *el; + unsigned int i; + int ret; + + if (ac->base_res == NULL) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + ldb = ldb_module_get_ctx(ac->module); + + el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); + /* no values found */ + if (el == NULL) { + ac->asq_ret = ASQ_CTRL_SUCCESS; + *terminated = true; + return asq_search_terminate(ac); + } + + ac->num_reqs = el->num_values; + ac->cur_req = 0; + ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); + if (ac->reqs == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < el->num_values; i++) { + + dn = ldb_dn_new(ac, ldb, + (const char *)el->values[i].data); + if ( ! ldb_dn_validate(dn)) { + ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; + *terminated = true; + return asq_search_terminate(ac); + } + + ret = ldb_build_search_req_ex(&ac->reqs[i], + ldb, ac, + dn, LDB_SCOPE_BASE, + ac->req->op.search.tree, + ac->req_attrs, + ac->req->controls, + ac, asq_reqs_callback, + ac->req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* remove the ASQ control itself */ + control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); + if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +static int asq_search_continue(struct asq_context *ac) +{ + struct ldb_context *ldb; + bool terminated = false; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + switch (ac->step) { + case ASQ_SEARCH_BASE: + + /* build up the requests call chain */ + ret = asq_build_multiple_requests(ac, &terminated); + if (ret != LDB_SUCCESS || terminated) { + return ret; + } + + ac->step = ASQ_SEARCH_MULTI; + + return ldb_request(ldb, ac->reqs[ac->cur_req]); + + case ASQ_SEARCH_MULTI: + + ac->cur_req++; + + if (ac->cur_req == ac->num_reqs) { + /* done */ + return asq_search_terminate(ac); + } + + return ldb_request(ldb, ac->reqs[ac->cur_req]); + } + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int asq_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_request *base_req; + struct ldb_control *control; + struct asq_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* check if there's an ASQ control */ + control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + ac = asq_context_init(module, req); + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* check the search is well formed */ + if (req->op.search.scope != LDB_SCOPE_BASE) { + ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; + return asq_search_terminate(ac); + } + + ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); + if (!ac->asq_ctrl) { + return LDB_ERR_PROTOCOL_ERROR; + } + + ret = asq_build_first_request(ac, &base_req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ac->step = ASQ_SEARCH_BASE; + + return ldb_request(ldb, base_req); +} + +static int asq_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_asq_module_ops = { + .name = "asq", + .search = asq_search, + .init_context = asq_init +}; + +int ldb_asq_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_asq_module_ops); +} diff --git a/lib/ldb/modules/paged_results.c b/lib/ldb/modules/paged_results.c new file mode 100644 index 00000000000..2d6c62fd54b --- /dev/null +++ b/lib/ldb/modules/paged_results.c @@ -0,0 +1,438 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + + ** 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: paged_result + * + * Component: ldb paged results control module + * + * Description: this module caches a complete search and sends back + * results in chunks as asked by the client + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct message_store { + /* keep the whole ldb_reply as an optimization + * instead of freeing and talloc-ing the container + * on each result */ + struct ldb_reply *r; + struct message_store *next; +}; + +struct private_data; + +struct results_store { + + struct private_data *priv; + + char *cookie; + time_t timestamp; + + struct results_store *next; + + struct message_store *first; + struct message_store *last; + int num_entries; + + struct message_store *first_ref; + struct message_store *last_ref; + + struct ldb_control **controls; +}; + +struct private_data { + unsigned int next_free_id; + struct results_store *store; + +}; + +static int store_destructor(struct results_store *del) +{ + struct private_data *priv = del->priv; + struct results_store *loop; + + if (priv->store == del) { + priv->store = del->next; + return 0; + } + + for (loop = priv->store; loop; loop = loop->next) { + if (loop->next == del) { + loop->next = del->next; + return 0; + } + } + + /* is not in list ? */ + return -1; +} + +static struct results_store *new_store(struct private_data *priv) +{ + struct results_store *newr; + unsigned int new_id = priv->next_free_id++; + + /* TODO: we should have a limit on the number of + * outstanding paged searches + */ + + newr = talloc(priv, struct results_store); + if (!newr) return NULL; + + newr->priv = priv; + + newr->cookie = talloc_asprintf(newr, "%d", new_id); + if (!newr->cookie) { + talloc_free(newr); + return NULL; + } + + newr->timestamp = time(NULL); + + newr->first = NULL; + newr->num_entries = 0; + newr->first_ref = NULL; + newr->controls = NULL; + + newr->next = priv->store; + priv->store = newr; + + talloc_set_destructor(newr, store_destructor); + + return newr; +} + +struct paged_context { + struct ldb_module *module; + struct ldb_request *req; + + struct results_store *store; + int size; + struct ldb_control **controls; +}; + +static int paged_results(struct paged_context *ac) +{ + struct ldb_paged_control *paged; + struct message_store *msg; + unsigned int i, num_ctrls; + int ret; + + if (ac->store == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + while (ac->store->num_entries > 0 && ac->size > 0) { + msg = ac->store->first; + ret = ldb_module_send_entry(ac->req, msg->r->message, msg->r->controls); + if (ret != LDB_SUCCESS) { + return ret; + } + + ac->store->first = msg->next; + talloc_free(msg); + ac->store->num_entries--; + ac->size--; + } + + while (ac->store->first_ref != NULL) { + msg = ac->store->first_ref; + ret = ldb_module_send_referral(ac->req, msg->r->referral); + if (ret != LDB_SUCCESS) { + return ret; + } + + ac->store->first_ref = msg->next; + talloc_free(msg); + } + + /* return result done */ + num_ctrls = 1; + i = 0; + + if (ac->store->controls != NULL) { + while (ac->store->controls[i]) i++; /* counting */ + + num_ctrls += i; + } + + ac->controls = talloc_array(ac, struct ldb_control *, num_ctrls +1); + if (ac->controls == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ac->controls[num_ctrls] = NULL; + + for (i = 0; i < (num_ctrls -1); i++) { + ac->controls[i] = talloc_reference(ac->controls, ac->store->controls[i]); + } + + ac->controls[i] = talloc(ac->controls, struct ldb_control); + if (ac->controls[i] == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i]->oid = talloc_strdup(ac->controls[i], + LDB_CONTROL_PAGED_RESULTS_OID); + if (ac->controls[i]->oid == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i]->critical = 0; + + paged = talloc(ac->controls[i], struct ldb_paged_control); + if (paged == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i]->data = paged; + + if (ac->size > 0) { + paged->size = 0; + paged->cookie = NULL; + paged->cookie_len = 0; + } else { + paged->size = ac->store->num_entries; + paged->cookie = talloc_strdup(paged, ac->store->cookie); + paged->cookie_len = strlen(paged->cookie) + 1; + } + + return LDB_SUCCESS; +} + +static int paged_search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct paged_context *ac ; + struct message_store *msg_store; + int ret; + + ac = talloc_get_type(req->context, struct paged_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + msg_store = talloc(ac->store, struct message_store); + if (msg_store == NULL) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + msg_store->next = NULL; + msg_store->r = talloc_steal(msg_store, ares); + + if (ac->store->first == NULL) { + ac->store->first = msg_store; + } else { + ac->store->last->next = msg_store; + } + ac->store->last = msg_store; + + ac->store->num_entries++; + + break; + + case LDB_REPLY_REFERRAL: + msg_store = talloc(ac->store, struct message_store); + if (msg_store == NULL) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + msg_store->next = NULL; + msg_store->r = talloc_steal(msg_store, ares); + + if (ac->store->first_ref == NULL) { + ac->store->first_ref = msg_store; + } else { + ac->store->last_ref->next = msg_store; + } + ac->store->last_ref = msg_store; + + break; + + case LDB_REPLY_DONE: + ac->store->controls = talloc_move(ac->store, &ares->controls); + ret = paged_results(ac); + return ldb_module_done(ac->req, ac->controls, + ares->response, ret); + } + + return LDB_SUCCESS; +} + +static int paged_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_control *control; + struct private_data *private_data; + struct ldb_paged_control *paged_ctrl; + struct ldb_control **saved_controls; + struct ldb_request *search_req; + struct paged_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* check if there's a paged request control */ + control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + paged_ctrl = talloc_get_type(control->data, struct ldb_paged_control); + if (!paged_ctrl) { + return LDB_ERR_PROTOCOL_ERROR; + } + + private_data = talloc_get_type(ldb_module_get_private(module), + struct private_data); + + ac = talloc_zero(req, struct paged_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->size = paged_ctrl->size; + if (ac->size < 0) { + /* apparently some clients send more than 2^31. This + violates the ldap standard, but we need to cope */ + ac->size = 0x7FFFFFFF; + } + + /* check if it is a continuation search the store */ + if (paged_ctrl->cookie_len == 0) { + if (paged_ctrl->size == 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->store = new_store(private_data); + if (ac->store == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req_ex(&search_req, ldb, ac, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->controls, + ac, + paged_search_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* save it locally and remove it from the list */ + /* we do not need to replace them later as we + * are keeping the original req intact */ + if (!ldb_save_controls(control, search_req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); + + } else { + struct results_store *current = NULL; + + /* TODO: age out old outstanding requests */ + for (current = private_data->store; current; current = current->next) { + if (strcmp(current->cookie, paged_ctrl->cookie) == 0) { + current->timestamp = time(NULL); + break; + } + } + if (current == NULL) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ac->store = current; + + /* check if it is an abandon */ + if (ac->size == 0) { + return ldb_module_done(req, NULL, NULL, + LDB_SUCCESS); + } + + ret = paged_results(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); + } + return ldb_module_done(req, ac->controls, NULL, + LDB_SUCCESS); + } +} + +static int paged_request_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + struct private_data *data; + int ret; + + ldb = ldb_module_get_ctx(module); + + data = talloc(module, struct private_data); + if (data == NULL) { + return LDB_ERR_OTHER; + } + + data->next_free_id = 1; + data->store = NULL; + ldb_module_set_private(module, data); + + ret = ldb_mod_register_control(module, LDB_CONTROL_PAGED_RESULTS_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "paged_results:" + "Unable to register control with rootdse!"); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_paged_results_module_ops = { + .name = "paged_results", + .search = paged_search, + .init_context = paged_request_init +}; + +int ldb_paged_results_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_paged_results_module_ops); +} diff --git a/lib/ldb/modules/paged_searches.c b/lib/ldb/modules/paged_searches.c new file mode 100644 index 00000000000..68eeb4c76e3 --- /dev/null +++ b/lib/ldb/modules/paged_searches.c @@ -0,0 +1,386 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + Copyright (C) Andrew Bartlett 2009 + + ** 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: paged_searches + * + * Component: ldb paged searches module + * + * Description: this module detects if the remote ldap server supports + * paged results and use them to transparently access all objects + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +#define PS_DEFAULT_PAGE_SIZE 500 +/* 500 objects per query seem to be a decent compromise + * the default AD limit per request is 1000 entries */ + +struct private_data { + + bool paged_supported; +}; + +struct ps_context { + struct ldb_module *module; + struct ldb_request *req; + + bool pending; + + char **saved_referrals; + unsigned int num_referrals; + + struct ldb_request *down_req; +}; + +static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct ldb_control *rep_control, *req_control; + struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; + ldb = ldb_module_get_ctx(ac->module); + + rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); + if (rep_control) { + paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); + } + + req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); + paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); + + if (!rep_control || !paged_rep_control) { + if (paged_req_control->cookie) { + /* something wrong here - why give us a control back befre, but not one now? */ + ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); + return LDB_ERR_OPERATIONS_ERROR; + } else { + /* No cookie received yet, valid to just return the full data set */ + + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } + } + + if (paged_rep_control->cookie_len == 0) { + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + /* if there's a reply control we must find a request + * control matching it */ + + if (paged_req_control->cookie) { + talloc_free(paged_req_control->cookie); + } + + paged_req_control->cookie = talloc_memdup(req_control, + paged_rep_control->cookie, + paged_rep_control->cookie_len); + paged_req_control->cookie_len = paged_rep_control->cookie_len; + + ac->pending = true; + return LDB_SUCCESS; +} + +static int store_referral(struct ps_context *ac, char *referral) +{ + ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); + if (!ac->saved_referrals) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); + if (!ac->saved_referrals[ac->num_referrals]) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->num_referrals++; + ac->saved_referrals[ac->num_referrals] = NULL; + + return LDB_SUCCESS; +} + +static int send_referrals(struct ps_context *ac) +{ + struct ldb_reply *ares; + int ret; + unsigned int i; + + for (i = 0; i < ac->num_referrals; i++) { + ares = talloc_zero(ac->req, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_REFERRAL; + ares->referral = ac->saved_referrals[i]; + + ret = ldb_module_send_referral(ac->req, ares->referral); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ps_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct ps_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + case LDB_REPLY_REFERRAL: + ret = store_referral(ac, ares->referral); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + case LDB_REPLY_DONE: + + ret = check_ps_continuation(ac, req, ares); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + + if (ac->pending) { + + ret = ldb_next_request(ac->module, ac->down_req); + + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + + } else { + + /* send referrals */ + ret = send_referrals(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + + /* send REPLY_DONE */ + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + } + break; + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int ps_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct private_data *private_data; + struct ps_context *ac; + struct ldb_paged_control *control; + int ret; + + private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); + ldb = ldb_module_get_ctx(module); + + /* check if paging is supported */ + if (!private_data || !private_data->paged_supported) { + /* do not touch this request paged controls not + * supported or we + * are just not setup yet */ + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct ps_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->pending = false; + ac->saved_referrals = NULL; + ac->num_referrals = 0; + + ldb = ldb_module_get_ctx(ac->module); + + control = talloc(ac, struct ldb_paged_control); + if (!control) { + return LDB_ERR_OPERATIONS_ERROR; + } + + control->size = PS_DEFAULT_PAGE_SIZE; + control->cookie = NULL; + control->cookie_len = 0; + + ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, + ac->req->op.search.base, + ac->req->op.search.scope, + ac->req->op.search.tree, + ac->req->op.search.attrs, + ac->req->controls, + ac, + ps_callback, + ac->req); + LDB_REQ_SET_LOCATION(ac->down_req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, + true, control); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(ac->down_req, control); + + return ldb_next_request(ac->module, ac->down_req); +} + +static int check_supported_paged(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct private_data *data; + + data = talloc_get_type(req->context, struct private_data); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + if (ldb_msg_check_string_attribute(ares->message, + "supportedControl", + LDB_CONTROL_PAGED_RESULTS_OID)) { + data->paged_supported = true; + } + break; + + case LDB_REPLY_REFERRAL: + /* ignore */ + break; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int ps_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + static const char *attrs[] = { "supportedControl", NULL }; + struct private_data *data; + struct ldb_dn *base; + int ret; + struct ldb_request *req; + + ldb = ldb_module_get_ctx(module); + + data = talloc(module, struct private_data); + if (data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + data->paged_supported = false; + + ldb_module_set_private(module, data); + + base = ldb_dn_new(module, ldb, ""); + if (base == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_build_search_req(&req, ldb, module, + base, LDB_SCOPE_BASE, + "(objectClass=*)", + attrs, NULL, + data, check_supported_paged, + NULL); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_free(base); + talloc_free(req); + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_paged_searches_module_ops = { + .name = "paged_searches", + .search = ps_search, + .init_context = ps_init +}; + +int ldb_paged_searches_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_paged_searches_module_ops); +} diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c new file mode 100644 index 00000000000..50b63aee133 --- /dev/null +++ b/lib/ldb/modules/rdn_name.c @@ -0,0 +1,453 @@ +/* + ldb database library + + Copyright (C) Andrew Bartlett 2005-2009 + Copyright (C) Simo Sorce 2006-2008 + + ** 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: rdn_name + * + * Component: ldb rdn name module + * + * Description: keep a consistent name attribute on objects manpulations + * + * Author: Andrew Bartlett + * + * Modifications: + * - made the module async + * Simo Sorce Mar 2006 + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct rename_context { + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_reply *ares; +}; + +static int rdn_name_add_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct rename_context *ac; + + ac = talloc_get_type(req->context, struct rename_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); +} + +static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_request *down_req; + struct rename_context *ac; + struct ldb_message *msg; + struct ldb_message_element *attribute; + const struct ldb_schema_attribute *a; + const char *rdn_name; + const struct ldb_val *rdn_val_p; + struct ldb_val rdn_val; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.add.message->dn)) { + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct rename_context); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + msg = ldb_msg_copy_shallow(req, req->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (rdn_name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.add.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + rdn_val = ldb_val_dup(msg, rdn_val_p); + + /* Perhaps someone above us tried to set this? Then ignore it */ + ldb_msg_remove_attr(msg, "name"); + + ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + + a = ldb_schema_attribute_by_name(ldb, rdn_name); + if (a == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + attribute = ldb_msg_find_element(msg, rdn_name); + if (!attribute) { + /* add entry with normalised RDN information if possible */ + if (a->name != NULL) { + ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); + } else { + ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); + } + if (ret != LDB_SUCCESS) { + return ret; + } + } else { + /* normalise attribute name if possible */ + if (a->name != NULL) { + attribute->name = a->name; + } + /* normalise attribute value */ + for (i = 0; i < attribute->num_values; i++) { + bool matched; + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &rdn_val, &attribute->values[i], &matched); + if (ret != LDB_SUCCESS) return ret; + } else { + matched = (a->syntax->comparison_fn(ldb, msg, + &rdn_val, &attribute->values[i]) == 0); + } + if (matched) { + /* overwrite so it matches in case */ + attribute->values[i] = rdn_val; + break; + } + } + if (i == attribute->num_values) { + char *rdn_errstring = talloc_asprintf(ac, + "RDN mismatch on %s: %s (%.*s) should match one of:", + ldb_dn_get_linearized(msg->dn), rdn_name, + (int)rdn_val.length, (const char *)rdn_val.data); + for (i = 0; i < attribute->num_values; i++) { + rdn_errstring = talloc_asprintf_append( + rdn_errstring, " (%.*s)", + (int)attribute->values[i].length, + (const char *)attribute->values[i].data); + } + ldb_set_errstring(ldb, rdn_errstring); + /* Match AD's error here */ + return LDB_ERR_INVALID_DN_SYNTAX; + } + } + + ret = ldb_build_add_req(&down_req, ldb, req, + msg, + req->controls, + ac, rdn_name_add_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(down_req, msg); + + /* go on with the call chain */ + return ldb_next_request(module, down_req); +} + +static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct rename_context *ac; + + ac = talloc_get_type(req->context, struct rename_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* the only supported reply right now is a LDB_REPLY_DONE */ + if (ares->type != LDB_REPLY_DONE) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* send saved controls eventually */ + return ldb_module_done(ac->req, ac->ares->controls, + ac->ares->response, LDB_SUCCESS); +} + +static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct rename_context *ac; + struct ldb_request *mod_req; + const char *rdn_name; + const struct ldb_val *rdn_val_p; + struct ldb_val rdn_val; + struct ldb_message *msg; + int ret; + + ac = talloc_get_type(req->context, struct rename_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + goto error; + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* the only supported reply right now is a LDB_REPLY_DONE */ + if (ares->type != LDB_REPLY_DONE) { + goto error; + } + + /* save reply for caller */ + ac->ares = talloc_steal(ac, ares); + + msg = ldb_msg_new(ac); + if (msg == NULL) { + goto error; + } + msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); + if (msg->dn == NULL) { + goto error; + } + + rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); + if (rdn_name == NULL) { + goto error; + } + + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + goto error; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.rename.olddn)); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_NAMING_VIOLATION); + } + rdn_val = ldb_val_dup(msg, rdn_val_p); + + if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto error; + } + if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { + goto error; + } + if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto error; + } + if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { + goto error; + } + + ret = ldb_build_mod_req(&mod_req, ldb, + ac, msg, NULL, + ac, rdn_modify_callback, + req); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + talloc_steal(mod_req, msg); + + /* go on with the call chain */ + return ldb_next_request(ac->module, mod_req); + +error: + return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); +} + +static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct rename_context *ac; + struct ldb_request *down_req; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.rename.newdn)) { + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct rename_context); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + ret = ldb_build_rename_req(&down_req, + ldb, + ac, + req->op.rename.olddn, + req->op.rename.newdn, + req->controls, + ac, + rdn_rename_callback, + req); + + if (ret != LDB_SUCCESS) { + return ret; + } + + /* rename first, modify "name" if rename is ok */ + return ldb_next_request(module, down_req); +} + +static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + const struct ldb_val *rdn_val_p; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.mod.message->dn)) { + return ldb_next_request(module, req); + } + + rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + if (ldb_msg_find_element(req->op.mod.message, "distinguishedName")) { + ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + if (ldb_msg_find_element(req->op.mod.message, "name")) { + ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_NOT_ALLOWED_ON_RDN; + } + + if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { + ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_NOT_ALLOWED_ON_RDN; + } + + /* All OK, they kept their fingers out of the special attributes */ + return ldb_next_request(module, req); +} + +static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + const char *rdn_name; + const struct ldb_val *rdn_val_p; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.search.base)) { + return ldb_next_request(module, req); + } + + rdn_name = ldb_dn_get_rdn_name(req->op.search.base); + rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); + if ((rdn_name != NULL) && (rdn_val_p == NULL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.search.base)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + return ldb_next_request(module, req); +} + +static const struct ldb_module_ops ldb_rdn_name_module_ops = { + .name = "rdn_name", + .add = rdn_name_add, + .modify = rdn_name_modify, + .rename = rdn_name_rename, + .search = rdn_name_search +}; + +int ldb_rdn_name_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_rdn_name_module_ops); +} diff --git a/lib/ldb/modules/skel.c b/lib/ldb/modules/skel.c new file mode 100644 index 00000000000..1ce3ec1df97 --- /dev/null +++ b/lib/ldb/modules/skel.c @@ -0,0 +1,147 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 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 skel module + * + * Description: example module + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct private_data { + + char *some_private_data; +}; + +/* search */ +static int skel_search(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* add */ +static int skel_add(struct ldb_module *module, struct ldb_request *req){ + return ldb_next_request(module, req); +} + +/* modify */ +static int skel_modify(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* delete */ +static int skel_delete(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* rename */ +static int skel_rename(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* start a transaction */ +static int skel_start_trans(struct ldb_module *module) +{ + return ldb_next_start_trans(module); +} + +/* end a transaction */ +static int skel_end_trans(struct ldb_module *module) +{ + return ldb_next_end_trans(module); +} + +/* delete a transaction */ +static int skel_del_trans(struct ldb_module *module) +{ + return ldb_next_del_trans(module); +} + +static int skel_destructor(struct ldb_module *ctx) +{ + struct private_data *data; + + data = talloc_get_type(ldb_module_get_private(ctx), struct private_data); + + /* put your clean-up functions here */ + if (data->some_private_data) talloc_free(data->some_private_data); + + return 0; +} + +static int skel_request(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +static int skel_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + struct private_data *data; + + ldb = ldb_module_get_ctx(module); + + data = talloc(module, struct private_data); + if (data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + data->some_private_data = NULL; + ldb_module_set_private(module, data); + + talloc_set_destructor (module, skel_destructor); + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_skel_module_ops = { + .name = "skel", + .init_context = skel_init, + .search = skel_search, + .add = skel_add, + .modify = skel_modify, + .del = skel_delete, + .rename = skel_rename, + .request = skel_request, + .start_transaction = skel_start_trans, + .end_transaction = skel_end_trans, + .del_transaction = skel_del_trans, +}; + +int ldb_skel_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_skel_module_ops); +} diff --git a/lib/ldb/modules/sort.c b/lib/ldb/modules/sort.c new file mode 100644 index 00000000000..c6fce2d96e0 --- /dev/null +++ b/lib/ldb/modules/sort.c @@ -0,0 +1,360 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + + ** 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 server side sort control module + * + * Description: this module sorts the results of a search + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct opaque { + struct ldb_context *ldb; + const struct ldb_attrib_handler *h; + const char *attribute; + int reverse; + int result; +}; + +struct sort_context { + struct ldb_module *module; + + const char *attributeName; + const char *orderingRule; + int reverse; + + struct ldb_request *req; + struct ldb_message **msgs; + char **referrals; + unsigned int num_msgs; + unsigned int num_refs; + + const struct ldb_schema_attribute *a; + int sort_result; +}; + +static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) +{ + struct ldb_control **controls; + struct ldb_sort_resp_control *resp; + unsigned int i; + + if (*ctrls) { + controls = *ctrls; + for (i = 0; controls[i]; i++); + controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); + } else { + i = 0; + controls = talloc_array(mem_ctx, struct ldb_control *, 2); + } + if (! controls ) + return LDB_ERR_OPERATIONS_ERROR; + + *ctrls = controls; + + controls[i+1] = NULL; + controls[i] = talloc(controls, struct ldb_control); + if (! controls[i] ) + return LDB_ERR_OPERATIONS_ERROR; + + controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; + controls[i]->critical = 0; + + resp = talloc(controls[i], struct ldb_sort_resp_control); + if (! resp ) + return LDB_ERR_OPERATIONS_ERROR; + + resp->result = result; + resp->attr_desc = talloc_strdup(resp, desc); + + if (! resp->attr_desc ) + return LDB_ERR_OPERATIONS_ERROR; + + controls[i]->data = resp; + + return LDB_SUCCESS; +} + +static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) +{ + struct sort_context *ac = talloc_get_type(opaque, struct sort_context); + struct ldb_message_element *el1, *el2; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(ac->module); + + if (ac->sort_result != 0) { + /* an error occurred previously, + * let's exit the sorting by returning always 0 */ + return 0; + } + + el1 = ldb_msg_find_element(*msg1, ac->attributeName); + el2 = ldb_msg_find_element(*msg2, ac->attributeName); + + if (!el1 && el2) { + return 1; + } + if (el1 && !el2) { + return -1; + } + if (!el1 && !el2) { + return 0; + } + + if (ac->reverse) + return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], &el1->values[0]); + + return ac->a->syntax->comparison_fn(ldb, ac, &el1->values[0], &el2->values[0]); +} + +static int server_sort_results(struct sort_context *ac) +{ + struct ldb_context *ldb; + struct ldb_reply *ares; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + ac->a = ldb_schema_attribute_by_name(ldb, ac->attributeName); + ac->sort_result = 0; + + LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); + + if (ac->sort_result != LDB_SUCCESS) { + return ac->sort_result; + } + + for (i = 0; i < ac->num_msgs; i++) { + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_ENTRY; + ares->message = talloc_move(ares, &ac->msgs[i]); + + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + for (i = 0; i < ac->num_refs; i++) { + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_REFERRAL; + ares->referral = talloc_move(ares, &ac->referrals[i]); + + ret = ldb_module_send_referral(ac->req, ares->referral); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct sort_context *ac; + struct ldb_context *ldb; + int ret; + + ac = talloc_get_type(req->context, struct sort_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); + if (! ac->msgs) { + talloc_free(ares); + ldb_oom(ldb); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); + ac->num_msgs++; + ac->msgs[ac->num_msgs] = NULL; + + break; + + case LDB_REPLY_REFERRAL: + ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); + if (! ac->referrals) { + talloc_free(ares); + ldb_oom(ldb); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); + ac->num_refs++; + ac->referrals[ac->num_refs] = NULL; + + break; + + case LDB_REPLY_DONE: + + ret = server_sort_results(ac); + return ldb_module_done(ac->req, ares->controls, + ares->response, ret); + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int server_sort_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_control *control; + struct ldb_server_sort_control **sort_ctrls; + struct ldb_control **saved_controls; + struct ldb_control **controls; + struct ldb_request *down_req; + struct sort_context *ac; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* check if there's a server sort control */ + control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct sort_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); + if (!sort_ctrls) { + return LDB_ERR_PROTOCOL_ERROR; + } + + /* FIXME: we do not support more than one attribute for sorting right now */ + /* FIXME: we need to check if the attribute type exist or return an error */ + + if (sort_ctrls[1] != NULL) { + if (control->critical) { + + /* callback immediately */ + ret = build_response(req, &controls, + LDB_ERR_UNWILLING_TO_PERFORM, + "sort control is not complete yet"); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(req, controls, NULL, ret); + } else { + /* just pass the call down and don't do any sorting */ + return ldb_next_request(module, req); + } + } + + ac->attributeName = sort_ctrls[0]->attributeName; + ac->orderingRule = sort_ctrls[0]->orderingRule; + ac->reverse = sort_ctrls[0]->reverse; + + ret = ldb_build_search_req_ex(&down_req, ldb, ac, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->controls, + ac, + server_sort_search_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* save it locally and remove it from the list */ + /* we do not need to replace them later as we + * are keeping the original req intact */ + if (!ldb_save_controls(control, down_req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, down_req); +} + +static int server_sort_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "server_sort:" + "Unable to register control with rootdse!"); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_server_sort_module_ops = { + .name = "server_sort", + .search = server_sort_search, + .init_context = server_sort_init +}; + +int ldb_server_sort_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_server_sort_module_ops); +} diff --git a/lib/ldb/nssldb/README.txt b/lib/ldb/nssldb/README.txt new file mode 100644 index 00000000000..ddba62b3804 --- /dev/null +++ b/lib/ldb/nssldb/README.txt @@ -0,0 +1,34 @@ + +This test code requires a tdb that is configured for to use the asq module. +You can do that adding the following record to a tdb: + +dn: @MODULES +@LIST: asq + +Other modules can be used as well (like rdn_name for example) + +The uidNumber 0 and the gidNumber 0 are considered invalid. + +The user records should contain the followin attributes: +uid (required) the user name +userPassword (optional) the user password (if not present "LDB" is + returned in the password field) +uidNumber (required) the user uid +gidNumber (required) the user primary gid +gecos (optional) the GECOS +homeDirectory (required) the home directory +loginShell (required) the login shell +memberOf (required) all the groups the user is member of should + be reported here using their DNs. The + primary group as well. + +The group accounts should contain the following attributes: +cn (required) the group name +uesrPassword (optional) the group password (if not present "LDB" is + returned in the password field) +gidNumber (required) the group gid +member (optional) the DNs of the member users, also the ones + that have this group as primary + + +SSS diff --git a/lib/ldb/nssldb/ldb-grp.c b/lib/ldb/nssldb/ldb-grp.c new file mode 100644 index 00000000000..5e7556dc735 --- /dev/null +++ b/lib/ldb/nssldb/ldb-grp.c @@ -0,0 +1,429 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +extern struct _ldb_nss_context *_ldb_nss_ctx; + +const char *_ldb_nss_gr_attrs[] = { + "cn", + "userPassword", + "gidNumber", + NULL +}; + +const char *_ldb_nss_mem_attrs[] = { + "uid", + NULL +}; + +#define _NSS_LDB_ENOMEM(amem) \ + do { \ + if ( ! amem) { \ + errno = ENOMEM; \ + talloc_free(memctx); \ + return NSS_STATUS_UNAVAIL; \ + } \ + } while(0) + +/* This setgrent, getgrent, endgrent is not very efficient */ + +NSS_STATUS _nss_ldb_setgrent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->gr_cur = 0; + if (_ldb_nss_ctx->gr_res != NULL) { + talloc_free(_ldb_nss_ctx->gr_res); + _ldb_nss_ctx->gr_res = NULL; + } + + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &_ldb_nss_ctx->gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + _LDB_NSS_GRENT_FILTER); + if (ret != LDB_SUCCESS) { + return NSS_STATUS_UNAVAIL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_endgrent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->gr_cur = 0; + if (_ldb_nss_ctx->gr_res) { + talloc_free(_ldb_nss_ctx->gr_res); + _ldb_nss_ctx->gr_res = NULL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + struct ldb_result *res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + *errnop = 0; + + if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { + /* already returned all entries */ + return NSS_STATUS_NOTFOUND; + } + + res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); + if ( ! res) { + errno = *errnop = ENOMEM; + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + return NSS_STATUS_UNAVAIL; + } + + ret = _ldb_nss_group_request(&res, + _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + talloc_free(res); + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + return ret; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], + res); + + talloc_free(res); + + if (ret != NSS_STATUS_SUCCESS) { + if (ret != NSS_STATUS_TRYAGAIN) { + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + } + return ret; + } + + /* this entry is ok, increment counter to nex entry */ + _ldb_nss_ctx->gr_cur++; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + TALLOC_CTX *ctx; + struct ldb_result *gr_res; + struct ldb_result *mem_res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + ctx = talloc_new(_ldb_nss_ctx->ldb); + if ( ! ctx) { + *errnop = errno = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(ctx, gr_res); + + /* if none found return */ + if (gr_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (gr_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + mem_res = talloc_zero(ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + gr_res->msgs[0]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + gr_res->msgs[0], + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; +done: + talloc_free(ctx); + return ret; +} + +NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + TALLOC_CTX *ctx; + struct ldb_result *gr_res; + struct ldb_result *mem_res; + + if (gid == 0) { /* we don't serve root gid by policy */ + *errnop = errno = ENOENT; + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + ctx = talloc_new(_ldb_nss_ctx->ldb); + if ( ! ctx) { + *errnop = errno = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(ctx, gr_res); + + /* if none found return */ + if (gr_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (gr_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + mem_res = talloc_zero(ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + gr_res->msgs[0]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + gr_res->msgs[0], + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; +done: + talloc_free(ctx); + return ret; +} + +NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) +{ + int ret; + char *filter; + const char * attrs[] = { "uidNumber", "gidNumber", NULL }; + struct ldb_result *uid_res; + struct ldb_result *mem_res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this name */ + filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &uid_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(mem_res, uid_res); + + /* if none found return */ + if (uid_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (uid_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + uid_res->msgs[0]->dn, + attrs, + "memberOf"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_initgr(group, + limit, + start, + size, + groups, + errnop, + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; + +done: + talloc_free(mem_res); + return ret; +} diff --git a/lib/ldb/nssldb/ldb-nss.c b/lib/ldb/nssldb/ldb-nss.c new file mode 100644 index 00000000000..92b0635561e --- /dev/null +++ b/lib/ldb/nssldb/ldb-nss.c @@ -0,0 +1,395 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +struct _ldb_nss_context *_ldb_nss_ctx = NULL; + +NSS_STATUS _ldb_nss_init(void) +{ + int ret; + + pid_t mypid = getpid(); + + if (_ldb_nss_ctx != NULL) { + if (_ldb_nss_ctx->pid == mypid) { + /* already initialized */ + return NSS_STATUS_SUCCESS; + } else { + /* we are in a forked child now, reinitialize */ + talloc_free(_ldb_nss_ctx); + _ldb_nss_ctx = NULL; + } + } + + _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); + if (_ldb_nss_ctx == NULL) { + return NSS_STATUS_UNAVAIL; + } + + _ldb_nss_ctx->pid = mypid; + + _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); + if (_ldb_nss_ctx->ldb == NULL) { + goto failed; + } + + ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + + _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); + if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { + goto failed; + } + + _ldb_nss_ctx->pw_cur = 0; + _ldb_nss_ctx->pw_res = NULL; + _ldb_nss_ctx->gr_cur = 0; + _ldb_nss_ctx->gr_res = NULL; + + return NSS_STATUS_SUCCESS; + +failed: + /* talloc_free(_ldb_nss_ctx); */ + _ldb_nss_ctx = NULL; + return NSS_STATUS_UNAVAIL; +} + +NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *msg) +{ + int len; + int bufpos; + const char *tmp; + + bufpos = 0; + + /* get username */ + tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_passwd = &buffer[bufpos]; + bufpos += len; + + /* this backend never serves an uid 0 user */ + result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); + if (result->pw_uid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); + if (result->pw_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* get gecos */ + tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_gecos = &buffer[bufpos]; + bufpos += len; + + /* get homeDirectory */ + tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_dir = &buffer[bufpos]; + bufpos += len; + + /* get shell */ + tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_shell = &buffer[bufpos]; + bufpos += len; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_group(struct group *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *group, + struct ldb_result *members) +{ + const char *tmp; + size_t len; + size_t bufpos; + size_t lsize; + unsigned int i; + + bufpos = 0; + + /* get group name */ + tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_passwd = &buffer[bufpos]; + bufpos += len; + + result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); + if (result->gr_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* check if there is enough memory for the list of pointers */ + lsize = (members->count + 1) * sizeof(char *); + + /* align buffer on pointer boundary */ + bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); + if ((buflen - bufpos) < lsize) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + + result->gr_mem = (char **)&buffer[bufpos]; + bufpos += lsize; + + for (i = 0; i < members->count; i++) { + tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_mem[i] = &buffer[bufpos]; + bufpos += len; + } + + result->gr_mem[i] = NULL; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_initgr(gid_t group, + long int limit, + long int *start, + long int *size, + gid_t **groups, + int *errnop, + struct ldb_result *grlist) +{ + NSS_STATUS ret; + unsigned int i; + + for (i = 0; i < grlist->count; i++) { + + if (limit && (*start > limit)) { + /* TODO: warn no all groups were reported */ + *errnop = 0; + ret = NSS_STATUS_SUCCESS; + goto done; + } + + if (*start == *size) { + /* buffer full, enlarge it */ + long int gs; + gid_t *gm; + + gs = (*size) + 32; + if (limit && (gs > limit)) { + gs = limit; + } + + gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); + if ( ! gm) { + *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + *groups = gm; + *size = gs; + } + + (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); + if ((*groups)[*start] == 0 || (*groups)[*start] == group) { + /* skip root group or primary group */ + continue; + } + (*start)++; + + } + + *errnop = 0; + ret = NSS_STATUS_SUCCESS; +done: + return ret; +} + +#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) + +NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, + struct ldb_dn *group_dn, + const char * const *attrs, + const char *mattr) +{ + struct ldb_control **ctrls; + struct ldb_control *ctrl; + struct ldb_asq_control *asqc; + struct ldb_request *req; + int ret; + struct ldb_result *res = *_res; + + ctrls = talloc_array(res, struct ldb_control *, 2); + _LDB_NSS_ALLOC_CHECK(ctrls); + + ctrl = talloc(ctrls, struct ldb_control); + _LDB_NSS_ALLOC_CHECK(ctrl); + + asqc = talloc(ctrl, struct ldb_asq_control); + _LDB_NSS_ALLOC_CHECK(asqc); + + asqc->source_attribute = talloc_strdup(asqc, mattr); + _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); + + asqc->request = 1; + asqc->src_attr_len = strlen(asqc->source_attribute); + ctrl->oid = LDB_CONTROL_ASQ_OID; + ctrl->critical = 1; + ctrl->data = asqc; + ctrls[0] = ctrl; + ctrls[1] = NULL; + + ret = ldb_build_search_req( + &req, + _ldb_nss_ctx->ldb, + res, + group_dn, + LDB_SCOPE_BASE, + "(objectClass=*)", + attrs, + ctrls, + res, + ldb_search_default_callback); + + if (ret != LDB_SUCCESS) { + errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); + + ret = ldb_request(_ldb_nss_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } else { + talloc_free(req); + return NSS_STATUS_UNAVAIL; + } + + talloc_free(req); + return NSS_STATUS_SUCCESS; +} + diff --git a/lib/ldb/nssldb/ldb-nss.h b/lib/ldb/nssldb/ldb-nss.h new file mode 100644 index 00000000000..583876fea67 --- /dev/null +++ b/lib/ldb/nssldb/ldb-nss.h @@ -0,0 +1,84 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef _LDB_NSS +#define _LDB_NSS + +#include "includes.h" +#include "ldb/include/includes.h" + +#include +#include +#include + +#define _LDB_NSS_URL "etc/users.ldb" +#define _LDB_NSS_BASEDN "CN=Users,CN=System" +#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" +#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" +#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" + +#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" +#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" +#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" + +typedef enum nss_status NSS_STATUS; + +struct _ldb_nss_context { + + pid_t pid; + + struct ldb_context *ldb; + struct ldb_dn *base; + + int pw_cur; + struct ldb_result *pw_res; + + int gr_cur; + struct ldb_result *gr_res; +}; + +NSS_STATUS _ldb_nss_init(void); + +NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *msg); + +NSS_STATUS _ldb_nss_fill_group(struct group *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *group, + struct ldb_result *members); + +NSS_STATUS _ldb_nss_fill_initgr(gid_t group, + long int limit, + long int *start, + long int *size, + gid_t **groups, + int *errnop, + struct ldb_result *grlist); + +NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, + struct ldb_dn *group_dn, + const char * const *attrs, + const char *mattr); + +#endif /* _LDB_NSS */ diff --git a/lib/ldb/nssldb/ldb-pwd.c b/lib/ldb/nssldb/ldb-pwd.c new file mode 100644 index 00000000000..6ab103a6fed --- /dev/null +++ b/lib/ldb/nssldb/ldb-pwd.c @@ -0,0 +1,242 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +extern struct _ldb_nss_context *_ldb_nss_ctx; + +const char *_ldb_nss_pw_attrs[] = { + "uid", + "userPassword", + "uidNumber", + "gidNumber", + "gecos", + "homeDirectory", + "loginShell", + NULL +}; + +NSS_STATUS _nss_ldb_setpwent(void) +{ + int ret; + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur = 0; + if (_ldb_nss_ctx->pw_res != NULL) { + talloc_free(_ldb_nss_ctx->pw_res); + _ldb_nss_ctx->pw_res = NULL; + } + + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &_ldb_nss_ctx->pw_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + _LDB_NSS_PWENT_FILTER); + if (ret != LDB_SUCCESS) { + return NSS_STATUS_UNAVAIL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_endpwent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur = 0; + if (_ldb_nss_ctx->pw_res) { + talloc_free(_ldb_nss_ctx->pw_res); + _ldb_nss_ctx->pw_res = NULL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, + char *buffer, + int buflen, + int *errnop) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + *errnop = 0; + + if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { + /* already returned all entries */ + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur++; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + struct ldb_result *res; + + if (uid == 0) { /* we don't serve root uid by policy */ + *errnop = errno = ENOENT; + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* if none found return */ + if (res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* fill in the passwd struct */ + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + res->msgs[0]); + +done: + talloc_free(filter); + talloc_free(res); + return ret; +} + +NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + struct ldb_result *res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + /* build the filter for this name */ + filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* if none found return */ + if (res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* fill in the passwd struct */ + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + res->msgs[0]); + +done: + talloc_free(filter); + talloc_free(res); + return ret; +} + diff --git a/lib/ldb/pyldb-util.pc.in b/lib/ldb/pyldb-util.pc.in new file mode 100644 index 00000000000..348ae8b95d6 --- /dev/null +++ b/lib/ldb/pyldb-util.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +modulesdir=@LDB_MODULESDIR@ + +Name: pyldb-util +Description: Python bindings for LDB +Version: @PACKAGE_VERSION@ +Requires: ldb +Libs: @LIB_RPATH@ -L${libdir} -lpyldb-util +Cflags: -I${includedir} +URL: http://ldb.samba.org/ diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c new file mode 100644 index 00000000000..e2a2e7180e1 --- /dev/null +++ b/lib/ldb/pyldb.c @@ -0,0 +1,3302 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb. + + Copyright (C) 2005,2006 Tim Potter + Copyright (C) 2006 Simo Sorce + Copyright (C) 2007-2010 Jelmer Vernooij + Copyright (C) 2009-2010 Matthias Dieter Wallnöfer + Copyright (C) 2009-2011 Andrew Tridgell + Copyright (C) 2009-2011 Andrew Bartlett + + ** 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 . +*/ + +#include +#include +#include "ldb_private.h" +#include "pyldb.h" + +void initldb(void); +static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); +static PyObject *PyExc_LdbError; + +staticforward PyTypeObject PyLdbControl; +staticforward PyTypeObject PyLdbResult; +staticforward PyTypeObject PyLdbMessage; +staticforward PyTypeObject PyLdbModule; +staticforward PyTypeObject PyLdbDn; +staticforward PyTypeObject PyLdb; +staticforward PyTypeObject PyLdbMessageElement; +staticforward PyTypeObject PyLdbTree; +static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); +static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); +static struct ldb_message_element *PyObject_AsMessageElement( + TALLOC_CTX *mem_ctx, + PyObject *set_obj, + unsigned int flags, + const char *attr_name); + +/* There's no Py_ssize_t in 2.4, apparently */ +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 +typedef int Py_ssize_t; +typedef inquiry lenfunc; +typedef intargfunc ssizeargfunc; +#endif + +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1)) + + + +static PyObject *py_ldb_control_str(PyLdbControlObject *self) +{ + if (self->data != NULL) { + char* control = ldb_control_to_string(self->mem_ctx, self->data); + if (control == NULL) { + PyErr_NoMemory(); + return NULL; + } + return PyString_FromString(control); + } else { + return PyString_FromFormat("ldb control"); + } +} + +static void py_ldb_control_dealloc(PyLdbControlObject *self) +{ + if (self->mem_ctx != NULL) { + talloc_free(self->mem_ctx); + } + self->data = NULL; + self->ob_type->tp_free(self); +} + +static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self) +{ + return PyString_FromString(self->data->oid); +} + +static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self) +{ + return PyBool_FromLong(self->data->critical); +} + +static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) +{ + if (PyObject_IsTrue(value)) { + self->data->critical = true; + } else { + self->data->critical = false; + } + return 0; +} + +static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + char *data = NULL; + const char * const kwnames[] = { "ldb", "data", NULL }; + struct ldb_control *parsed_controls; + PyLdbControlObject *ret; + PyObject *py_ldb; + TALLOC_CTX *mem_ctx; + struct ldb_context *ldb_ctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os", + discard_const_p(char *, kwnames), + &py_ldb, &data)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ldb_ctx = PyLdb_AsLdbContext(py_ldb); + parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); + + if (!parsed_controls) { + talloc_free(mem_ctx); + PyErr_SetString(PyExc_ValueError, "unable to parse control string"); + return NULL; + } + + ret = PyObject_New(PyLdbControlObject, type); + if (ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + ret->mem_ctx = mem_ctx; + + ret->data = talloc_move(mem_ctx, &parsed_controls); + if (ret->data == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + return (PyObject *)ret; +} + +static PyGetSetDef py_ldb_control_getset[] = { + { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL }, + { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL }, + { NULL } +}; + +static PyTypeObject PyLdbControl = { + .tp_name = "ldb.control", + .tp_dealloc = (destructor)py_ldb_control_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbControlObject), + .tp_getset = py_ldb_control_getset, + .tp_doc = "LDB control.", + .tp_str = (reprfunc)py_ldb_control_str, + .tp_new = py_ldb_control_new, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) +{ + if (ret == LDB_ERR_PYTHON_EXCEPTION) + return; /* Python exception should already be set, just keep that */ + + PyErr_SetObject(error, + Py_BuildValue(discard_const_p(char, "(i,s)"), ret, + ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); +} + +static PyObject *PyObject_FromLdbValue(struct ldb_val *val) +{ + return PyString_FromStringAndSize((const char *)val->data, val->length); +} + +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ +static PyObject *PyLdbControl_FromControl(struct ldb_control *control) +{ + TALLOC_CTX *ctl_ctx = talloc_new(NULL); + PyLdbControlObject *ctrl; + if (ctl_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); + if (ctrl == NULL) { + talloc_free(ctl_ctx); + PyErr_NoMemory(); + return NULL; + } + ctrl->mem_ctx = ctl_ctx; + ctrl->data = talloc_steal(ctrl->mem_ctx, control); + if (ctrl->data == NULL) { + Py_DECREF(ctrl); + PyErr_NoMemory(); + return NULL; + } + return (PyObject*) ctrl; +} + +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ +static PyObject *PyLdbResult_FromResult(struct ldb_result *result) +{ + PyLdbResultObject *ret; + PyObject *list, *controls, *referals; + Py_ssize_t i; + + if (result == NULL) { + Py_RETURN_NONE; + } + + ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + list = PyList_New(result->count); + if (list == NULL) { + PyErr_NoMemory(); + Py_DECREF(ret); + return NULL; + } + + for (i = 0; i < result->count; i++) { + PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); + } + + ret->mem_ctx = talloc_new(NULL); + if (ret->mem_ctx == NULL) { + Py_DECREF(list); + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + + ret->msgs = list; + + if (result->controls) { + controls = PyList_New(1); + if (controls == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + for (i=0; result->controls[i]; i++) { + PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); + if (ctrl == NULL) { + Py_DECREF(ret); + Py_DECREF(controls); + PyErr_NoMemory(); + return NULL; + } + PyList_SetItem(controls, i, ctrl); + } + } else { + /* + * No controls so we keep an empty list + */ + controls = PyList_New(0); + if (controls == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + } + + ret->controls = controls; + + i = 0; + + while (result->refs && result->refs[i]) { + i++; + } + + referals = PyList_New(i); + if (referals == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + + for (i = 0;result->refs && result->refs[i]; i++) { + PyList_SetItem(referals, i, PyString_FromString(result->refs[i])); + } + ret->referals = referals; + return (PyObject *)ret; +} + +/** + * Create a LDB Result from a Python object. + * If conversion fails, NULL will be returned and a Python exception set. + * + * @param mem_ctx Memory context in which to allocate the LDB Result + * @param obj Python object to convert + * @return a ldb_result, or NULL if the conversion failed + */ +static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, + PyObject *obj) +{ + struct ldb_result *res; + Py_ssize_t i; + + if (obj == Py_None) + return NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + res->count = PyList_Size(obj); + res->msgs = talloc_array(res, struct ldb_message *, res->count); + for (i = 0; i < res->count; i++) { + PyObject *item = PyList_GetItem(obj, i); + res->msgs[i] = PyLdbMessage_AsMessage(item); + } + return res; +} + +static PyObject *py_ldb_dn_validate(PyLdbDnObject *self) +{ + return PyBool_FromLong(ldb_dn_validate(self->dn)); +} + +static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self) +{ + return PyBool_FromLong(ldb_dn_is_valid(self->dn)); +} + +static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self) +{ + return PyBool_FromLong(ldb_dn_is_special(self->dn)); +} + +static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self) +{ + return PyBool_FromLong(ldb_dn_is_null(self->dn)); +} + +static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self) +{ + return PyString_FromString(ldb_dn_get_casefold(self->dn)); +} + +static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) +{ + return PyString_FromString(ldb_dn_get_linearized(self->dn)); +} + +static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self) +{ + return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn)); +} + +static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self) +{ + return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); +} + +static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "mode", NULL }; + int mode = 1; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", + discard_const_p(char *, kwnames), + &mode)) + return NULL; + return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); +} + +static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + const struct ldb_val *val; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + val = ldb_dn_get_extended_component(self->dn, name); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyString_FromStringAndSize((const char *)val->data, val->length); +} + +static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + PyObject *value; + int err; + + if (!PyArg_ParseTuple(args, "sO", &name, &value)) + return NULL; + + if (value == Py_None) { + err = ldb_dn_set_extended_component(self->dn, name, NULL); + } else { + struct ldb_val val; + if (!PyString_Check(value)) { + PyErr_SetString(PyExc_TypeError, "Expected a string argument"); + return NULL; + } + val.data = (uint8_t *)PyString_AsString(value); + val.length = PyString_Size(value); + err = ldb_dn_set_extended_component(self->dn, name, &val); + } + + if (err != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) +{ + return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn)))); +} + +static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args) +{ + char *name; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + return ldb_dn_check_special(self->dn, name)?Py_True:Py_False; +} + +static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2) +{ + int ret; + ret = ldb_dn_compare(dn1->dn, dn2->dn); + if (ret < 0) ret = -1; + if (ret > 0) ret = 1; + return ret; +} + +static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self) +{ + struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self); + struct ldb_dn *parent; + PyLdbDnObject *py_ret; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + parent = ldb_dn_get_parent(mem_ctx, dn); + if (parent == NULL) { + talloc_free(mem_ctx); + Py_RETURN_NONE; + } + + py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + py_ret->mem_ctx = mem_ctx; + py_ret->dn = parent; + return (PyObject *)py_ret; +} + +#define dn_ldb_ctx(dn) ((struct ldb_context *)dn) + +static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args) +{ + PyObject *py_other; + struct ldb_dn *dn, *other; + if (!PyArg_ParseTuple(args, "O", &py_other)) + return NULL; + + dn = PyLdbDn_AsDn((PyObject *)self); + + if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other)) + return NULL; + + return ldb_dn_add_child(dn, other)?Py_True:Py_False; +} + +static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args) +{ + PyObject *py_other; + struct ldb_dn *other, *dn; + if (!PyArg_ParseTuple(args, "O", &py_other)) + return NULL; + + dn = PyLdbDn_AsDn((PyObject *)self); + + if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other)) + return NULL; + + return ldb_dn_add_base(dn, other)?Py_True:Py_False; +} + +static PyMethodDef py_ldb_dn_methods[] = { + { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, + "S.validate() -> bool\n" + "Validate DN is correct." }, + { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS, + "S.is_valid() -> bool\n" }, + { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS, + "S.is_special() -> bool\n" + "Check whether this is a special LDB DN." }, + { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS, + "Check whether this is a null DN." }, + { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, + NULL }, + { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS, + NULL }, + { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, + "S.canonical_str() -> string\n" + "Canonical version of this DN (like a posix path)." }, + { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, + "S.canonical_ex_str() -> string\n" + "Canonical version of this DN (like a posix path, with terminating newline)." }, + { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS, + "S.extended_str(mode=1) -> string\n" + "Extended version of this DN" }, + { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, + "S.parent() -> dn\n" + "Get the parent for this DN." }, + { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, + "S.add_child(dn) -> None\n" + "Add a child DN to this DN." }, + { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS, + "S.add_base(dn) -> None\n" + "Add a base DN to this DN." }, + { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, + "S.check_special(name) -> bool\n\n" + "Check if name is a special DN name"}, + { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, + "S.get_extended_component(name) -> string\n\n" + "returns a DN extended component as a binary string"}, + { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, + "S.set_extended_component(name, value) -> string\n\n" + "set a DN extended component as a binary string"}, + { NULL } +}; + +static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) +{ + return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self)); +} + +static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other) +{ + struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), + *other; + PyLdbDnObject *py_ret; + + if (!PyObject_AsDn(NULL, py_other, NULL, &other)) + return NULL; + + py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = talloc_new(NULL); + py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); + ldb_dn_add_child(py_ret->dn, other); + return (PyObject *)py_ret; +} + +static PySequenceMethods py_ldb_dn_seq = { + .sq_length = (lenfunc)py_ldb_dn_len, + .sq_concat = (binaryfunc)py_ldb_dn_concat, +}; + +static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + struct ldb_dn *ret; + char *str; + PyObject *py_ldb; + struct ldb_context *ldb_ctx; + TALLOC_CTX *mem_ctx; + PyLdbDnObject *py_ret; + const char * const kwnames[] = { "ldb", "dn", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os", + discard_const_p(char *, kwnames), + &py_ldb, &str)) + return NULL; + + ldb_ctx = PyLdb_AsLdbContext(py_ldb); + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = ldb_dn_new(mem_ctx, ldb_ctx, str); + if (!ldb_dn_validate(ret)) { + talloc_free(mem_ctx); + PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); + return NULL; + } + + py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0); + if (ret == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = mem_ctx; + py_ret->dn = ret; + return (PyObject *)py_ret; +} + +static void py_ldb_dn_dealloc(PyLdbDnObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbDn = { + .tp_name = "ldb.Dn", + .tp_methods = py_ldb_dn_methods, + .tp_str = (reprfunc)py_ldb_dn_get_linearized, + .tp_repr = (reprfunc)py_ldb_dn_repr, + .tp_compare = (cmpfunc)py_ldb_dn_compare, + .tp_as_sequence = &py_ldb_dn_seq, + .tp_doc = "A LDB distinguished name.", + .tp_new = py_ldb_dn_new, + .tp_dealloc = (destructor)py_ldb_dn_dealloc, + .tp_basicsize = sizeof(PyLdbDnObject), + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +/* Debug */ +static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); +static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) +{ + PyObject *fn = (PyObject *)context; + PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap)); +} + +static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args) +{ + PyObject *cb; + + if (!PyArg_ParseTuple(args, "O", &cb)) + return NULL; + + Py_INCREF(cb); + /* FIXME: Where do we DECREF cb ? */ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self)); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args) +{ + unsigned int perms; + if (!PyArg_ParseTuple(args, "I", &perms)) + return NULL; + + ldb_set_create_perms(PyLdb_AsLdbContext(self), perms); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) +{ + char *modules_dir; + if (!PyArg_ParseTuple(args, "s", &modules_dir)) + return NULL; + + ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_start(PyLdbObject *self) +{ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_commit(PyLdbObject *self) +{ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self) +{ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_cancel(PyLdbObject *self) +{ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self) +{ + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_repr(PyLdbObject *self) +{ + return PyString_FromFormat(""); +} + +static PyObject *py_ldb_get_root_basedn(PyLdbObject *self) +{ + struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return PyLdbDn_FromDn(dn); +} + + +static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) +{ + struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return PyLdbDn_FromDn(dn); +} + +static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) +{ + struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return PyLdbDn_FromDn(dn); +} + +static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) +{ + struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return PyLdbDn_FromDn(dn); +} + +static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, + const char *paramname) +{ + const char **ret; + Py_ssize_t i; + if (!PyList_Check(list)) { + PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); + return NULL; + } + ret = talloc_array(NULL, const char *, PyList_Size(list)+1); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (i = 0; i < PyList_Size(list); i++) { + PyObject *item = PyList_GetItem(list, i); + if (!PyString_Check(item)) { + PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); + return NULL; + } + ret[i] = talloc_strndup(ret, PyString_AsString(item), + PyString_Size(item)); + } + ret[i] = NULL; + return ret; +} + +static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "url", "flags", "options", NULL }; + char *url = NULL; + PyObject *py_options = Py_None; + const char **options; + unsigned int flags = 0; + int ret; + struct ldb_context *ldb; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", + discard_const_p(char *, kwnames), + &url, &flags, &py_options)) + return -1; + + ldb = PyLdb_AsLdbContext(self); + + if (py_options == Py_None) { + options = NULL; + } else { + options = PyList_AsStringList(ldb, py_options, "options"); + if (options == NULL) + return -1; + } + + if (url != NULL) { + ret = ldb_connect(ldb, url, flags, options); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb); + return -1; + } + } + + talloc_free(options); + return 0; +} + +static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyLdbObject *ret; + struct ldb_context *ldb; + ret = (PyLdbObject *)type->tp_alloc(type, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ldb = ldb_init(ret->mem_ctx, NULL); + + if (ldb == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret->ldb_ctx = ldb; + return (PyObject *)ret; +} + +static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + char *url; + unsigned int flags = 0; + PyObject *py_options = Py_None; + int ret; + const char **options; + const char * const kwnames[] = { "url", "flags", "options", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO", + discard_const_p(char *, kwnames), + &url, &flags, &py_options)) + return NULL; + + if (py_options == Py_None) { + options = NULL; + } else { + options = PyList_AsStringList(NULL, py_options, "options"); + if (options == NULL) + return NULL; + } + + ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options); + talloc_free(options); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_msg; + PyObject *py_controls = Py_None; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + struct ldb_control **parsed_controls; + struct ldb_message *msg; + int ret; + TALLOC_CTX *mem_ctx; + bool validate=true; + const char * const kwnames[] = { "message", "controls", "validate", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", + discard_const_p(char *, kwnames), + &py_msg, &py_controls, &validate)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = PyLdb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (!PyLdbMessage_Check(py_msg)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); + talloc_free(mem_ctx); + return NULL; + } + msg = PyLdbMessage_AsMessage(py_msg); + + if (validate) { + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + talloc_free(mem_ctx); + return NULL; + } + } + + ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + if (ldb_ctx->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); + } + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + + +/** + * Obtain a ldb message from a Python Dictionary object. + * + * @param mem_ctx Memory context + * @param py_obj Python Dictionary object + * @param ldb_ctx LDB context + * @param mod_flags Flags to be set on every message element + * @return ldb_message on success or NULL on failure + */ +static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, + PyObject *py_obj, + struct ldb_context *ldb_ctx, + unsigned int mod_flags) +{ + struct ldb_message *msg; + unsigned int msg_pos = 0; + Py_ssize_t dict_pos = 0; + PyObject *key, *value; + struct ldb_message_element *msg_el; + PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); + + msg = ldb_msg_new(mem_ctx); + msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); + + if (dn_value) { + if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { + PyErr_SetString(PyExc_TypeError, "unable to import dn object"); + return NULL; + } + if (msg->dn == NULL) { + PyErr_SetString(PyExc_TypeError, "dn set but not found"); + return NULL; + } + } else { + PyErr_SetString(PyExc_TypeError, "no dn set"); + return NULL; + } + + while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { + char *key_str = PyString_AsString(key); + if (strcmp(key_str, "dn") != 0) { + msg_el = PyObject_AsMessageElement(msg->elements, value, + mod_flags, key_str); + if (msg_el == NULL) { + PyErr_SetString(PyExc_TypeError, "unable to import element"); + return NULL; + } + memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); + msg_pos++; + } + } + + msg->num_elements = msg_pos; + + return msg; +} + +static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_obj; + int ret; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + struct ldb_message *msg = NULL; + PyObject *py_controls = Py_None; + TALLOC_CTX *mem_ctx; + struct ldb_control **parsed_controls; + const char * const kwnames[] = { "message", "controls", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_obj, &py_controls)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = PyLdb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (PyLdbMessage_Check(py_obj)) { + msg = PyLdbMessage_AsMessage(py_obj); + } else if (PyDict_Check(py_obj)) { + msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); + } else { + PyErr_SetString(PyExc_TypeError, + "Dictionary or LdbMessage object expected!"); + } + + if (!msg) { + /* we should have a PyErr already set */ + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + if (ldb_ctx->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); + } + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_dn; + struct ldb_dn *dn; + int ret; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + PyObject *py_controls = Py_None; + TALLOC_CTX *mem_ctx; + struct ldb_control **parsed_controls; + const char * const kwnames[] = { "dn", "controls", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_dn, &py_controls)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = PyLdb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + if (ldb_ctx->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); + } + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_dn1, *py_dn2; + struct ldb_dn *dn1, *dn2; + int ret; + struct ldb_context *ldb; + TALLOC_CTX *mem_ctx; + PyObject *py_controls = Py_None; + struct ldb_control **parsed_controls; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; + + ldb_ctx = PyLdb_AsLdbContext(self); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", + discard_const_p(char *, kwnames), + &py_dn1, &py_dn2, &py_controls)) + return NULL; + + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb = PyLdb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + + if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) { + talloc_free(mem_ctx); + return NULL; + } + + if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) { + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + if (ldb_ctx->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); + } + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args) +{ + char *attribute, *syntax; + unsigned int flags; + int ret; + if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax)) + return NULL; + + ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); + + Py_RETURN_NONE; +} + +static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) +{ + if (ldif == NULL) { + Py_RETURN_NONE; + } else { + /* We don't want this attached to the 'ldb' any more */ + return Py_BuildValue(discard_const_p(char, "(iO)"), + ldif->changetype, + PyLdbMessage_FromMessage(ldif->msg)); + } +} + + +static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) +{ + int changetype; + PyObject *py_msg; + struct ldb_ldif ldif; + PyObject *ret; + char *string; + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) + return NULL; + + if (!PyLdbMessage_Check(py_msg)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); + return NULL; + } + + ldif.msg = PyLdbMessage_AsMessage(py_msg); + ldif.changetype = changetype; + + mem_ctx = talloc_new(NULL); + + string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif); + if (!string) { + PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); + return NULL; + } + + ret = PyString_FromString(string); + + talloc_free(mem_ctx); + + return ret; +} + +static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) +{ + PyObject *list; + struct ldb_ldif *ldif; + const char *s; + + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (!mem_ctx) { + Py_RETURN_NONE; + } + + list = PyList_New(0); + while (s && *s != '\0') { + ldif = ldb_ldif_read_string(self->ldb_ctx, &s); + talloc_steal(mem_ctx, ldif); + if (ldif) { + PyList_Append(list, ldb_ldif_to_pyobject(ldif)); + } else { + PyErr_SetString(PyExc_ValueError, "unable to parse ldif string"); + talloc_free(mem_ctx); + return NULL; + } + } + talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */ + return PyObject_GetIter(list); +} + +static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) +{ + int ldb_ret; + PyObject *py_msg_old; + PyObject *py_msg_new; + struct ldb_message *diff; + struct ldb_context *ldb; + PyObject *py_ret; + + if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) + return NULL; + + if (!PyLdbMessage_Check(py_msg_old)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message"); + return NULL; + } + + if (!PyLdbMessage_Check(py_msg_new)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message"); + return NULL; + } + + ldb = PyLdb_AsLdbContext(self); + ldb_ret = ldb_msg_difference(ldb, ldb, + PyLdbMessage_AsMessage(py_msg_old), + PyLdbMessage_AsMessage(py_msg_new), + &diff); + if (ldb_ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); + return NULL; + } + + py_ret = PyLdbMessage_FromMessage(diff); + + talloc_unlink(ldb, diff); + + return py_ret; +} + +static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args) +{ + const struct ldb_schema_attribute *a; + struct ldb_val old_val; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx; + PyObject *ret; + char *element_name; + PyObject *val; + + if (!PyArg_ParseTuple(args, "sO", &element_name, &val)) + return NULL; + + mem_ctx = talloc_new(NULL); + + old_val.data = (uint8_t *)PyString_AsString(val); + old_val.length = PyString_Size(val); + + a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name); + + if (a == NULL) { + Py_RETURN_NONE; + } + + if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) { + talloc_free(mem_ctx); + Py_RETURN_NONE; + } + + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; +} + +static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base = Py_None; + int scope = LDB_SCOPE_DEFAULT; + char *expr = NULL; + PyObject *py_attrs = Py_None; + PyObject *py_controls = Py_None; + const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL }; + int ret; + struct ldb_result *res; + struct ldb_request *req; + const char **attrs; + struct ldb_context *ldb_ctx; + struct ldb_control **parsed_controls; + struct ldb_dn *base; + PyObject *py_ret; + TALLOC_CTX *mem_ctx; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", + discard_const_p(char *, kwnames), + &py_base, &scope, &expr, &py_attrs, &py_controls)) + return NULL; + + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = PyLdb_AsLdbContext(self); + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs"); + if (attrs == NULL) { + talloc_free(mem_ctx); + return NULL; + } + } + + if (py_base == Py_None) { + base = ldb_get_default_basedn(ldb_ctx); + } else { + if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) { + talloc_free(attrs); + return NULL; + } + } + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + res = talloc_zero(mem_ctx, struct ldb_result); + if (res == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, + base, + scope, + expr, + attrs, + parsed_controls, + res, + ldb_search_default_callback, + NULL); + + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + talloc_steal(req, attrs); + + ret = ldb_request(ldb_ctx, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + py_ret = PyLdbResult_FromResult(res); + + talloc_free(mem_ctx); + + return py_ret; +} + +static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) +{ + char *name; + void *data; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + data = ldb_get_opaque(PyLdb_AsLdbContext(self), name); + + if (data == NULL) + Py_RETURN_NONE; + + /* FIXME: More interpretation */ + + return Py_True; +} + +static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) +{ + char *name; + PyObject *data; + + if (!PyArg_ParseTuple(args, "sO", &name, &data)) + return NULL; + + /* FIXME: More interpretation */ + + ldb_set_opaque(PyLdb_AsLdbContext(self), name, data); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_modules(PyLdbObject *self) +{ + struct ldb_context *ldb = PyLdb_AsLdbContext(self); + PyObject *ret = PyList_New(0); + struct ldb_module *mod; + + for (mod = ldb->modules; mod; mod = mod->next) { + PyList_Append(ret, PyLdbModule_FromModule(mod)); + } + + return ret; +} + +static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) +{ + struct ldb_context *ldb = PyLdb_AsLdbContext(self); + int type, ret; + uint64_t value; + + if (!PyArg_ParseTuple(args, "i", &type)) + return NULL; + + /* FIXME: More interpretation */ + + ret = ldb_sequence_number(ldb, type, &value); + + if (ret != LDB_SUCCESS) { + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); + return NULL; + } + return PyLong_FromLongLong(value); +} +static PyMethodDef py_ldb_methods[] = { + { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, + "S.set_debug(callback) -> None\n" + "Set callback for LDB debug messages.\n" + "The callback should accept a debug level and debug text." }, + { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, + "S.set_create_perms(mode) -> None\n" + "Set mode to use when creating new LDB files." }, + { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS, + "S.set_modules_dir(path) -> None\n" + "Set path LDB should search for modules" }, + { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, + "S.transaction_start() -> None\n" + "Start a new transaction." }, + { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, + "S.transaction_prepare_commit() -> None\n" + "prepare to commit a new transaction (2-stage commit)." }, + { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, + "S.transaction_commit() -> None\n" + "commit a new transaction." }, + { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, + "S.transaction_cancel() -> None\n" + "cancel a new transaction." }, + { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, + NULL }, + { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS, + NULL }, + { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS, + NULL }, + { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS, + NULL }, + { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, + NULL }, + { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, + "S.connect(url, flags=0, options=None) -> None\n" + "Connect to a LDB URL." }, + { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS, + "S.modify(message, controls=None, validate=False) -> None\n" + "Modify an entry." }, + { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS, + "S.add(message, controls=None) -> None\n" + "Add an entry." }, + { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS, + "S.delete(dn, controls=None) -> None\n" + "Remove an entry." }, + { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS, + "S.rename(old_dn, new_dn, controls=None) -> None\n" + "Rename an entry." }, + { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS, + "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n" + "Search in a database.\n" + "\n" + ":param base: Optional base DN to search\n" + ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" + ":param expression: Optional search expression\n" + ":param attrs: Attributes to return (defaults to all)\n" + ":param controls: Optional list of controls\n" + ":return: Iterator over Message objects\n" + }, + { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, + NULL }, + { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, + NULL }, + { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS, + NULL }, + { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, + "S.parse_ldif(ldif) -> iter(messages)\n" + "Parse a string formatted using LDIF." }, + { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, + "S.write_ldif(message, changetype) -> ldif\n" + "Print the message as a string formatted using LDIF." }, + { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, + "S.msg_diff(Message) -> Message\n" + "Return an LDB Message of the difference between two Message objects." }, + { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS, + "S.get_opaque(name) -> value\n" + "Get an opaque value set on this LDB connection. \n" + ":note: The returned value may not be useful in Python." + }, + { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS, + "S.set_opaque(name, value) -> None\n" + "Set an opaque value on this LDB connection. \n" + ":note: Passing incorrect values may cause crashes." }, + { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS, + "S.modules() -> list\n" + "Return the list of modules on this LDB connection " }, + { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, + "S.sequence_number(type) -> value\n" + "Return the value of the sequence according to the requested type" }, + { NULL }, +}; + +static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) +{ + PyLdbModuleObject *ret; + + ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->mod = talloc_reference(ret->mem_ctx, mod); + return (PyObject *)ret; +} + +static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure) +{ + return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules); +} + +static PyGetSetDef py_ldb_getset[] = { + { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL }, + { NULL } +}; + +static int py_ldb_contains(PyLdbObject *self, PyObject *obj) +{ + struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self); + struct ldb_dn *dn; + struct ldb_result *result; + unsigned int count; + int ret; + + if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { + return -1; + } + + ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, + NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return -1; + } + + count = result->count; + + talloc_free(result); + + if (count > 1) { + PyErr_Format(PyExc_RuntimeError, + "Searching for [%s] dn gave %u results!", + ldb_dn_get_linearized(dn), + count); + return -1; + } + + return count; +} + +static PySequenceMethods py_ldb_seq = { + .sq_contains = (objobjproc)py_ldb_contains, +}; + +static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) +{ + PyLdbObject *ret; + + ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx); + return (PyObject *)ret; +} + +static void py_ldb_dealloc(PyLdbObject *self) +{ + talloc_free(self->mem_ctx); + self->ob_type->tp_free(self); +} + +static PyTypeObject PyLdb = { + .tp_name = "ldb.Ldb", + .tp_methods = py_ldb_methods, + .tp_repr = (reprfunc)py_ldb_repr, + .tp_new = py_ldb_new, + .tp_init = (initproc)py_ldb_init, + .tp_dealloc = (destructor)py_ldb_dealloc, + .tp_getset = py_ldb_getset, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbObject), + .tp_doc = "Connection to a LDB database.", + .tp_as_sequence = &py_ldb_seq, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static void py_ldb_result_dealloc(PyLdbResultObject *self) +{ + talloc_free(self->mem_ctx); + Py_DECREF(self->msgs); + Py_DECREF(self->referals); + Py_DECREF(self->controls); + self->ob_type->tp_free(self); +} + +static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->msgs); + return self->msgs; +} + +static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->controls); + return self->controls; +} + +static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->referals); + return self->referals; +} + +static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) +{ + Py_ssize_t size; + if (self->msgs == NULL) { + PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); + return NULL; + } + size = PyList_Size(self->msgs); + return PyInt_FromLong(size); +} + +static PyGetSetDef py_ldb_result_getset[] = { + { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL }, + { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL }, + { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL }, + { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL }, + { NULL } +}; + +static PyObject *py_ldb_result_iter(PyLdbResultObject *self) +{ + return PyObject_GetIter(self->msgs); +} + +static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) +{ + return PySequence_Size(self->msgs); +} + +static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) +{ + return PySequence_GetItem(self->msgs, idx); +} + +static PySequenceMethods py_ldb_result_seq = { + .sq_length = (lenfunc)py_ldb_result_len, + .sq_item = (ssizeargfunc)py_ldb_result_find, +}; + +static PyObject *py_ldb_result_repr(PyLdbObject *self) +{ + return PyString_FromFormat(""); +} + + +static PyTypeObject PyLdbResult = { + .tp_name = "ldb.Result", + .tp_repr = (reprfunc)py_ldb_result_repr, + .tp_dealloc = (destructor)py_ldb_result_dealloc, + .tp_iter = (getiterfunc)py_ldb_result_iter, + .tp_getset = py_ldb_result_getset, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbResultObject), + .tp_as_sequence = &py_ldb_result_seq, + .tp_doc = "LDB result.", + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) +{ + return PyString_FromFormat("", PyLdbModule_AsModule(self)->ops->name); +} + +static PyObject *py_ldb_module_str(PyLdbModuleObject *self) +{ + return PyString_FromString(PyLdbModule_AsModule(self)->ops->name); +} + +static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self) +{ + PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self) +{ + PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self) +{ + PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base, *py_tree, *py_attrs, *py_ret; + int ret, scope; + struct ldb_request *req; + const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL }; + struct ldb_module *mod; + const char * const*attrs; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO", + discard_const_p(char *, kwnames), + &py_base, &scope, &py_tree, &py_attrs)) + return NULL; + + mod = self->mod; + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStringList(NULL, py_attrs, "attrs"); + if (attrs == NULL) + return NULL; + } + + ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), + scope, NULL /* expr */, attrs, + NULL /* controls */, NULL, NULL, NULL); + + talloc_steal(req, attrs); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + req->op.search.res = NULL; + + ret = mod->ops->search(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + py_ret = PyLdbResult_FromResult(req->op.search.res); + + talloc_free(req); + + return py_ret; +} + + +static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args) +{ + struct ldb_request *req; + PyObject *py_message; + int ret; + struct ldb_module *mod; + + if (!PyArg_ParseTuple(args, "O", &py_message)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_ADD; + req->op.add.message = PyLdbMessage_AsMessage(py_message); + + mod = PyLdbModule_AsModule(self); + ret = mod->ops->add(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_message; + struct ldb_module *mod; + + if (!PyArg_ParseTuple(args, "O", &py_message)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_MODIFY; + req->op.mod.message = PyLdbMessage_AsMessage(py_message); + + mod = PyLdbModule_AsModule(self); + ret = mod->ops->modify(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_dn; + + if (!PyArg_ParseTuple(args, "O", &py_dn)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_DELETE; + req->op.del.dn = PyLdbDn_AsDn(py_dn); + + ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_dn1, *py_dn2; + + if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + + req->operation = LDB_RENAME; + req->op.rename.olddn = PyLdbDn_AsDn(py_dn1); + req->op.rename.newdn = PyLdbDn_AsDn(py_dn2); + + ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_module_methods[] = { + { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL }, + { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, + { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, + { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, + { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL }, + { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, + { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, + { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, + { NULL }, +}; + +static void py_ldb_module_dealloc(PyLdbModuleObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbModule = { + .tp_name = "ldb.LdbModule", + .tp_methods = py_ldb_module_methods, + .tp_repr = (reprfunc)py_ldb_module_repr, + .tp_str = (reprfunc)py_ldb_module_str, + .tp_basicsize = sizeof(PyLdbModuleObject), + .tp_dealloc = (destructor)py_ldb_module_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/** + * Create a ldb_message_element from a Python object. + * + * This will accept any sequence objects that contains strings, or + * a string object. + * + * A reference to set_obj will be borrowed. + * + * @param mem_ctx Memory context + * @param set_obj Python object to convert + * @param flags ldb_message_element flags to set + * @param attr_name Name of the attribute + * @return New ldb_message_element, allocated as child of mem_ctx + */ +static struct ldb_message_element *PyObject_AsMessageElement( + TALLOC_CTX *mem_ctx, + PyObject *set_obj, + unsigned int flags, + const char *attr_name) +{ + struct ldb_message_element *me; + + if (PyLdbMessageElement_Check(set_obj)) { + PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; + /* We have to talloc_reference() the memory context, not the pointer + * which may not actually be it's own context */ + if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { + return PyLdbMessageElement_AsMessageElement(set_obj); + } + return NULL; + } + + me = talloc(mem_ctx, struct ldb_message_element); + if (me == NULL) { + PyErr_NoMemory(); + return NULL; + } + + me->name = talloc_strdup(me, attr_name); + me->flags = flags; + if (PyString_Check(set_obj)) { + me->num_values = 1; + me->values = talloc_array(me, struct ldb_val, me->num_values); + me->values[0].length = PyString_Size(set_obj); + me->values[0].data = talloc_memdup(me, + (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1); + } else if (PySequence_Check(set_obj)) { + Py_ssize_t i; + me->num_values = PySequence_Size(set_obj); + me->values = talloc_array(me, struct ldb_val, me->num_values); + for (i = 0; i < me->num_values; i++) { + PyObject *obj = PySequence_GetItem(set_obj, i); + if (!PyString_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "Expected string as element %zd in list", i); + talloc_free(me); + return NULL; + } + + me->values[i].length = PyString_Size(obj); + me->values[i].data = talloc_memdup(me, + (uint8_t *)PyString_AsString(obj), me->values[i].length+1); + } + } else { + talloc_free(me); + me = NULL; + } + + return me; +} + + +static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, + struct ldb_message_element *me) +{ + Py_ssize_t i; + PyObject *result; + + /* Python << 2.5 doesn't have PySet_New and PySet_Add. */ + result = PyList_New(me->num_values); + + for (i = 0; i < me->num_values; i++) { + PyList_SetItem(result, i, + PyObject_FromLdbValue(&me->values[i])); + } + + return result; +} + +static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) +{ + unsigned int i; + if (!PyArg_ParseTuple(args, "I", &i)) + return NULL; + if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values) + Py_RETURN_NONE; + + return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i])); +} + +static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) +{ + struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); + return PyInt_FromLong(el->flags); +} + +static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) +{ + unsigned int flags; + struct ldb_message_element *el; + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + el = PyLdbMessageElement_AsMessageElement(self); + el->flags = flags; + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_msg_element_methods[] = { + { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, + { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, + { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, + { NULL }, +}; + +static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) +{ + return PyLdbMessageElement_AsMessageElement(self)->num_values; +} + +static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx) +{ + struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); + if (idx < 0 || idx >= el->num_values) { + PyErr_SetString(PyExc_IndexError, "Out of range"); + return NULL; + } + return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); +} + +static PySequenceMethods py_ldb_msg_element_seq = { + .sq_length = (lenfunc)py_ldb_msg_element_len, + .sq_item = (ssizeargfunc)py_ldb_msg_element_find, +}; + +static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other) +{ + int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), + PyLdbMessageElement_AsMessageElement(other)); + return SIGN(ret); +} + +static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self) +{ + return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self))); +} + +static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) +{ + PyLdbMessageElementObject *ret; + ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->el = el; + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *py_elements = NULL; + struct ldb_message_element *el; + unsigned int flags = 0; + char *name = NULL; + const char * const kwnames[] = { "elements", "flags", "name", NULL }; + PyLdbMessageElementObject *ret; + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", + discard_const_p(char *, kwnames), + &py_elements, &flags, &name)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + if (py_elements != NULL) { + Py_ssize_t i; + if (PyString_Check(py_elements)) { + el->num_values = 1; + el->values = talloc_array(el, struct ldb_val, 1); + if (el->values == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + el->values[0].length = PyString_Size(py_elements); + el->values[0].data = talloc_memdup(el->values, + (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1); + } else if (PySequence_Check(py_elements)) { + el->num_values = PySequence_Size(py_elements); + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < el->num_values; i++) { + PyObject *item = PySequence_GetItem(py_elements, i); + if (item == NULL) { + talloc_free(mem_ctx); + return NULL; + } + if (!PyString_Check(item)) { + PyErr_Format(PyExc_TypeError, + "Expected string as element %zd in list", i); + talloc_free(mem_ctx); + return NULL; + } + el->values[i].length = PyString_Size(item); + el->values[i].data = talloc_memdup(el, + (uint8_t *)PyString_AsString(item), el->values[i].length+1); + } + } else { + PyErr_SetString(PyExc_TypeError, + "Expected string or list"); + talloc_free(mem_ctx); + return NULL; + } + } + + el->flags = flags; + el->name = talloc_strdup(el, name); + + ret = PyObject_New(PyLdbMessageElementObject, type); + if (ret == NULL) { + talloc_free(mem_ctx); + return NULL; + } + + ret->mem_ctx = mem_ctx; + ret->el = el; + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self) +{ + char *element_str = NULL; + Py_ssize_t i; + struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); + PyObject *ret; + + for (i = 0; i < el->num_values; i++) { + PyObject *o = py_ldb_msg_element_find(self, i); + if (element_str == NULL) + element_str = talloc_strdup(NULL, PyObject_REPR(o)); + else + element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o)); + } + + if (element_str != NULL) { + ret = PyString_FromFormat("MessageElement([%s])", element_str); + talloc_free(element_str); + } else { + ret = PyString_FromString("MessageElement([])"); + } + + return ret; +} + +static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) +{ + struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); + + if (el->num_values == 1) + return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length); + else + Py_RETURN_NONE; +} + +static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbMessageElement = { + .tp_name = "ldb.MessageElement", + .tp_basicsize = sizeof(PyLdbMessageElementObject), + .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, + .tp_repr = (reprfunc)py_ldb_msg_element_repr, + .tp_str = (reprfunc)py_ldb_msg_element_str, + .tp_methods = py_ldb_msg_element_methods, + .tp_compare = (cmpfunc)py_ldb_msg_element_cmp, + .tp_iter = (getiterfunc)py_ldb_msg_element_iter, + .tp_as_sequence = &py_ldb_msg_element_seq, + .tp_new = py_ldb_msg_element_new, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) +{ + PyObject *py_ldb; + PyObject *py_dict; + PyObject *py_ret; + struct ldb_message *msg; + struct ldb_context *ldb_ctx; + unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; + + if (!PyArg_ParseTuple(args, "O!O!|I", + &PyLdb, &py_ldb, &PyDict_Type, &py_dict, + &mod_flags)) { + return NULL; + } + + /* mask only flags we are going to use */ + mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); + if (!mod_flags) { + PyErr_SetString(PyExc_ValueError, + "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" + " expected as mod_flag value"); + return NULL; + } + + ldb_ctx = PyLdb_AsLdbContext(py_ldb); + + msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); + if (!msg) { + return NULL; + } + + py_ret = PyLdbMessage_FromMessage(msg); + + talloc_unlink(ldb_ctx, msg); + + return py_ret; +} + +static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + ldb_msg_remove_attr(self->msg, name); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + Py_ssize_t i, j = 0; + PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); + if (msg->dn != NULL) { + PyList_SetItem(obj, j, PyString_FromString("dn")); + j++; + } + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name)); + j++; + } + return obj; +} + +static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) +{ + struct ldb_message_element *el; + char *name; + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + if (!PyString_Check(py_name)) { + PyErr_SetNone(PyExc_TypeError); + return NULL; + } + name = PyString_AsString(py_name); + if (!strcmp(name, "dn")) + return PyLdbDn_FromDn(msg->dn); + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return NULL; + } + return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); +} + +static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) +{ + PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); + if (ret == NULL) { + PyErr_SetString(PyExc_KeyError, "No such element"); + return NULL; + } + return ret; +} + +static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args) +{ + PyObject *name, *ret, *retobj; + retobj = NULL; + if (!PyArg_ParseTuple(args, "O|O", &name, &retobj)) + return NULL; + + ret = py_ldb_msg_getitem_helper(self, name); + if (ret == NULL) { + if (PyErr_Occurred()) + return NULL; + if (retobj != NULL) { + return retobj; + } else { + Py_RETURN_NONE; + } + } + return ret; +} + +static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + Py_ssize_t i, j = 0; + PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); + if (msg->dn != NULL) { + PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn))); + j++; + } + for (i = 0; i < msg->num_elements; i++, j++) { + PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); + PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); + PyList_SetItem(l, j, value); + } + return l; +} + +static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + Py_ssize_t i = 0; + PyObject *l = PyList_New(msg->num_elements); + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); + } + return l; +} + +static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + PyLdbMessageElementObject *py_element; + int ret; + struct ldb_message_element *el; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) + return NULL; + + el = talloc_reference(msg, py_element->el); + if (el == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = ldb_msg_add(msg, el, el->flags); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_msg_methods[] = { + { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, + "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" + "Class method to create ldb.Message object from Dictionary.\n" + "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, + { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, + "S.keys() -> list\n\n" + "Return sequence of all attribute names." }, + { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, + "S.remove(name)\n\n" + "Remove all entries for attributes with the specified name."}, + { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL }, + { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, + { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, + { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, + "S.append(element)\n\n" + "Add an element to this message." }, + { NULL }, +}; + +static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) +{ + PyObject *list, *iter; + + list = py_ldb_msg_keys(self); + iter = PyObject_GetIter(list); + Py_DECREF(list); + return iter; +} + +static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value) +{ + char *attr_name; + + if (!PyString_Check(name)) { + PyErr_SetNone(PyExc_TypeError); + return -1; + } + + attr_name = PyString_AsString(name); + if (value == NULL) { + /* delitem */ + ldb_msg_remove_attr(self->msg, attr_name); + } else { + struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, + value, 0, attr_name); + if (el == NULL) + return -1; + ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name); + ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags); + } + return 0; +} + +static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) +{ + return PyLdbMessage_AsMessage(self)->num_elements; +} + +static PyMappingMethods py_ldb_msg_mapping = { + .mp_length = (lenfunc)py_ldb_msg_length, + .mp_subscript = (binaryfunc)py_ldb_msg_getitem, + .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem, +}; + +static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "dn", NULL }; + struct ldb_message *ret; + TALLOC_CTX *mem_ctx; + PyObject *pydn = NULL; + PyLdbMessageObject *py_ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", + discard_const_p(char *, kwnames), + &pydn)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = ldb_msg_new(mem_ctx); + if (ret == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + + if (pydn != NULL) { + struct ldb_dn *dn; + if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) { + talloc_free(mem_ctx); + return NULL; + } + ret->dn = talloc_reference(ret, dn); + } + + py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + py_ret->mem_ctx = mem_ctx; + py_ret->msg = ret; + return (PyObject *)py_ret; +} + +static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) +{ + PyLdbMessageObject *ret; + + ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->msg = talloc_reference(ret->mem_ctx, msg); + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + return PyLdbDn_FromDn(msg->dn); +} + +static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + if (!PyLdbDn_Check(value)) { + PyErr_SetNone(PyExc_TypeError); + return -1; + } + + msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value)); + return 0; +} + +static PyGetSetDef py_ldb_msg_getset[] = { + { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL }, + { NULL } +}; + +static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self) +{ + PyObject *dict = PyDict_New(), *ret; + if (PyDict_Update(dict, (PyObject *)self) != 0) + return NULL; + ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict)); + Py_DECREF(dict); + return ret; +} + +static void py_ldb_msg_dealloc(PyLdbMessageObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1, + PyLdbMessageObject *py_msg2) +{ + struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1), + *msg2 = PyLdbMessage_AsMessage(py_msg2); + unsigned int i; + int ret; + + if ((msg1->dn != NULL) || (msg2->dn != NULL)) { + ret = ldb_dn_compare(msg1->dn, msg2->dn); + if (ret != 0) { + return SIGN(ret); + } + } + + ret = msg1->num_elements - msg2->num_elements; + if (ret != 0) { + return SIGN(ret); + } + + for (i = 0; i < msg1->num_elements; i++) { + ret = ldb_msg_element_compare_name(&msg1->elements[i], + &msg2->elements[i]); + if (ret != 0) { + return SIGN(ret); + } + + ret = ldb_msg_element_compare(&msg1->elements[i], + &msg2->elements[i]); + if (ret != 0) { + return SIGN(ret); + } + } + + return 0; +} + +static PyTypeObject PyLdbMessage = { + .tp_name = "ldb.Message", + .tp_methods = py_ldb_msg_methods, + .tp_getset = py_ldb_msg_getset, + .tp_as_mapping = &py_ldb_msg_mapping, + .tp_basicsize = sizeof(PyLdbMessageObject), + .tp_dealloc = (destructor)py_ldb_msg_dealloc, + .tp_new = py_ldb_msg_new, + .tp_repr = (reprfunc)py_ldb_msg_repr, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_iter = (getiterfunc)py_ldb_msg_iter, + .tp_compare = (cmpfunc)py_ldb_msg_compare, +}; + +static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) +{ + PyLdbTreeObject *ret; + + ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret->mem_ctx = talloc_new(NULL); + ret->tree = talloc_reference(ret->mem_ctx, tree); + return (PyObject *)ret; +} + +static void py_ldb_tree_dealloc(PyLdbTreeObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbTree = { + .tp_name = "ldb.Tree", + .tp_basicsize = sizeof(PyLdbTreeObject), + .tp_dealloc = (destructor)py_ldb_tree_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +/* Ldb_module */ +static int py_module_search(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_base, *py_attrs, *py_tree; + + py_base = PyLdbDn_FromDn(req->op.search.base); + + if (py_base == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_tree = PyLdbTree_FromTree(req->op.search.tree); + + if (py_tree == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + if (req->op.search.attrs == NULL) { + py_attrs = Py_None; + } else { + int i, len; + for (len = 0; req->op.search.attrs[len]; len++); + py_attrs = PyList_New(len); + for (i = 0; i < len; i++) + PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i])); + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"), + discard_const_p(char, "OiOO"), + py_base, req->op.search.scope, py_tree, py_attrs); + + Py_DECREF(py_attrs); + Py_DECREF(py_tree); + Py_DECREF(py_base); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + req->op.search.res = PyLdbResult_AsResult(NULL, py_result); + if (req->op.search.res == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_add(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_msg; + + py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message)); + + if (py_msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"), + discard_const_p(char, "O"), + py_msg); + + Py_DECREF(py_msg); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_modify(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_msg; + + py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message)); + + if (py_msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"), + discard_const_p(char, "O"), + py_msg); + + Py_DECREF(py_msg); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_del(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_dn; + + py_dn = PyLdbDn_FromDn(req->op.del.dn); + + if (py_dn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"), + discard_const_p(char, "O"), + py_dn); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_rename(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_olddn, *py_newdn; + + py_olddn = PyLdbDn_FromDn(req->op.rename.olddn); + + if (py_olddn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_newdn = PyLdbDn_FromDn(req->op.rename.newdn); + + if (py_newdn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"), + discard_const_p(char, "OO"), + py_olddn, py_newdn); + + Py_DECREF(py_olddn); + Py_DECREF(py_newdn); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_request(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"), + discard_const_p(char, "")); + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int py_module_extended(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"), + discard_const_p(char, "")); + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int py_module_start_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_end_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_del_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_destructor(struct ldb_module *mod) +{ + Py_DECREF((PyObject *)mod->private_data); + return 0; +} + +static int py_module_init(struct ldb_module *mod) +{ + PyObject *py_class = (PyObject *)mod->ops->private_data; + PyObject *py_result, *py_next, *py_ldb; + + py_ldb = PyLdb_FromLdbContext(mod->ldb); + + if (py_ldb == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_next = PyLdbModule_FromModule(mod->next); + + if (py_next == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"), + py_ldb, py_next); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + mod->private_data = py_result; + + talloc_set_destructor(mod, py_module_destructor); + + return ldb_next_init(mod); +} + +static PyObject *py_register_module(PyObject *module, PyObject *args) +{ + int ret; + struct ldb_module_ops *ops; + PyObject *input; + + if (!PyArg_ParseTuple(args, "O", &input)) + return NULL; + + ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops); + if (ops == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name")))); + + Py_INCREF(input); + ops->private_data = input; + ops->init_context = py_module_init; + ops->search = py_module_search; + ops->add = py_module_add; + ops->modify = py_module_modify; + ops->del = py_module_del; + ops->rename = py_module_rename; + ops->request = py_module_request; + ops->extended = py_module_extended; + ops->start_transaction = py_module_start_transaction; + ops->end_transaction = py_module_end_transaction; + ops->del_transaction = py_module_del_transaction; + + ret = ldb_register_module(ops); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyObject *py_timestring(PyObject *module, PyObject *args) +{ + /* most times "time_t" is a signed integer type with 32 or 64 bit: + * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ + long int t_val; + char *tresult; + PyObject *ret; + if (!PyArg_ParseTuple(args, "l", &t_val)) + return NULL; + tresult = ldb_timestring(NULL, (time_t) t_val); + ret = PyString_FromString(tresult); + talloc_free(tresult); + return ret; +} + +static PyObject *py_string_to_time(PyObject *module, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + + return PyInt_FromLong(ldb_string_to_time(str)); +} + +static PyObject *py_valid_attr_name(PyObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + return PyBool_FromLong(ldb_valid_attr_name(name)); +} + +static PyMethodDef py_ldb_global_methods[] = { + { "register_module", py_register_module, METH_VARARGS, + "S.register_module(module) -> None\n" + "Register a LDB module."}, + { "timestring", py_timestring, METH_VARARGS, + "S.timestring(int) -> string\n" + "Generate a LDAP time string from a UNIX timestamp" }, + { "string_to_time", py_string_to_time, METH_VARARGS, + "S.string_to_time(string) -> int\n" + "Parse a LDAP time string into a UNIX timestamp." }, + { "valid_attr_name", py_valid_attr_name, METH_VARARGS, + "S.valid_attr_name(name) -> bool\n" + "Check whether the supplied name is a valid attribute name." }, + { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS, + NULL }, + { NULL } +}; + +void initldb(void) +{ + PyObject *m; + + if (PyType_Ready(&PyLdbDn) < 0) + return; + + if (PyType_Ready(&PyLdbMessage) < 0) + return; + + if (PyType_Ready(&PyLdbMessageElement) < 0) + return; + + if (PyType_Ready(&PyLdb) < 0) + return; + + if (PyType_Ready(&PyLdbModule) < 0) + return; + + if (PyType_Ready(&PyLdbTree) < 0) + return; + + if (PyType_Ready(&PyLdbResult) < 0) + return; + + if (PyType_Ready(&PyLdbControl) < 0) + return; + + m = Py_InitModule3("ldb", py_ldb_global_methods, + "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."); + if (m == NULL) + return; + + PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ)); + PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP)); + PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT)); + PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT)); + PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE)); + PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL)); + PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE)); + + PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE)); + PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD)); + PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE)); + PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY)); + + PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD)); + PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE)); + PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE)); + + PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS)); + PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR)); + PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR)); + PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED)); + PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED)); + PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE)); + PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE)); + PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED)); + PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED)); + PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL)); + PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED)); + PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION)); + PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED)); + PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS)); + PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE)); + PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE)); + PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING)); + PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION)); + PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)); + PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX)); + PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT)); + PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM)); + PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX)); + PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM)); + PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION)); + PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS)); + PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS)); + PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY)); + PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE)); + PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM)); + PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT)); + PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION)); + PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION)); + PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF)); + PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN)); + PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS)); + PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED)); + PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); + PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER)); + + PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY)); + PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC)); + PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT)); + PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP)); + + PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText")); + + PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL); + PyModule_AddObject(m, "LdbError", PyExc_LdbError); + + Py_INCREF(&PyLdb); + Py_INCREF(&PyLdbDn); + Py_INCREF(&PyLdbModule); + Py_INCREF(&PyLdbMessage); + Py_INCREF(&PyLdbMessageElement); + Py_INCREF(&PyLdbTree); + Py_INCREF(&PyLdbResult); + Py_INCREF(&PyLdbControl); + + PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); + PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn); + PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage); + PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement); + PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); + PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); + PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); + + PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION)); + +#define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(val)) + + ADD_LDB_STRING(LDB_SYNTAX_DN); + ADD_LDB_STRING(LDB_SYNTAX_DN); + ADD_LDB_STRING(LDB_SYNTAX_DIRECTORY_STRING); + ADD_LDB_STRING(LDB_SYNTAX_INTEGER); + ADD_LDB_STRING(LDB_SYNTAX_BOOLEAN); + ADD_LDB_STRING(LDB_SYNTAX_OCTET_STRING); + ADD_LDB_STRING(LDB_SYNTAX_UTC_TIME); +} diff --git a/lib/ldb/pyldb.h b/lib/ldb/pyldb.h new file mode 100644 index 00000000000..04d8ff856c1 --- /dev/null +++ b/lib/ldb/pyldb.h @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb. + + Copyright (C) 2007-2008 Jelmer Vernooij + + ** 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 . +*/ + +#ifndef _PYLDB_H_ +#define _PYLDB_H_ + +#include + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_context *ldb_ctx; +} PyLdbObject; + +#define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx +#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_dn *dn; +} PyLdbDnObject; + +PyObject *PyLdbDn_FromDn(struct ldb_dn *); +bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn); +#define PyLdbDn_AsDn(pyobj) ((PyLdbDnObject *)pyobj)->dn +#define PyLdbDn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn) + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_message *msg; +} PyLdbMessageObject; +#define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) +#define PyLdbMessage_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_module *mod; +} PyLdbModuleObject; +#define PyLdbModule_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_message_element *el; +} PyLdbMessageElementObject; +#define PyLdbMessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el +#define PyLdbMessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_parse_tree *tree; +} PyLdbTreeObject; +#define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + PyObject *msgs; + PyObject *referals; + PyObject *controls; +} PyLdbResultObject; + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_control *data; +} PyLdbControlObject; + +#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \ + if (ret != LDB_SUCCESS) { \ + PyErr_SetLdbError(err, ret, ldb); \ + return NULL; \ + } + +/* Picked out of thin air. To do this properly, we should probably have some part of the + * errors in LDB be allocated to bindings ? */ +#define LDB_ERR_PYTHON_EXCEPTION 142 + +#endif /* _PYLDB_H_ */ diff --git a/lib/ldb/pyldb_util.c b/lib/ldb/pyldb_util.c new file mode 100644 index 00000000000..79077416be4 --- /dev/null +++ b/lib/ldb/pyldb_util.c @@ -0,0 +1,119 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb - utility functions. + + Copyright (C) 2007-2010 Jelmer Vernooij + + ** 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 . +*/ + +#include +#include "ldb.h" +#include "pyldb.h" + +static PyObject *ldb_module = NULL; + +/* There's no Py_ssize_t in 2.4, apparently */ +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 +typedef int Py_ssize_t; +typedef inquiry lenfunc; +typedef intargfunc ssizeargfunc; +#endif + +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + + +/** + * Find out PyTypeObject in ldb module for a given typename + */ +static PyTypeObject * PyLdb_GetPyType(const char *typename) +{ + PyObject *py_obj = NULL; + + if (ldb_module == NULL) { + ldb_module = PyImport_ImportModule("ldb"); + if (ldb_module == NULL) { + return NULL; + } + } + + py_obj = PyObject_GetAttrString(ldb_module, typename); + + return (PyTypeObject*)py_obj; +} + +/** + * Obtain a ldb DN from a Python object. + * + * @param mem_ctx Memory context + * @param object Python object + * @param ldb_ctx LDB context + * @return Whether or not the conversion succeeded + */ +bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, + struct ldb_context *ldb_ctx, struct ldb_dn **dn) +{ + struct ldb_dn *odn; + PyTypeObject *PyLdb_Dn_Type; + + if (ldb_ctx != NULL && PyString_Check(object)) { + odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object)); + *dn = odn; + return true; + } + + PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); + if (PyLdb_Dn_Type == NULL) { + return false; + } + + if (PyObject_TypeCheck(object, PyLdb_Dn_Type)) { + *dn = PyLdbDn_AsDn(object); + return true; + } + + PyErr_SetString(PyExc_TypeError, "Expected DN"); + return false; +} + +PyObject *PyLdbDn_FromDn(struct ldb_dn *dn) +{ + PyLdbDnObject *py_ret; + PyTypeObject *PyLdb_Dn_Type; + + if (dn == NULL) { + Py_RETURN_NONE; + } + + PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); + if (PyLdb_Dn_Type == NULL) { + return NULL; + } + + py_ret = (PyLdbDnObject *)PyLdb_Dn_Type->tp_alloc(PyLdb_Dn_Type, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = talloc_new(NULL); + py_ret->dn = talloc_reference(py_ret->mem_ctx, dn); + return (PyObject *)py_ret; +} diff --git a/lib/ldb/tests/init.ldif b/lib/ldb/tests/init.ldif new file mode 100644 index 00000000000..97b4561e378 --- /dev/null +++ b/lib/ldb/tests/init.ldif @@ -0,0 +1,41 @@ +dn: o=University of Michigan,c=TEST +objectclass: organization +objectclass: domainRelatedObject +l: Ann Arbor, Michigan +st: Michigan +o: University of Michigan +o: UMICH +o: UM +o: U-M +o: U of M +description: The University of Michigan at Ann Arbor +postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 + 09 $ US +telephonenumber: +1 313 764-1817 +associateddomain: example.com + +# there was an empty "seeAlso" here + +dn: ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +uidNumber: 0 +gidNumber: 0 + +dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +ou: Ldb Test +uidNumber: 0 +gidNumber: 0 + +dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +ou: LdbTspace +description: test white space removal in comparisons +uidNumber: 0 +gidNumber: 0 diff --git a/lib/ldb/tests/init_slapd.sh b/lib/ldb/tests/init_slapd.sh new file mode 100755 index 00000000000..cf06acd08b9 --- /dev/null +++ b/lib/ldb/tests/init_slapd.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +rm -rf tests/tmp/db +mkdir -p tests/tmp/db + +if [ -f tests/tmp/slapd.pid ]; then + kill `cat tests/tmp/slapd.pid` + sleep 1 +fi +if [ -f tests/tmp/slapd.pid ]; then + kill -9 `cat tests/tmp/slapd.pid` + rm -f tests/tmp/slapd.pid +fi + +# we don't consider a slapadd failure as a test suite failure, as it +# has nothing to do with ldb + +MODCONF=tests/tmp/modules.conf +rm -f $MODCONF +touch $MODCONF || exit 1 + +slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { + echo "enabling sladp modules" +cat > $MODCONF < + +import os +import unittest + +import ldb + + +def filename(): + import tempfile + try: + dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") + except KeyError: + dir_prefix = None + return tempfile.mktemp(dir=dir_prefix) + +class NoContextTests(unittest.TestCase): + + def test_valid_attr_name(self): + self.assertTrue(ldb.valid_attr_name("foo")) + self.assertFalse(ldb.valid_attr_name("24foo")) + + def test_timestring(self): + self.assertEquals("19700101000000.0Z", ldb.timestring(0)) + self.assertEquals("20071119191012.0Z", ldb.timestring(1195499412)) + + def test_string_to_time(self): + self.assertEquals(0, ldb.string_to_time("19700101000000.0Z")) + self.assertEquals(1195499412, ldb.string_to_time("20071119191012.0Z")) + + +class SimpleLdb(unittest.TestCase): + + def test_connect(self): + ldb.Ldb(filename()) + + def test_connect_none(self): + ldb.Ldb() + + def test_connect_later(self): + x = ldb.Ldb() + x.connect(filename()) + + def test_repr(self): + x = ldb.Ldb() + self.assertTrue(repr(x).startswith("]", repr(x.modules())) + + def test_search(self): + l = ldb.Ldb(filename()) + self.assertEquals(len(l.search()), 1) + + def test_search_controls(self): + l = ldb.Ldb(filename()) + self.assertEquals(len(l.search(controls=["paged_results:0:5"])), 1) + + def test_search_attrs(self): + l = ldb.Ldb(filename()) + self.assertEquals(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) + + def test_search_string_dn(self): + l = ldb.Ldb(filename()) + self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) + + def test_search_attr_string(self): + l = ldb.Ldb(filename()) + self.assertRaises(TypeError, l.search, attrs="dc") + + def test_opaque(self): + l = ldb.Ldb(filename()) + l.set_opaque("my_opaque", l) + self.assertTrue(l.get_opaque("my_opaque") is not None) + self.assertEquals(None, l.get_opaque("unknown")) + + def test_search_scope_base(self): + l = ldb.Ldb(filename()) + self.assertEquals(len(l.search(ldb.Dn(l, "dc=foo1"), + ldb.SCOPE_ONELEVEL)), 0) + + def test_delete(self): + l = ldb.Ldb(filename()) + self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) + + def test_delete_w_unhandled_ctrl(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo1") + m["b"] = ["a"] + l.add(m) + self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) + l.delete(m.dn) + + def test_contains(self): + name = filename() + l = ldb.Ldb(name) + self.assertFalse(ldb.Dn(l, "dc=foo3") in l) + l = ldb.Ldb(name) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo3") + m["b"] = ["a"] + l.add(m) + try: + self.assertTrue(ldb.Dn(l, "dc=foo3") in l) + finally: + l.delete(m.dn) + + def test_get_config_basedn(self): + l = ldb.Ldb(filename()) + self.assertEquals(None, l.get_config_basedn()) + + def test_get_root_basedn(self): + l = ldb.Ldb(filename()) + self.assertEquals(None, l.get_root_basedn()) + + def test_get_schema_basedn(self): + l = ldb.Ldb(filename()) + self.assertEquals(None, l.get_schema_basedn()) + + def test_get_default_basedn(self): + l = ldb.Ldb(filename()) + self.assertEquals(None, l.get_default_basedn()) + + def test_add(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = "bla" + self.assertEquals(len(l.search()), 1) + l.add(m) + try: + self.assertEquals(len(l.search()), 2) + finally: + l.delete(ldb.Dn(l, "dc=foo4")) + + def test_add_w_unhandled_ctrl(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = "bla" + self.assertEquals(len(l.search()), 1) + self.assertRaises(ldb.LdbError, lambda: l.add(m,["search_options:1:2"])) + + def test_add_dict(self): + l = ldb.Ldb(filename()) + m = {"dn": ldb.Dn(l, "dc=foo5"), + "bla": "bla"} + self.assertEquals(len(l.search()), 1) + l.add(m) + try: + self.assertEquals(len(l.search()), 2) + finally: + l.delete(ldb.Dn(l, "dc=foo5")) + + def test_add_dict_string_dn(self): + l = ldb.Ldb(filename()) + m = {"dn": "dc=foo6", "bla": "bla"} + self.assertEquals(len(l.search()), 1) + l.add(m) + try: + self.assertEquals(len(l.search()), 2) + finally: + l.delete(ldb.Dn(l, "dc=foo6")) + + def test_rename(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo7") + m["bla"] = "bla" + self.assertEquals(len(l.search()), 1) + l.add(m) + try: + l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) + self.assertEquals(len(l.search()), 2) + finally: + l.delete(ldb.Dn(l, "dc=bar")) + + def test_rename_string_dns(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo8") + m["bla"] = "bla" + self.assertEquals(len(l.search()), 1) + l.add(m) + self.assertEquals(len(l.search()), 2) + try: + l.rename("dc=foo8", "dc=bar") + self.assertEquals(len(l.search()), 2) + finally: + l.delete(ldb.Dn(l, "dc=bar")) + + def test_modify_delete(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m["bla"] = ["1234"] + l.add(m) + rm = l.search(m.dn)[0] + self.assertEquals(["1234"], list(rm["bla"])) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") + self.assertEquals(ldb.FLAG_MOD_DELETE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEquals(1, len(rm)) + rm = l.search(m.dn, attrs=["bla"]) + self.assertEquals(0, len(rm)) + finally: + l.delete(ldb.Dn(l, "dc=modifydelete")) + + def test_modify_add(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ["1234"] + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEquals(2, len(rm)) + self.assertEquals(["1234", "456"], list(rm["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_modify_replace(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m["bla"] = ["1234", "456"] + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") + self.assertEquals(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEquals(2, len(rm)) + self.assertEquals(["789"], list(rm["bla"])) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEquals(1, len(rm)) + finally: + l.delete(ldb.Dn(l, "dc=modify2")) + + def test_modify_flags_change(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ["1234"] + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEquals(2, len(rm)) + self.assertEquals(["1234", "456"], list(rm["bla"])) + + # Now create another modify, but switch the flags before we do it + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + m["bla"].set_flags(ldb.FLAG_MOD_DELETE) + l.modify(m) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEquals(1, len(rm)) + self.assertEquals(["1234"], list(rm["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_transaction_commit(self): + l = ldb.Ldb(filename()) + l.transaction_start() + m = ldb.Message(ldb.Dn(l, "dc=foo9")) + m["foo"] = ["bar"] + l.add(m) + l.transaction_commit() + l.delete(m.dn) + + def test_transaction_cancel(self): + l = ldb.Ldb(filename()) + l.transaction_start() + m = ldb.Message(ldb.Dn(l, "dc=foo10")) + m["foo"] = ["bar"] + l.add(m) + l.transaction_cancel() + self.assertEquals(0, len(l.search(ldb.Dn(l, "dc=foo10")))) + + def test_set_debug(self): + def my_report_fn(level, text): + pass + l = ldb.Ldb(filename()) + l.set_debug(my_report_fn) + + def test_zero_byte_string(self): + """Testing we do not get trapped in the \0 byte in a property string.""" + l = ldb.Ldb(filename()) + l.add({ + "dn" : "dc=somedn", + "objectclass" : "user", + "cN" : "LDAPtestUSER", + "givenname" : "ldap", + "displayname" : "foo\0bar", + }) + res = l.search(expression="(dn=dc=somedn)") + self.assertEquals("foo\0bar", res[0]["displayname"][0]) + + def test_no_crash_broken_expr(self): + l = ldb.Ldb(filename()) + self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"])) + + +class DnTests(unittest.TestCase): + + def setUp(self): + self.ldb = ldb.Ldb(filename()) + + def test_set_dn_invalid(self): + x = ldb.Message() + def assign(): + x.dn = "astring" + self.assertRaises(TypeError, assign) + + def test_eq(self): + x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") + y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") + self.assertEquals(x, y) + y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") + self.assertNotEquals(x, y) + + def test_str(self): + x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe") + self.assertEquals(x.__str__(), "dc=foo12,bar=bloe") + + def test_repr(self): + x = ldb.Dn(self.ldb, "dc=foo13,bla=blie") + self.assertEquals(x.__repr__(), "Dn('dc=foo13,bla=blie')") + + def test_get_casefold(self): + x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe") + self.assertEquals(x.get_casefold(), "DC=FOO14,BAR=bloe") + + def test_validate(self): + x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe") + self.assertTrue(x.validate()) + + def test_parent(self): + x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe") + self.assertEquals("bar=bloe", x.parent().__str__()) + + def test_parent_nonexistant(self): + x = ldb.Dn(self.ldb, "@BLA") + self.assertEquals(None, x.parent()) + + def test_is_valid(self): + x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe") + self.assertTrue(x.is_valid()) + x = ldb.Dn(self.ldb, "") + self.assertTrue(x.is_valid()) + + def test_is_special(self): + x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe") + self.assertFalse(x.is_special()) + x = ldb.Dn(self.ldb, "@FOOBAR") + self.assertTrue(x.is_special()) + + def test_check_special(self): + x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe") + self.assertFalse(x.check_special("FOOBAR")) + x = ldb.Dn(self.ldb, "@FOOBAR") + self.assertTrue(x.check_special("@FOOBAR")) + + def test_len(self): + x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe") + self.assertEquals(2, len(x)) + x = ldb.Dn(self.ldb, "dc=foo21") + self.assertEquals(1, len(x)) + + def test_add_child(self): + x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") + self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe"))) + self.assertEquals("bla=bloe,dc=foo22,bar=bloe", x.__str__()) + + def test_add_base(self): + x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") + base = ldb.Dn(self.ldb, "bla=bloe") + self.assertTrue(x.add_base(base)) + self.assertEquals("dc=foo23,bar=bloe,bla=bloe", x.__str__()) + + def test_add(self): + x = ldb.Dn(self.ldb, "dc=foo24") + y = ldb.Dn(self.ldb, "bar=bla") + self.assertEquals("dc=foo24,bar=bla", str(y + x)) + + def test_parse_ldif(self): + msgs = self.ldb.parse_ldif("dn: foo=bar\n") + msg = msgs.next() + self.assertEquals("foo=bar", str(msg[1].dn)) + self.assertTrue(isinstance(msg[1], ldb.Message)) + ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) + self.assertEquals("dn: foo=bar\n\n", ldif) + + def test_parse_ldif_more(self): + msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") + msg = msgs.next() + self.assertEquals("foo=bar", str(msg[1].dn)) + msg = msgs.next() + self.assertEquals("bar=bar", str(msg[1].dn)) + + def test_canonical_string(self): + x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe") + self.assertEquals("/bloe/foo25", x.canonical_str()) + + def test_canonical_ex_string(self): + x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe") + self.assertEquals("/bloe\nfoo26", x.canonical_ex_str()) + + +class LdbMsgTests(unittest.TestCase): + + def setUp(self): + self.msg = ldb.Message() + + def test_init_dn(self): + self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27")) + self.assertEquals("dc=foo27", str(self.msg.dn)) + + def test_iter_items(self): + self.assertEquals(0, len(self.msg.items())) + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo28") + self.assertEquals(1, len(self.msg.items())) + + def test_repr(self): + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo29") + self.msg["dc"] = "foo" + self.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self.msg)) + + def test_len(self): + self.assertEquals(0, len(self.msg)) + + def test_notpresent(self): + self.assertRaises(KeyError, lambda: self.msg["foo"]) + + def test_del(self): + del self.msg["foo"] + + def test_add(self): + self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) + + def test_elements_empty(self): + self.assertEquals([], self.msg.elements()) + + def test_elements(self): + el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.msg.add(el) + self.assertEquals([el], self.msg.elements()) + + def test_add_value(self): + self.assertEquals(0, len(self.msg)) + self.msg["foo"] = ["foo"] + self.assertEquals(1, len(self.msg)) + + def test_add_value_multiple(self): + self.assertEquals(0, len(self.msg)) + self.msg["foo"] = ["foo", "bla"] + self.assertEquals(1, len(self.msg)) + self.assertEquals(["foo", "bla"], list(self.msg["foo"])) + + def test_set_value(self): + self.msg["foo"] = ["fool"] + self.assertEquals(["fool"], list(self.msg["foo"])) + self.msg["foo"] = ["bar"] + self.assertEquals(["bar"], list(self.msg["foo"])) + + def test_keys(self): + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") + self.msg["foo"] = ["bla"] + self.msg["bar"] = ["bla"] + self.assertEquals(["dn", "foo", "bar"], self.msg.keys()) + + def test_dn(self): + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") + self.assertEquals("@BASEINFO", self.msg.dn.__str__()) + + def test_get_dn(self): + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") + self.assertEquals("@BASEINFO", self.msg.get("dn").__str__()) + + def test_get_invalid(self): + self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") + self.assertRaises(TypeError, self.msg.get, 42) + + def test_get_other(self): + self.msg["foo"] = ["bar"] + self.assertEquals("bar", self.msg.get("foo")[0]) + + def test_get_default(self): + self.assertEquals(None, self.msg.get("tatayoyo")) + + self.assertEquals("anniecordie", self.msg.get("tatayoyo", "anniecordie")) + + def test_get_unknown(self): + self.assertEquals(None, self.msg.get("lalalala")) + + def test_msg_diff(self): + l = ldb.Ldb() + msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") + msg1 = msgs.next()[1] + msg2 = msgs.next()[1] + msgdiff = l.msg_diff(msg1, msg2) + self.assertEquals("foo=bar", msgdiff.get("dn").__str__()) + self.assertRaises(KeyError, lambda: msgdiff["foo"]) + self.assertEquals(1, len(msgdiff)) + + def test_equal_empty(self): + msg1 = ldb.Message() + msg2 = ldb.Message() + self.assertEquals(msg1, msg2) + + def test_equal_simplel(self): + db = ldb.Ldb(filename()) + msg1 = ldb.Message() + msg1.dn = ldb.Dn(db, "foo=bar") + msg2 = ldb.Message() + msg2.dn = ldb.Dn(db, "foo=bar") + self.assertEquals(msg1, msg2) + msg1['foo'] = 'bar' + msg2['foo'] = 'bar' + self.assertEquals(msg1, msg2) + msg2['foo'] = 'blie' + self.assertNotEquals(msg1, msg2) + msg2['foo'] = 'blie' + + def test_from_dict(self): + rec = {"dn": "dc=fromdict", + "a1": ["a1-val1", "a1-val1"]} + l = ldb.Ldb() + # check different types of input Flags + for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: + m = ldb.Message.from_dict(l, rec, flags) + self.assertEquals(rec["a1"], list(m["a1"])) + self.assertEquals(flags, m["a1"].flags()) + # check input params + self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) + self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) + self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) + # Message.from_dict expects dictionary with 'dn' + err_rec = {"a1": ["a1-val1", "a1-val1"]} + self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) + + + +class MessageElementTests(unittest.TestCase): + + def test_cmp_element(self): + x = ldb.MessageElement(["foo"]) + y = ldb.MessageElement(["foo"]) + z = ldb.MessageElement(["bzr"]) + self.assertEquals(x, y) + self.assertNotEquals(x, z) + + def test_create_iterable(self): + x = ldb.MessageElement(["foo"]) + self.assertEquals(["foo"], list(x)) + + def test_repr(self): + x = ldb.MessageElement(["foo"]) + self.assertEquals("MessageElement(['foo'])", repr(x)) + x = ldb.MessageElement(["foo", "bla"]) + self.assertEquals(2, len(x)) + self.assertEquals("MessageElement(['foo','bla'])", repr(x)) + + def test_get_item(self): + x = ldb.MessageElement(["foo", "bar"]) + self.assertEquals("foo", x[0]) + self.assertEquals("bar", x[1]) + self.assertEquals("bar", x[-1]) + self.assertRaises(IndexError, lambda: x[45]) + + def test_len(self): + x = ldb.MessageElement(["foo", "bar"]) + self.assertEquals(2, len(x)) + + def test_eq(self): + x = ldb.MessageElement(["foo", "bar"]) + y = ldb.MessageElement(["foo", "bar"]) + self.assertEquals(y, x) + x = ldb.MessageElement(["foo"]) + self.assertNotEquals(y, x) + y = ldb.MessageElement(["foo"]) + self.assertEquals(y, x) + + def test_extended(self): + el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEquals("MessageElement(['456'])", repr(el)) + + +class ModuleTests(unittest.TestCase): + + def test_register_module(self): + class ExampleModule: + name = "example" + ldb.register_module(ExampleModule) + + def test_use_module(self): + ops = [] + class ExampleModule: + name = "bla" + + def __init__(self, ldb, next): + ops.append("init") + self.next = next + + def search(self, *args, **kwargs): + return self.next.search(*args, **kwargs) + + def request(self, *args, **kwargs): + pass + + name = filename() + ldb.register_module(ExampleModule) + if os.path.exists(name): + os.unlink(name) + l = ldb.Ldb(name) + l.add({"dn": "@MODULES", "@LIST": "bla"}) + self.assertEquals([], ops) + l = ldb.Ldb(name) + self.assertEquals(["init"], ops) + +class LdbResultTests(unittest.TestCase): + + def setUp(self): + name = filename() + self.name = name + if os.path.exists(name): + os.unlink(name) + self.l = ldb.Ldb(name) + self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": "samba.org"}) + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": "Admins"}) + self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": "Users"}) + self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": "OU #1"}) + self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": "OU #2"}) + self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": "OU #3"}) + self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": "OU #4"}) + self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": "OU #5"}) + self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": "OU #6"}) + self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": "OU #7"}) + self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": "OU #8"}) + self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": "OU #9"}) + self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": "OU #10"}) + + def tearDown(self): + if os.path.exists(self.name): + os.unlink(self.name) + + def test_return_type(self): + res = self.l.search() + self.assertEquals(str(res), "") + + def test_get_msgs(self): + res = self.l.search() + list = res.msgs + + def test_get_controls(self): + res = self.l.search() + list = res.controls + + def test_get_referals(self): + res = self.l.search() + list = res.referals + + def test_iter_msgs(self): + found = False + for l in self.l.search().msgs: + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + def test_iter_msgs_count(self): + self.assertTrue(self.l.search().count > 0) + # 13 objects has been added to the DC=SAMBA, DC=ORG + self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) + + def test_iter_controls(self): + res = self.l.search().controls + it = iter(res) + + def test_create_control(self): + self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") + c = ldb.Control(self.l, "relax:1") + self.assertEquals(c.critical, True) + self.assertEquals(c.oid, "1.3.6.1.4.1.4203.666.5.12") + + def test_iter_refs(self): + res = self.l.search().referals + it = iter(res) + + def test_iter_as_sequence_msgs(self): + found = False + res = self.l.search().msgs + + for i in range(0, len(res)): + l = res[i] + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + def test_iter_as_sequence(self): + found = False + res = self.l.search() + + for i in range(0, len(res)): + l = res[i] + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + +class VersionTests(unittest.TestCase): + + def test_version(self): + self.assertTrue(isinstance(ldb.__version__, str)) + + +if __name__ == '__main__': + import unittest + unittest.TestProgram() diff --git a/lib/ldb/tests/samba4.png b/lib/ldb/tests/samba4.png new file mode 100644 index 00000000000..c8096889a67 Binary files /dev/null and b/lib/ldb/tests/samba4.png differ diff --git a/lib/ldb/tests/sample_module.c b/lib/ldb/tests/sample_module.c new file mode 100644 index 00000000000..bee40a5e80f --- /dev/null +++ b/lib/ldb/tests/sample_module.c @@ -0,0 +1,71 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2007 + + ** 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 . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +static int sample_add(struct ldb_module *mod, struct ldb_request *req) +{ + struct ldb_control *control; + + ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample"); + + /* check if there's a relax control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(mod, req); + } else { + return LDB_ERR_UNWILLING_TO_PERFORM; + } +} + +static int sample_modify(struct ldb_module *mod, struct ldb_request *req) +{ + struct ldb_control *control; + + /* check if there's a relax control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(mod, req); + } else { + return LDB_ERR_UNWILLING_TO_PERFORM; + } +} + + +static struct ldb_module_ops ldb_sample_module_ops = { + .name = "sample", + .add = sample_add, + .del = sample_modify, + .modify = sample_modify, +}; + +int ldb_sample_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_sample_module_ops); +} diff --git a/lib/ldb/tests/schema-tests/schema-add-test.ldif b/lib/ldb/tests/schema-tests/schema-add-test.ldif new file mode 100644 index 00000000000..472ab48fac9 --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-add-test.ldif @@ -0,0 +1,66 @@ +dn: CN=Users,DC=schema,DC=test +objectClass: top +objectClass: container +cn: Users +description: Default container for upgraded user accounts +instanceType: 4 +whenCreated: 20050116175504.0Z +whenChanged: 20050116175504.0Z +uSNCreated: 1 +uSNChanged: 1 +showInAdvancedViewOnly: FALSE +name: Users +objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 +systemFlags: 0x8c000000 +objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test +isCriticalSystemObject: TRUE +nTSecurityDescriptor: foo + +dn: CN=Administrator,CN=Users,DC=schema,DC=test +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: user +cn: Administrator +description: Built-in account for administering the computer/domain +instanceType: 4 +whenCreated: 20050116175504.0Z +whenChanged: 20050116175504.0Z +uSNCreated: 1 +memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test +memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test +uSNChanged: 1 +name: Administrator +objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c +userAccountControl: 0x10200 +badPwdCount: 0 +codePage: 0 +countryCode: 0 +badPasswordTime: 0 +lastLogoff: 0 +lastLogon: 0 +pwdLastSet: 0 +primaryGroupID: 513 +objectSid: S-1-5-21-43662522-77495566-38969261-500 +adminCount: 1 +accountExpires: 9223372036854775807 +logonCount: 0 +sAMAccountName: Administrator +sAMAccountType: 0x30000000 +objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test +isCriticalSystemObject: TRUE +unicodePwd: samba +nTSecurityDescriptor: foo + +dn: CN=Test,CN=Users,DC=schema,DC=test +objectClass: top +objectClass: test +cn: Test +description: This is a test +objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test +nTSecurityDescriptor: foo +instanceType: 4 + diff --git a/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif b/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif new file mode 100644 index 00000000000..b9767244854 --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +replace: description +description: this test must not fail + diff --git a/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif b/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif new file mode 100644 index 00000000000..fa193af6832 --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +delete: description +# this test must not fail + diff --git a/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif b/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif new file mode 100644 index 00000000000..8ab7798f9ce --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +add: description +description: this test must not fail + diff --git a/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif b/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif new file mode 100644 index 00000000000..cbf0e60bbea --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +add: foo +foo: this test must fail + diff --git a/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif b/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif new file mode 100644 index 00000000000..bc64e9edb61 --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +delete: nTSecurityDescriptor +# this test must fail + diff --git a/lib/ldb/tests/schema-tests/schema.ldif b/lib/ldb/tests/schema-tests/schema.ldif new file mode 100644 index 00000000000..4ab1932839b --- /dev/null +++ b/lib/ldb/tests/schema-tests/schema.ldif @@ -0,0 +1,100 @@ +dn: @INDEXLIST +@IDXATTR: name +@IDXATTR: sAMAccountName +@IDXATTR: objectSid +@IDXATTR: objectClass +@IDXATTR: member +@IDXATTR: uidNumber +@IDXATTR: gidNumber +@IDXATTR: unixName +@IDXATTR: privilege +@IDXATTR: lDAPDisplayName + +dn: @ATTRIBUTES +realm: CASE_INSENSITIVE +userPrincipalName: CASE_INSENSITIVE +servicePrincipalName: CASE_INSENSITIVE +name: CASE_INSENSITIVE +dn: CASE_INSENSITIVE +sAMAccountName: CASE_INSENSITIVE +objectClass: CASE_INSENSITIVE +unicodePwd: HIDDEN +ntPwdHash: HIDDEN +ntPwdHistory: HIDDEN +lmPwdHash: HIDDEN +lmPwdHistory: HIDDEN +createTimestamp: HIDDEN +modifyTimestamp: HIDDEN + +dn: @MODULES +@LIST: timestamps,schema + +dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +lDAPDisplayName: top +cn: Top +uSNCreated: 1 +uSNChanged: 1 +subClassOf: top +systemMustContain: objectClass +systemMayContain: structuralObjectClass +systemMayContain: createTimeStamp +systemMayContain: modifyTimeStamp +systemMayContain: creatorsName +systemMayContain: modifiersName +systemMayContain: hasSubordinates +systemMayContain: subschemaSubentry +systemMayContain: collectiveSubentry +systemMayContain: entryUUID +systemMayContain: entryCSN +systemMayContain: namingCSN +systemMayContain: superiorUUID +systemMayContain: contextCSN +systemMayContain: whenCreated +systemMayContain: whenChanged +systemMayContain: uSNCreated +systemMayContain: uSNChanged +systemMayContain: distinguishedName +systemMayContain: name +systemMayContain: cn +systemMayContain: userPassword +systemMayContain: labeledURI + +dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +lDAPDisplayName: classSchema +cn: Class-Schema +uSNCreated: 2 +uSNChanged: 2 +lDAPDisplayName: classSchema +subClassOf: top +systemMustContain: cn +systemMustContain: subClassOf +systemMayContain: systemPossSuperiors +systemMayContain: systemOnly +systemMayContain: systemMustContain +systemMayContain: systemMayContain +systemMayContain: systemAuxiliaryClass +systemMayContain: possSuperiors +systemMayContain: mustContain +systemMayContain: mayContain +systemMayContain: lDAPDisplayName +systemMayContain: auxiliaryClass + +dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +cn: Attribute-Schema +uSNCreated: 3 +uSNChanged: 3 +lDAPDisplayName: attributeSchema +subClassOf: top +systemMustContain: oMSyntax +systemMustContain: lDAPDisplayName +systemMustContain: isSingleValued +systemMustContain: cn +systemMustContain: attributeSyntax +systemMustContain: attributeID + diff --git a/lib/ldb/tests/slapd.conf b/lib/ldb/tests/slapd.conf new file mode 100644 index 00000000000..fa2789d8c17 --- /dev/null +++ b/lib/ldb/tests/slapd.conf @@ -0,0 +1,26 @@ +loglevel 0 + +include tests/schema/core.schema +include tests/schema/cosine.schema +include tests/schema/inetorgperson.schema +include tests/schema/openldap.schema +include tests/schema/nis.schema + + +pidfile tests/tmp/slapd.pid +argsfile tests/tmp/slapd.args + +access to * by * write + +allow update_anon bind_anon_dn + +include tests/tmp/modules.conf + +defaultsearchbase "o=University of Michigan,c=TEST" + +backend bdb +database bdb +suffix "o=University of Michigan,c=TEST" +directory tests/tmp/db +index objectClass eq +index uid eq diff --git a/lib/ldb/tests/start_slapd.sh b/lib/ldb/tests/start_slapd.sh new file mode 100755 index 00000000000..11679d47a3e --- /dev/null +++ b/lib/ldb/tests/start_slapd.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +mkdir -p $LDBDIR/tests/tmp/db + +# running slapd in the background (with &) means it stays in the same process group, so it can be +# killed by timelimit +slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & + +sleep 2 diff --git a/lib/ldb/tests/test-attribs.ldif b/lib/ldb/tests/test-attribs.ldif new file mode 100644 index 00000000000..79508c4b7bc --- /dev/null +++ b/lib/ldb/tests/test-attribs.ldif @@ -0,0 +1,6 @@ +dn: @ATTRIBUTES +uid: CASE_INSENSITIVE +cn: CASE_INSENSITIVE +ou: CASE_INSENSITIVE +dn: CASE_INSENSITIVE + diff --git a/lib/ldb/tests/test-config.ldif b/lib/ldb/tests/test-config.ldif new file mode 100644 index 00000000000..7926a9e3c58 --- /dev/null +++ b/lib/ldb/tests/test-config.ldif @@ -0,0 +1,67 @@ +############################## +# global configuration options +dn: cn=Global,cn=Config,cn=Samba +objectclass: globalconfig +LocalConfigCn: cn=%U,cn=Config,cn=Samba +LocalConfigCn;1: cn=%U,cn=Config,cn=Samba +LocalConfigCn;2: cn=%I,cn=Config,cn=Samba +LocalConfigCn;3: cn=%M,cn=Config,cn=Samba + +############# +dn: cn=Protocol,cn=Global,cn=Config,cn=Samba +maxXmit: 7000 + +################################ +dn: cn=Volker,cn=Config,cn=Samba +Workgroup: VNET3 +UnixCharset: UTF8 +Security: user +Interfaces: vmnet* eth* +NetbiosName: blu +GuestAccount: tridge + +################################# +dn: cn=Volker,cn=Config,cn=Samba +Workgroup: VNET3 +UnixCharset: UTF8 +Security: user +Interfaces: vmnet* eth* +NetbiosName: blu +GuestAccount: tridge +Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba + +#### ((objectClass=fileshare)(cn=test)) +############################## +# [test] share +dn: cn=test,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: test +Comment: a test share +Path: /home/tridge/samba4/prefix/test +ReadOnly: no + +##################################### +# [msdn] a remote proxy share, stored +# on \\msdn\test +dn: cn=msdn,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: msdn +NtvfsHandler: cifs +ReadOnly: no +_CifsServer: msdn +_CifsUser: administrator +_CifsPassword: penguin +_CifsDomain: winxp +_CifsShare: test + + +############################## +# [VisualC] share +dn: cn=visualc,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: VisualC +Comment: VisualC development +Path: /home/tridge/VisualC +ReadOnly: no +NtvfsHandler: simple + diff --git a/lib/ldb/tests/test-controls.sh b/lib/ldb/tests/test-controls.sh new file mode 100755 index 00000000000..771085ec606 --- /dev/null +++ b/lib/ldb/tests/test-controls.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +if [ -n "$TEST_DATA_PREFIX" ]; then + LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" +else + LDB_URL="tdbtest.ldb" +fi +export LDB_URL + +PATH=bin:$PATH +export PATH + +rm -f $LDB_URL* + +echo "LDB_URL: $LDB_URL" +cat </dev/null 2>&1 || exit 1 + +set diff --git a/lib/ldb/tests/test-default-config.ldif b/lib/ldb/tests/test-default-config.ldif new file mode 100644 index 00000000000..87b7bcd3cc7 --- /dev/null +++ b/lib/ldb/tests/test-default-config.ldif @@ -0,0 +1,17 @@ +############################## +# global configuration options +dn: cn=Global,cn=DefaultConfig,cn=Samba +objectclass: globalconfig +Workgroup: WORKGROUP +UnixCharset: UTF8 +Security: user +NetbiosName: blu +GuestAccount: nobody + +############################## +# [_default_] share +dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba +objectclass: fileshare +cn: _default_ +Path: /tmp +ReadOnly: yes diff --git a/lib/ldb/tests/test-extended.sh b/lib/ldb/tests/test-extended.sh new file mode 100755 index 00000000000..14b988e3f94 --- /dev/null +++ b/lib/ldb/tests/test-extended.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +echo "Running extended search tests" + +mv $LDB_URL $LDB_URL.1 + +cat < /dev/null && { + echo "Should have failed to add again - gave $?" + exit 1 +} + +echo "Modifying elements" +$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify.ldif || exit 1 + +echo "Showing modified record" +$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 + +echo "Rename entry with ldbmodify - modrdn" +$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 + +echo "Rename entry with ldbrename" +OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" +NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" +$VALGRIND ldbrename$EXEEXT "$OLDDN" "$NEWDN" || exit 1 + +echo "Showing renamed record" +$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 + +echo "Starting ldbtest" +$VALGRIND ldbtest$EXEEXT --num-records 100 --num-searches 10 || exit 1 + +if [ $LDB_SPECIALS = 1 ]; then + echo "Adding index" + $VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-index.ldif || exit 1 +fi + +echo "Adding bad attributes - should fail" +$VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-wrong_attributes.ldif && { + echo "Should fhave failed - gave $?" + exit 1 +} + +echo "Testing indexed search" +$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uham))' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(|(uid=uham)(uid=uham))' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 +$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 + +# note that the "((" is treated as an attribute not an expression +# this matches the openldap ldapsearch behaviour of looking for a '=' +# to see if the first argument is an expression or not +$VALGRIND ldbsearch$EXEEXT '((' uid || exit 1 +$VALGRIND ldbsearch$EXEEXT '(objectclass=)' uid || exit 1 +$VALGRIND ldbsearch$EXEEXT -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 + +echo "Test wildcard match" +$VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-wildcard.ldif || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=test*multi)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=*test*multi*)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=*test_multi)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=test_multi*)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=test*multi*test*multi)' || exit 1 +$VALGRIND ldbsearch$EXEEXT '(cn=test*multi*test*multi*multi_*)' || exit 1 + +echo "Starting ldbtest indexed" +$VALGRIND ldbtest$EXEEXT --num-records 100 --num-searches 500 || exit 1 + +echo "Testing one level search" +count=`$VALGRIND ldbsearch$EXEEXT -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` +if [ $count != 3 ]; then + echo returned $count records - expected 3 + exit 1 +fi + +echo "Testing binary file attribute value" +$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/photo.ldif || exit 1 +count=`$VALGRIND ldbsearch$EXEEXT '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` +if [ $count != 1 ]; then + echo returned $count records - expected 1 + exit 1 +fi + +echo "*TODO* Testing UTF8 upper lower case searches !!" + +echo "Testing compare" +count=`$VALGRIND ldbsearch$EXEEXT '(cn>=t)' cn | grep '^dn' | wc -l` +if [ $count != 2 ]; then + echo returned $count records - expected 2 + echo "this fails on openLdap ..." +fi + +count=`$VALGRIND ldbsearch$EXEEXT '(cn<=t)' cn | grep '^dn' | wc -l` +if [ $count != 13 ]; then + echo returned $count records - expected 13 + echo "this fails on openLdap ..." +fi + +checkcount() { + count=$1 + scope=$2 + basedn=$3 + expression="$4" + n=`$VALGRIND ldbsearch$EXEEXT -s "$scope" -b "$basedn" "$expression" | grep '^dn' | wc -l` + if [ $n != $count ]; then + echo "Got $n but expected $count for $expression" + bin/ldbsearch "$expression" + exit 1 + fi + echo "OK: $count $expression" +} + +checkcount 0 'base' '' '(uid=uham)' +checkcount 0 'one' '' '(uid=uham)' + +checkcount 1 'base' 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' +checkcount 1 'one' 'ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' +checkcount 1 'one' 'ou=People,o=University of Michigan,c=TEST' '(ou=ldb test)' diff --git a/lib/ldb/tests/test-index.ldif b/lib/ldb/tests/test-index.ldif new file mode 100644 index 00000000000..268173641d1 --- /dev/null +++ b/lib/ldb/tests/test-index.ldif @@ -0,0 +1,7 @@ +dn: @INDEXLIST +@IDXATTR: uid +@IDXATTR: objectclass + +dn: @ATTRIBUTES +uid: CASE_INSENSITIVE + diff --git a/lib/ldb/tests/test-ldap.sh b/lib/ldb/tests/test-ldap.sh new file mode 100755 index 00000000000..14cfb5f9793 --- /dev/null +++ b/lib/ldb/tests/test-ldap.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH +export PATH +SCHEMA_NEEDED="core nis cosine inetorgperson openldap" + +# setup needed schema files +for f in $SCHEMA_NEEDED; do + if [ ! -r tests/schema/$f.schema ]; then + mkdir -p tests/schema + if [ -r /etc/ldap/schema/$f.schema ]; then + ln -s /etc/ldap/schema/$f.schema tests/schema/$f.schema + continue; + fi + if [ -r /etc/openldap/schema/$f.schema ]; then + ln -s /etc/openldap/schema/$f.schema tests/schema/$f.schema + continue; + fi + + echo "SKIPPING TESTS: you need the following OpenLDAP schema files" + for f in $SCHEMA_NEEDED; do + echo " $f.schema" + done + exit 0 + fi +done + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +LDB_URL=`$LDBDIR/tests/ldapi_url.sh` +export LDB_URL + +PATH=bin:$PATH +export PATH + +LDB_SPECIALS=0 +export LDB_SPECIALS + +if $LDBDIR/tests/init_slapd.sh && + $LDBDIR/tests/start_slapd.sh && + $LDBDIR/tests/test-generic.sh; then + echo "ldap tests passed"; + ret=0 +else + echo "ldap tests failed"; + ret=$? +fi + +#$LDBDIR/tests/kill_slapd.sh + +exit $ret diff --git a/lib/ldb/tests/test-modify-modrdn.ldif b/lib/ldb/tests/test-modify-modrdn.ldif new file mode 100644 index 00000000000..efa31494626 --- /dev/null +++ b/lib/ldb/tests/test-modify-modrdn.ldif @@ -0,0 +1,12 @@ +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=TEST +changetype: moddn +newrdn: cn=Hampster Ursula +deleteoldrdn: 1 +newsuperior: ou=Alumni Association,ou=People,o=University of Michigan,c=TEST + +dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michiga + n,c=TEST +changetype: modrdn +newrdn: cn=Ursula Hampster +deleteoldrdn: 1 diff --git a/lib/ldb/tests/test-modify.ldif b/lib/ldb/tests/test-modify.ldif new file mode 100644 index 00000000000..e5b9ca40861 --- /dev/null +++ b/lib/ldb/tests/test-modify.ldif @@ -0,0 +1,23 @@ +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=TEST +changetype: modify +add: drink +drink: mango lassi +- +add: drink +drink: lemonade +- +delete: pager +- +replace: telephonenumber +telephonenumber: +61 2 6260 6012 +telephonenumber: +61 412 666 929 +- +delete: telephonenumber +telephonenumber: +61 2 6260 6012 +- +delete: telephonenumber +telephonenumber: +61 412 666 929 +- +add: telephonenumber +telephonenumber: +61 412 666 929 diff --git a/lib/ldb/tests/test-schema.sh b/lib/ldb/tests/test-schema.sh new file mode 100755 index 00000000000..97841844db8 --- /dev/null +++ b/lib/ldb/tests/test-schema.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +LDB_URL="tdb://schema.ldb" +export LDB_URL + +rm -f schema.ldb + +echo "LDB_URL: $LDB_URL" + +echo "Adding schema" +$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema.ldif || exit 1 + +echo "Adding few test elements (no failure expected here)" +$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema-add-test.ldif || exit 1 + +echo "Modifying elements (2 failures expected here)" + +$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-1.ldif || exit 1 +$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-2.ldif || exit 1 +$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-3.ldif || exit 1 +$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-4.ldif +if [ "$?" = "0" ]; then + echo "test failed!" + exit 1 +fi +$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif +if [ "$?" = "0" ]; then + echo "test failed!" + exit 1 +fi + +echo "Showing modified record" +$VALGRIND bin/ldbsearch '(cn=Test)' || exit 1 + diff --git a/lib/ldb/tests/test-soloading.sh b/lib/ldb/tests/test-soloading.sh new file mode 100755 index 00000000000..da6d57541e5 --- /dev/null +++ b/lib/ldb/tests/test-soloading.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +if [ -n "$TEST_DATA_PREFIX" ]; then + LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" +else + LDB_URL="tdbtest.ldb" +fi +export LDB_URL + +PATH=bin:$PATH +export PATH + +rm -f $LDB_URL* + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +cat <. +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "ldb_module.h" +#include "tools/cmdline.h" + +static struct ldb_cmdline options; /* needs to be static for older compilers */ + +enum ldb_cmdline_options { CMDLINE_RELAX=1 }; + +static struct poptOption builtin_popt_options[] = { + POPT_AUTOHELP + { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, + { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, + { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, + { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, + { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, + { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, + { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, + { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, + { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, + { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, + { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, + { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, + { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, + { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, + { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, + { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, + { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, + { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, + { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, + { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, + { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, + { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, + { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, + { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, + { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, + { NULL } +}; + +void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) +{ + poptContext pc; + struct poptOption **popt_options = ldb_module_popt_options(ldb); + pc = poptGetContext(cmdname, 0, NULL, *popt_options, + POPT_CONTEXT_KEEP_FIRST); + poptPrintHelp(pc, f, 0); +} + +/* + add a control to the options structure + */ +static bool add_control(TALLOC_CTX *mem_ctx, const char *control) +{ + unsigned int i; + + /* count how many controls we already have */ + for (i=0; options.controls && options.controls[i]; i++) ; + + options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); + if (options.controls == NULL) { + return false; + } + options.controls[i] = control; + options.controls[i+1] = NULL; + return true; +} + +/** + process command line options +*/ +struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, + int argc, const char **argv, + void (*usage)(struct ldb_context *)) +{ + struct ldb_cmdline *ret=NULL; + poptContext pc; + int num_options = 0; + int opt; + unsigned int flags = 0; + int rc; + struct poptOption **popt_options; + + /* make the ldb utilities line buffered */ + setlinebuf(stdout); + + ret = talloc_zero(ldb, struct ldb_cmdline); + if (ret == NULL) { + fprintf(stderr, "Out of memory!\n"); + goto failed; + } + + options = *ret; + + /* pull in URL */ + options.url = getenv("LDB_URL"); + + /* and editor (used by ldbedit) */ + options.editor = getenv("VISUAL"); + if (!options.editor) { + options.editor = getenv("EDITOR"); + } + if (!options.editor) { + options.editor = "vi"; + } + + options.scope = LDB_SCOPE_DEFAULT; + + popt_options = ldb_module_popt_options(ldb); + (*popt_options) = builtin_popt_options; + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + pc = poptGetContext(argv[0], argc, argv, *popt_options, + POPT_CONTEXT_KEEP_FIRST); + + while((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 's': { + const char *arg = poptGetOptArg(pc); + if (strcmp(arg, "base") == 0) { + options.scope = LDB_SCOPE_BASE; + } else if (strcmp(arg, "sub") == 0) { + options.scope = LDB_SCOPE_SUBTREE; + } else if (strcmp(arg, "one") == 0) { + options.scope = LDB_SCOPE_ONELEVEL; + } else { + fprintf(stderr, "Invalid scope '%s'\n", arg); + goto failed; + } + break; + } + + case 'v': + options.verbose++; + break; + + case 'o': + options.options = talloc_realloc(ret, options.options, + const char *, num_options+3); + if (options.options == NULL) { + fprintf(stderr, "Out of memory!\n"); + goto failed; + } + options.options[num_options] = poptGetOptArg(pc); + options.options[num_options+1] = NULL; + num_options++; + break; + + case 'c': { + const char *cs = poptGetOptArg(pc); + const char *p; + + for (p = cs; p != NULL; ) { + const char *t, *c; + + t = strchr(p, ','); + if (t == NULL) { + c = talloc_strdup(options.controls, p); + p = NULL; + } else { + c = talloc_strndup(options.controls, p, t-p); + p = t + 1; + } + if (c == NULL || !add_control(ret, c)) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + } + + break; + } + case 'P': + if (!add_control(ret, "paged_results:1:1024")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'D': + if (!add_control(ret, "show_deleted:1")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'R': + if (!add_control(ret, "show_recycled:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'd': + if (!add_control(ret, "show_deactivated_link:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'r': + if (!add_control(ret, "reveal_internals:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case CMDLINE_RELAX: + if (!add_control(ret, "relax:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'N': + if (!add_control(ret, "search_options:1:2")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'E': + if (!add_control(ret, "extended_dn:1:1")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + default: + fprintf(stderr, "Invalid option %s: %s\n", + poptBadOption(pc, 0), poptStrerror(opt)); + if (usage) usage(ldb); + goto failed; + } + } + + /* setup the remaining options for the main program to use */ + options.argv = poptGetArgs(pc); + if (options.argv) { + options.argv++; + while (options.argv[options.argc]) options.argc++; + } + + *ret = options; + + /* all utils need some option */ + if (ret->url == NULL) { + fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); + if (usage) usage(ldb); + goto failed; + } + + if (strcmp(ret->url, "NONE") == 0) { + return ret; + } + + if (options.nosync) { + flags |= LDB_FLG_NOSYNC; + } + + if (options.show_binary) { + flags |= LDB_FLG_SHOW_BINARY; + } + + if (options.tracing) { + flags |= LDB_FLG_ENABLE_TRACING; + } + + if (options.modules_path != NULL) { + ldb_set_modules_dir(ldb, options.modules_path); + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + /* now connect to the ldb */ + if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { + fprintf(stderr, "Failed to connect to %s - %s\n", + ret->url, ldb_errstring(ldb)); + goto failed; + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + exit(LDB_ERR_OPERATIONS_ERROR); + return NULL; +} + +/* this function check controls reply and determines if more + * processing is needed setting up the request controls correctly + * + * returns: + * -1 error + * 0 all ok + * 1 all ok, more processing required + */ +int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) +{ + unsigned int i, j; + int ret = 0; + + if (reply == NULL || request == NULL) return -1; + + for (i = 0; reply[i]; i++) { + if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { + struct ldb_vlv_resp_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); + + /* check we have a matching control in the request */ + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) + break; + } + if (! request[j]) { + fprintf(stderr, "Warning VLV reply received but no request have been made\n"); + continue; + } + + /* check the result */ + if (rep_control->vlv_result != 0) { + fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); + } else { + fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); + } + + continue; + } + + if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { + struct ldb_asq_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); + + /* check the result */ + if (rep_control->result != 0) { + fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); + } + + continue; + } + + if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { + struct ldb_paged_control *rep_control, *req_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + ret = 1; + + continue; + } + + if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { + struct ldb_sort_resp_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); + + /* check we have a matching control in the request */ + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) + break; + } + if (! request[j]) { + fprintf(stderr, "Warning Server Sort reply received but no request found\n"); + continue; + } + + /* check the result */ + if (rep_control->result != 0) { + fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); + } + + continue; + } + + if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { + struct ldb_dirsync_control *rep_control, *req_control; + char *cookie; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); + printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); + + continue; + } + + /* no controls matched, throw a warning */ + fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); + } + + return ret; +} + diff --git a/lib/ldb/tools/cmdline.h b/lib/ldb/tools/cmdline.h new file mode 100644 index 00000000000..416bf51d228 --- /dev/null +++ b/lib/ldb/tools/cmdline.h @@ -0,0 +1,56 @@ +/* + ldb database library - command line handling for ldb tools + + Copyright (C) Andrew Tridgell 2005 + + ** 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 . +*/ + +#include + +struct ldb_cmdline { + const char *url; + enum ldb_scope scope; + const char *basedn; + const char *modules_path; + int interactive; + int sorted; + const char *editor; + int verbose; + int recursive; + int all_records; + int nosync; + const char **options; + int argc; + const char **argv; + int num_records; + int num_searches; + const char *sasl_mechanism; + const char **controls; + int show_binary; + int tracing; +}; + +struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, + const char **argv, + void (*usage)(struct ldb_context *)); + + +int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); +void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); + diff --git a/lib/ldb/tools/ldbadd.c b/lib/ldb/tools/ldbadd.c new file mode 100644 index 00000000000..47fd2618416 --- /dev/null +++ b/lib/ldb/tools/ldbadd.c @@ -0,0 +1,154 @@ +/* + 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: ldbadd + * + * Description: utility to add records - modelled on ldapadd + * + * Author: Andrew Tridgell + */ + +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" + +static unsigned int failures; +static struct ldb_cmdline *options; + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbadd \n"); + printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); + ldb_cmdline_help(ldb, "ldbadd", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + + +/* + add records from an opened file +*/ +static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) +{ + struct ldb_ldif *ldif; + int fun_ret = LDB_SUCCESS, ret; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + + while ((ldif = ldb_ldif_read_file(ldb, f))) { + if (ldif->changetype != LDB_CHANGETYPE_ADD && + ldif->changetype != LDB_CHANGETYPE_NONE) { + fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); + break; + } + + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); + if (ret != LDB_SUCCESS) { + fprintf(stderr, + "ERR: Message canonicalize failed - %s\n", + ldb_strerror(ret)); + failures++; + fun_ret = ret; + ldb_ldif_read_free(ldb, ldif); + continue; + } + + ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); + if (ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: %s : \"%s\" on DN %s\n", + ldb_strerror(ret), ldb_errstring(ldb), + ldb_dn_get_linearized(ldif->msg->dn)); + failures++; + fun_ret = ret; + } else { + (*count)++; + if (options->verbose) { + printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); + } + } + ldb_ldif_read_free(ldb, ldif); + } + + return fun_ret; +} + + + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + unsigned int i, count = 0; + int ret = LDB_SUCCESS; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); + return ret; + } + + if (options->argc == 0) { + ret = process_file(ldb, stdin, &count); + } else { + for (i=0;iargc;i++) { + const char *fname = options->argv[i]; + FILE *f; + f = fopen(fname, "r"); + if (!f) { + perror(fname); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = process_file(ldb, f, &count); + fclose(f); + } + } + + if (count != 0) { + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); + return ret; + } + } else { + ldb_transaction_cancel(ldb); + } + + talloc_free(mem_ctx); + + printf("Added %u records with %u failures\n", count, failures); + + return ret; +} diff --git a/lib/ldb/tools/ldbdel.c b/lib/ldb/tools/ldbdel.c new file mode 100644 index 00000000000..8036d09a70d --- /dev/null +++ b/lib/ldb/tools/ldbdel.c @@ -0,0 +1,135 @@ +/* + 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: ldbdel + * + * Description: utility to delete records - modelled on ldapdelete + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" + +static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) +{ + return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); +} + +static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) +{ + int ret; + unsigned int i, total=0; + const char *attrs[] = { NULL }; + struct ldb_result *res; + + ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); + if (ret != LDB_SUCCESS) return ret; + + /* sort the DNs, deepest first */ + TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); + + for (i = 0; i < res->count; i++) { + if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { + total++; + } else { + printf("Failed to delete '%s' - %s\n", + ldb_dn_get_linearized(res->msgs[i]->dn), + ldb_errstring(ldb)); + } + } + + talloc_free(res); + + if (total == 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + printf("Deleted %u records\n", total); + return LDB_SUCCESS; +} + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbdel \n"); + printf("Deletes records from a ldb\n\n"); + ldb_cmdline_help(ldb, "ldbdel", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + struct ldb_control **req_ctrls; + struct ldb_cmdline *options; + struct ldb_context *ldb; + int ret = 0, i; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc < 1) { + usage(ldb); + } + + req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0;iargc;i++) { + struct ldb_dn *dn; + + dn = ldb_dn_new(ldb, ldb, options->argv[i]); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (options->recursive) { + ret = ldb_delete_recursive(ldb, dn,req_ctrls); + } else { + ret = ldb_delete_ctrl(ldb, dn,req_ctrls); + if (ret == LDB_SUCCESS) { + printf("Deleted 1 record\n"); + } + } + if (ret != LDB_SUCCESS) { + printf("delete of '%s' failed - (%s) %s\n", + ldb_dn_get_linearized(dn), + ldb_strerror(ret), + ldb_errstring(ldb)); + } + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/lib/ldb/tools/ldbedit.c b/lib/ldb/tools/ldbedit.c new file mode 100644 index 00000000000..aaf6d80352d --- /dev/null +++ b/lib/ldb/tools/ldbedit.c @@ -0,0 +1,372 @@ +/* + 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: ldbedit + * + * Description: utility for ldb database editing + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "system/filesys.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "tools/ldbutil.h" + +static struct ldb_cmdline *options; + +/* + debug routine +*/ +static void ldif_write_msg(struct ldb_context *ldb, + FILE *f, + enum ldb_changetype changetype, + struct ldb_message *msg) +{ + struct ldb_ldif ldif; + ldif.changetype = changetype; + ldif.msg = msg; + ldb_ldif_write_file(ldb, f, &ldif); +} + +/* + modify a database record so msg1 becomes msg2 + returns the number of modified elements +*/ +static int modify_record(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_control **req_ctrls) +{ + int ret; + struct ldb_message *mod; + + if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { + fprintf(stderr, "Failed to calculate message differences\n"); + return -1; + } + + ret = mod->num_elements; + if (ret == 0) { + goto done; + } + + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); + } + + if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to modify %s - %s\n", + ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); + ret = -1; + goto done; + } + +done: + talloc_free(mod); + return ret; +} + +/* + find dn in msgs[] +*/ +static struct ldb_message *msg_find(struct ldb_context *ldb, + struct ldb_message **msgs, + unsigned int count, + struct ldb_dn *dn) +{ + unsigned int i; + for (i=0;idn) == 0) { + return msgs[i]; + } + } + return NULL; +} + +/* + merge the changes in msgs2 into the messages from msgs1 +*/ +static int merge_edits(struct ldb_context *ldb, + struct ldb_message **msgs1, unsigned int count1, + struct ldb_message **msgs2, unsigned int count2) +{ + unsigned int i; + struct ldb_message *msg; + int ret; + unsigned int adds=0, modifies=0, deletes=0; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls == NULL) { + fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); + return -1; + } + + if (ldb_transaction_start(ldb) != LDB_SUCCESS) { + fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); + return -1; + } + + /* do the adds and modifies */ + for (i=0;idn); + if (!msg) { + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); + } + if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to add %s - %s\n", + ldb_dn_get_linearized(msgs2[i]->dn), + ldb_errstring(ldb)); + ldb_transaction_cancel(ldb); + return -1; + } + adds++; + } else { + ret = modify_record(ldb, msg, msgs2[i], req_ctrls); + if (ret != -1) { + modifies += (unsigned int) ret; + } else { + return -1; + } + } + } + + /* do the deletes */ + for (i=0;idn); + if (!msg) { + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); + } + if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to delete %s - %s\n", + ldb_dn_get_linearized(msgs1[i]->dn), + ldb_errstring(ldb)); + ldb_transaction_cancel(ldb); + return -1; + } + deletes++; + } + } + + if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { + fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); + return -1; + } + + printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); + + return 0; +} + +/* + save a set of messages as ldif to a file +*/ +static int save_ldif(struct ldb_context *ldb, + FILE *f, struct ldb_message **msgs, unsigned int count) +{ + unsigned int i; + + fprintf(f, "# editing %u records\n", count); + + for (i=0;imsg; + } + + /* the feof() test works here, even for the last line of the + * file, as we parse ldif files character by character, and + * feof() is only true if we have failed to read a character + * from the file. So if the last line is bad, we don't get + * feof() set, so we know the record was bad. Only if we + * attempt to go to the next record will we get feof() and + * thus consider that the ldif has ended without errors + */ + if (!feof(f)) { + fprintf(stderr, "Error parsing ldif - aborting\n"); + fclose(f); + unlink(file_template); + return -1; + } + + fclose(f); + unlink(file_template); + + return merge_edits(ldb, msgs1, count1, msgs2, count2); +} + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbedit \n"); + ldb_cmdline_help(ldb, "ldbedit", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + struct ldb_result *result = NULL; + struct ldb_dn *basedn = NULL; + int ret; + const char *expression = "(|(objectClass=*)(distinguishedName=*))"; + const char * const * attrs = NULL; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct ldb_control **req_ctrls; + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + /* the check for '=' is for compatibility with ldapsearch */ + if (options->argc > 0 && + strchr(options->argv[0], '=')) { + expression = options->argv[0]; + options->argv++; + options->argc--; + } + + if (options->argc > 0) { + attrs = (const char * const *)(options->argv); + } + + if (options->basedn != NULL) { + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if (basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); + if (ret != LDB_SUCCESS) { + printf("search failed - %s\n", ldb_errstring(ldb)); + return ret; + } + + if (result->count == 0) { + printf("no matching records - cannot edit\n"); + talloc_free(mem_ctx); + return LDB_SUCCESS; + } + + ret = do_edit(ldb, result->msgs, result->count, options->editor); + + talloc_free(mem_ctx); + + return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; +} diff --git a/lib/ldb/tools/ldbmodify.c b/lib/ldb/tools/ldbmodify.c new file mode 100644 index 00000000000..2ca7b62b2c3 --- /dev/null +++ b/lib/ldb/tools/ldbmodify.c @@ -0,0 +1,156 @@ +/* + 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: ldbmodify + * + * Description: utility to modify records - modelled on ldapmodify + * + * Author: Andrew Tridgell + */ + +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" + +static unsigned int failures; +static struct ldb_cmdline *options; + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbmodify \n"); + printf("Modifies a ldb based upon ldif change records\n\n"); + ldb_cmdline_help(ldb, "ldbmodify", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +/* + process modifies for one file +*/ +static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) +{ + struct ldb_ldif *ldif; + int fun_ret = LDB_SUCCESS, ret; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + while ((ldif = ldb_ldif_read_file(ldb, f))) { + struct ldb_dn *olddn; + bool deleteoldrdn = false; + struct ldb_dn *newdn; + const char *errstr = NULL; + + switch (ldif->changetype) { + case LDB_CHANGETYPE_NONE: + case LDB_CHANGETYPE_ADD: + ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); + break; + case LDB_CHANGETYPE_DELETE: + ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); + break; + case LDB_CHANGETYPE_MODIFY: + ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); + break; + case LDB_CHANGETYPE_MODRDN: + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, + NULL, &deleteoldrdn, + NULL, &newdn); + if (ret == LDB_SUCCESS) { + if (deleteoldrdn) { + ret = ldb_rename(ldb, olddn, newdn); + } else { + errstr = "modrdn: deleteoldrdn=0 " + "not supported."; + ret = LDB_ERR_CONSTRAINT_VIOLATION; + } + } + break; + } + if (ret != LDB_SUCCESS) { + if (errstr == NULL) { + errstr = ldb_errstring(ldb); + } + fprintf(stderr, "ERR: (%s) \"%s\" on DN %s\n", + ldb_strerror(ret), + errstr, ldb_dn_get_linearized(ldif->msg->dn)); + failures++; + fun_ret = ret; + } else { + (*count)++; + if (options->verbose) { + printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); + } + } + ldb_ldif_read_free(ldb, ldif); + } + + if (!feof(f)) { + fprintf(stderr, "Failed to parse ldif\n"); + fun_ret = LDB_ERR_OPERATIONS_ERROR; + } + + return fun_ret; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + unsigned int i, count = 0; + int ret = LDB_SUCCESS; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc == 0) { + ret = process_file(ldb, stdin, &count); + } else { + for (i=0;iargc;i++) { + const char *fname = options->argv[i]; + FILE *f; + f = fopen(fname, "r"); + if (!f) { + perror(fname); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = process_file(ldb, f, &count); + fclose(f); + } + } + + talloc_free(mem_ctx); + + printf("Modified %u records with %u failures\n", count, failures); + + return ret; +} diff --git a/lib/ldb/tools/ldbrename.c b/lib/ldb/tools/ldbrename.c new file mode 100644 index 00000000000..9bbd1f06b1a --- /dev/null +++ b/lib/ldb/tools/ldbrename.c @@ -0,0 +1,84 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 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: ldbrename + * + * Description: utility to rename records - modelled on ldapmodrdn + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +#include "ldb.h" +#include "tools/cmdline.h" + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbrename [] \n"); + printf("Renames records in a ldb\n\n"); + ldb_cmdline_help(ldb, "ldbmodify", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + int ret; + struct ldb_cmdline *options; + struct ldb_dn *dn1, *dn2; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc < 2) { + usage(ldb); + } + + dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); + dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); + if ((dn1 == NULL) || (dn2 == NULL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_rename(ldb, dn1, dn2); + if (ret == LDB_SUCCESS) { + printf("Renamed 1 record\n"); + } else { + printf("rename of '%s' to '%s' failed - %s\n", + options->argv[0], options->argv[1], ldb_errstring(ldb)); + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/lib/ldb/tools/ldbsearch.c b/lib/ldb/tools/ldbsearch.c new file mode 100644 index 00000000000..d10b9650daf --- /dev/null +++ b/lib/ldb/tools/ldbsearch.c @@ -0,0 +1,317 @@ +/* + 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: ldbsearch + * + * Description: utility for ldb search - modelled on ldapsearch + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "tools/cmdline.h" + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbsearch \n"); + ldb_cmdline_help(ldb, "ldbsearch", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +static int do_compare_msg(struct ldb_message **el1, + struct ldb_message **el2, + void *opaque) +{ + return ldb_dn_compare((*el1)->dn, (*el2)->dn); +} + +struct search_context { + struct ldb_context *ldb; + struct ldb_control **req_ctrls; + + int sort; + unsigned int num_stored; + struct ldb_message **store; + unsigned int refs_stored; + char **refs_store; + + unsigned int entries; + unsigned int refs; + + unsigned int pending; + int status; +}; + +static int store_message(struct ldb_message *msg, struct search_context *sctx) { + + sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); + if (!sctx->store) { + fprintf(stderr, "talloc_realloc failed while storing messages\n"); + return -1; + } + + sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); + sctx->num_stored++; + sctx->store[sctx->num_stored] = NULL; + + return 0; +} + +static int store_referral(char *referral, struct search_context *sctx) { + + sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs_stored + 2); + if (!sctx->refs_store) { + fprintf(stderr, "talloc_realloc failed while storing referrals\n"); + return -1; + } + + sctx->refs_store[sctx->refs_stored] = talloc_move(sctx->refs_store, &referral); + sctx->refs_stored++; + sctx->refs_store[sctx->refs_stored] = NULL; + + return 0; +} + +static int display_message(struct ldb_message *msg, struct search_context *sctx) { + struct ldb_ldif ldif; + + sctx->entries++; + printf("# record %d\n", sctx->entries); + + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = msg; + + if (sctx->sort) { + /* + * Ensure attributes are always returned in the same + * order. For testing, this makes comparison of old + * vs. new much easier. + */ + ldb_msg_sort_elements(ldif.msg); + } + + ldb_ldif_write_file(sctx->ldb, stdout, &ldif); + + return 0; +} + +static int display_referral(char *referral, struct search_context *sctx) +{ + + sctx->refs++; + printf("# Referral\nref: %s\n\n", referral); + + return 0; +} + +static int search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct search_context *sctx; + int ret = LDB_SUCCESS; + + sctx = talloc_get_type(req->context, struct search_context); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + if (sctx->sort) { + ret = store_message(ares->message, sctx); + } else { + ret = display_message(ares->message, sctx); + } + break; + + case LDB_REPLY_REFERRAL: + if (sctx->sort) { + ret = store_referral(ares->referral, sctx); + } else { + ret = display_referral(ares->referral, sctx); + } + if (ret) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + break; + + case LDB_REPLY_DONE: + if (ares->controls) { + if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) + sctx->pending = 1; + } + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + if (ret != LDB_SUCCESS) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +static int do_search(struct ldb_context *ldb, + struct ldb_dn *basedn, + struct ldb_cmdline *options, + const char *expression, + const char * const *attrs) +{ + struct ldb_request *req; + struct search_context *sctx; + int ret; + + req = NULL; + + sctx = talloc_zero(ldb, struct search_context); + if (!sctx) return LDB_ERR_OPERATIONS_ERROR; + + sctx->ldb = ldb; + sctx->sort = options->sorted; + sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); + if (options->controls != NULL && sctx->req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (basedn == NULL) { + basedn = ldb_get_default_basedn(ldb); + } + +again: + /* free any previous requests */ + if (req) talloc_free(req); + + ret = ldb_build_search_req(&req, ldb, ldb, + basedn, options->scope, + expression, attrs, + sctx->req_ctrls, + sctx, search_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(sctx); + printf("allocating request failed: %s\n", ldb_errstring(ldb)); + return ret; + } + + sctx->pending = 0; + + ret = ldb_request(ldb, req); + if (ret != LDB_SUCCESS) { + printf("search failed - %s\n", ldb_errstring(ldb)); + return ret; + } + + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + printf("search error - %s\n", ldb_errstring(ldb)); + return ret; + } + + if (sctx->pending) + goto again; + + if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { + unsigned int i; + + if (sctx->num_stored) { + LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); + } + for (i = 0; i < sctx->num_stored; i++) { + display_message(sctx->store[i], sctx); + } + + for (i = 0; i < sctx->refs_stored; i++) { + display_referral(sctx->refs_store[i], sctx); + } + } + + printf("# returned %u records\n# %u entries\n# %u referrals\n", + sctx->entries + sctx->refs, sctx->entries, sctx->refs); + + talloc_free(sctx); + talloc_free(req); + + return LDB_SUCCESS; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + struct ldb_dn *basedn = NULL; + const char * const * attrs = NULL; + struct ldb_cmdline *options; + int ret = -1; + const char *expression = "(|(objectClass=*)(distinguishedName=*))"; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + /* the check for '=' is for compatibility with ldapsearch */ + if (!options->interactive && + options->argc > 0 && + strchr(options->argv[0], '=')) { + expression = options->argv[0]; + options->argv++; + options->argc--; + } + + if (options->argc > 0) { + attrs = (const char * const *)(options->argv); + } + + if (options->basedn != NULL) { + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if (basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + if (options->interactive) { + char line[1024]; + while (fgets(line, sizeof(line), stdin)) { + ret = do_search(ldb, basedn, options, line, attrs); + } + } else { + ret = do_search(ldb, basedn, options, expression, attrs); + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/lib/ldb/tools/ldbtest.c b/lib/ldb/tools/ldbtest.c new file mode 100644 index 00000000000..4e181af9d55 --- /dev/null +++ b/lib/ldb/tools/ldbtest.c @@ -0,0 +1,434 @@ +/* + 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: ldbtest + * + * Description: utility to test ldb + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "tools/cmdline.h" + +static struct timespec tp1,tp2; +static struct ldb_cmdline *options; + +static void _start_timer(void) +{ + if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { + clock_gettime(CLOCK_REALTIME, &tp1); + } +} + +static double _end_timer(void) +{ + if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { + clock_gettime(CLOCK_REALTIME, &tp2); + } + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); +} + +static void add_records(struct ldb_context *ldb, + struct ldb_dn *basedn, + unsigned int count) +{ + struct ldb_message msg; + unsigned int i; + +#if 0 + if (ldb_lock(ldb, "transaction") != 0) { + printf("transaction lock failed\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } +#endif + for (i=0;icount != 1)) { + printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (uid >= nrecords && res->count > 0) { + printf("Found %s !? - %d\n", expr, ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + printf("Testing uid %d/%d - %d \r", i, uid, res->count); + fflush(stdout); + + talloc_free(res); + talloc_free(expr); + } + + printf("\n"); +} + +static void start_test(struct ldb_context *ldb, unsigned int nrecords, + unsigned int nsearches) +{ + struct ldb_dn *basedn; + + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if ( ! ldb_dn_validate(basedn)) { + printf("Invalid base DN format\n"); + exit(LDB_ERR_INVALID_DN_SYNTAX); + } + + printf("Adding %d records\n", nrecords); + add_records(ldb, basedn, nrecords); + + printf("Starting search on uid\n"); + _start_timer(); + search_uid(ldb, basedn, nrecords, nsearches); + printf("uid search took %.2f seconds\n", _end_timer()); + + printf("Modifying records\n"); + modify_records(ldb, basedn, nrecords); + + printf("Deleting records\n"); + delete_records(ldb, basedn, nrecords); +} + + +/* + 2) Store an @indexlist record + + 3) Store a record that contains fields that should be index according +to @index + + 4) disconnection from database + + 5) connect to same database + + 6) search for record added in step 3 using a search key that should +be indexed +*/ +static void start_test_index(struct ldb_context **ldb) +{ + struct ldb_message *msg; + struct ldb_result *res = NULL; + struct ldb_dn *indexlist; + struct ldb_dn *basedn; + int ret; + unsigned int flags = 0; + const char *specials; + + specials = getenv("LDB_SPECIALS"); + if (specials && atoi(specials) == 0) { + printf("LDB_SPECIALS disabled - skipping index test\n"); + return; + } + + if (options->nosync) { + flags |= LDB_FLG_NOSYNC; + } + + printf("Starting index test\n"); + + indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); + + ldb_delete(*ldb, indexlist); + + msg = ldb_msg_new(NULL); + + msg->dn = indexlist; + ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); + + if (ldb_add(*ldb, msg) != 0) { + printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + basedn = ldb_dn_new(*ldb, *ldb, options->basedn); + + memset(msg, 0, sizeof(*msg)); + msg->dn = ldb_dn_copy(msg, basedn); + ldb_dn_add_child_fmt(msg->dn, "cn=test"); + ldb_msg_add_string(msg, "cn", strdup("test")); + ldb_msg_add_string(msg, "sn", strdup("test")); + ldb_msg_add_string(msg, "uid", strdup("test")); + ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); + + if (ldb_add(*ldb, msg) != LDB_SUCCESS) { + printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (talloc_free(*ldb) != 0) { + printf("failed to free/close ldb database"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + (*ldb) = ldb_init(options, NULL); + + ret = ldb_connect(*ldb, options->url, flags, NULL); + if (ret != LDB_SUCCESS) { + printf("failed to connect to %s\n", options->url); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + basedn = ldb_dn_new(*ldb, *ldb, options->basedn); + msg->dn = basedn; + ldb_dn_add_child_fmt(msg->dn, "cn=test"); + + ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); + if (ret != LDB_SUCCESS) { + printf("Search with (uid=test) filter failed!\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if(res->count != 1) { + printf("Should have found 1 record - found %d\n", res->count); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); + + if (ldb_delete(*ldb, msg->dn) != 0 || + ldb_delete(*ldb, indexlist) != 0) { + printf("cleanup failed - %s\n", ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + printf("Finished index test\n"); +} + + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbtest \n"); + printf("Options:\n"); + printf(" -H ldb_url choose the database (or $LDB_URL)\n"); + printf(" --num-records nrecords database size to use\n"); + printf(" --num-searches nsearches number of searches to do\n"); + printf("\n"); + printf("tests ldb API\n\n"); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct ldb_context *ldb; + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + talloc_steal(mem_ctx, options); + + if (options->basedn == NULL) { + options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; + } + + srandom(1); + + printf("Testing with num-records=%d and num-searches=%d\n", + options->num_records, options->num_searches); + + start_test(ldb, + (unsigned int) options->num_records, + (unsigned int) options->num_searches); + + start_test_index(&ldb); + + talloc_free(mem_ctx); + + return LDB_SUCCESS; +} diff --git a/lib/ldb/tools/ldbutil.c b/lib/ldb/tools/ldbutil.c new file mode 100644 index 00000000000..26f252704c1 --- /dev/null +++ b/lib/ldb/tools/ldbutil.c @@ -0,0 +1,219 @@ +/* + ldb database library utility + + Copyright (C) Matthieu Patou 2009 + + ** 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 + * + * Description: Common function used by ldb_add/ldb_modify/ldb_delete + * + * Author: Matthieu Patou + */ + +#include "ldb.h" +#include "ldb_module.h" +#include "ldbutil.h" + + +/* autostarts a transacion if none active */ +static int ldb_do_autotransaction(struct ldb_context *ldb, + struct ldb_request *req) +{ + int ret; + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request(ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + return ldb_transaction_commit(ldb); + } + ldb_transaction_cancel(ldb); + + if (ldb_errstring(ldb) == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); + } + + return ret; +} +/* + Same as ldb_add but accept control +*/ +int ldb_add_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&req, ldb, ldb, + message, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + +/* + same as ldb_delete but accept control +*/ +int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_del_req(&req, ldb, ldb, + dn, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + same as ldb_modify, but accepts controls +*/ +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_mod_req(&req, ldb, ldb, + message, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + ldb_search with controls +*/ +int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + struct ldb_control **controls, + const char *exp_fmt, ...) +{ + struct ldb_request *req; + struct ldb_result *res; + char *expression; + va_list ap; + int ret; + + expression = NULL; + *result = NULL; + req = NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (exp_fmt) { + va_start(ap, exp_fmt); + expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); + va_end(ap); + + if (!expression) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ldb_build_search_req(&req, ldb, mem_ctx, + base?base:ldb_get_default_basedn(ldb), + scope, + expression, + attrs, + controls, + res, + ldb_search_default_callback, + NULL); + ldb_req_set_location(req, "ldb_search_ctrl"); + + if (ret != LDB_SUCCESS) goto done; + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + res = NULL; + } + + talloc_free(expression); + talloc_free(req); + + *result = res; + return ret; +} diff --git a/lib/ldb/tools/ldbutil.h b/lib/ldb/tools/ldbutil.h new file mode 100644 index 00000000000..f8d3f3a2106 --- /dev/null +++ b/lib/ldb/tools/ldbutil.h @@ -0,0 +1,46 @@ +/* + ldb database library utility header file + + Copyright (C) Matthieu Patou 2009 + + ** 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 + * + * Description: Common function used by ldb_add/ldb_modify/ldb_delete + * + * Author: Matthieu Patou + */ + +#include "ldb.h" + +int ldb_add_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls); +int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, + struct ldb_control **controls); +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls); +int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + struct ldb_control **controls, + const char *exp_fmt, ...); diff --git a/lib/ldb/web/index.html b/lib/ldb/web/index.html new file mode 100644 index 00000000000..7f50cdc63ad --- /dev/null +++ b/lib/ldb/web/index.html @@ -0,0 +1,74 @@ + + + +ldb + + + +

ldb

+ +ldb is a LDAP-like embedded database. It is not at all +LDAP +standards compliant, so if you want a standards compliant database then please +see the excellent OpenLDAP +project.

+ +What ldb does is provide a fast database with an LDAP-like API +designed to be used within an application. In some ways it can be seen +as a intermediate solution between key-value pair databases and a real +LDAP database.

+ +ldb is the database engine used in Samba4. + +

Features

+ +The main features that separate ldb from other solutions are: + +
    +
  • Safe multi-reader, multi-writer, using byte range locking +
  • LDAP-like API +
  • fast operation +
  • choice of local tdb or remote LDAP backends +
  • integration with talloc +
  • schema-less operation, for trivial setup +
  • modules for extensions (such as schema support) +
  • easy setup of indexes and attribute properties +
  • LDIF for import/export +
  • ldbedit tool for database (via LDIF) editing (reminiscent of 'vipw') +
+ +

Documentation

+ +Currently ldb is completely lacking in programmer or user +documentation. This is your opportunity to make a contribution! Start +with the public functions declared in ldb.h +and the example code in the tools +directory. Documentation in the same docbook format used by Samba +would be preferred. + +

Discussion and bug reports

+ +ldb does not have its own mailing list or bug tracking system. Please +use +the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

Download

+ +You can download the latest release here:
+ http://samba.org/ftp/pub/ldb + +Alternatively, you can fetch via git. See the following guide:
+Using Git for Samba Development
+ +
+ +Andrew Tridgell
+ldb AT tridgell.net +
+ + + diff --git a/lib/ldb/wscript b/lib/ldb/wscript new file mode 100755 index 00000000000..f1845546650 --- /dev/null +++ b/lib/ldb/wscript @@ -0,0 +1,287 @@ +#!/usr/bin/env python + +APPNAME = 'ldb' +VERSION = '1.1.0' + +blddir = 'bin' + +import sys, os + +# find the buildtools directory +srcdir = '.' +while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: + srcdir = '../' + srcdir +sys.path.insert(0, srcdir + '/buildtools/wafsamba') + +import wafsamba, samba_dist, Options + +samba_dist.DIST_DIRS('''lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc + lib/tdb:lib/tdb lib/tdb2:lib/tdb2 lib/tdb_compat:lib/tdb_compat lib/ccan:lib/ccan lib/tevent:lib/tevent lib/popt:lib/popt + buildtools:buildtools''') + + +def set_options(opt): + opt.BUILTIN_DEFAULT('replace') + opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') + opt.RECURSE('lib/tdb_compat') + opt.RECURSE('lib/tevent') + opt.RECURSE('lib/replace') + opt.tool_options('python') # options for disabling pyc or pyo compilation + +def configure(conf): + conf.RECURSE('lib/tdb_compat') + conf.RECURSE('lib/tevent') + conf.RECURSE('lib/popt') + conf.RECURSE('lib/replace') + conf.RECURSE('lib/tdb_compat') + conf.find_program('python', var='PYTHON') + conf.find_program('xsltproc', var='XSLTPROC') + conf.check_tool('python') + conf.check_python_version((2,4,2)) + conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=True) + + # This make #include work. + conf.ADD_EXTRA_INCLUDES('''#lib''') + + # where does the default LIBDIR end up? in conf.env somewhere? + # + conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') + + conf.env.standalone_ldb = conf.IN_LAUNCH_DIR() + + if not conf.env.standalone_ldb: + if conf.CHECK_BUNDLED_SYSTEM('ldb', minversion=VERSION, + onlyif='talloc tdb tevent', + implied_deps='replace talloc tdb tevent'): + conf.define('USING_SYSTEM_LDB', 1) + if conf.CHECK_BUNDLED_SYSTEM('pyldb-util', minversion=VERSION, + onlyif='talloc tdb tevent ldb', + implied_deps='replace talloc tdb tevent ldb'): + conf.define('USING_SYSTEM_PYLDB_UTIL', 1) + + if conf.env.standalone_ldb: + conf.CHECK_XSLTPROC_MANPAGES() + + # we need this for the ldap backend + if conf.CHECK_FUNCS_IN('ber_flush ldap_open ldap_initialize', 'lber ldap', headers='lber.h ldap.h'): + conf.env.ENABLE_LDAP_BACKEND = True + + conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) + + # we don't want any libraries or modules to rely on runtime + # resolution of symbols + if sys.platform != "openbsd4": + conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) + + conf.SAMBA_CONFIG_H() + +def build(bld): + bld.RECURSE('lib/tdb_compat') + bld.RECURSE('lib/tevent') + bld.RECURSE('lib/popt') + bld.RECURSE('lib/replace') + bld.RECURSE('lib/tdb_compat') + + if bld.env.standalone_ldb: + private_library = False + ldb_pc_files='ldb.pc' + pyldb_pc_files='pyldb-util.pc' + else: + private_library = True + ldb_pc_files=None + pyldb_pc_files=None + + LDB_MAP_SRC = bld.SUBDIR('ldb_map', + 'ldb_map.c ldb_map_inbound.c ldb_map_outbound.c') + + 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_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') + + bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', + init_function='ldb_ldap_init', + module_init_name='ldb_init_module', + deps='talloc lber ldap ldb', + enabled=bld.env.ENABLE_LDAP_BACKEND, + internal_module=False, + subsystem='ldb') + + # we're not currently linking against the ldap libs, but ldb.pc.in + # has @LDAP_LIBS@ + bld.env.LDAP_LIBS = '' + + if not 'PACKAGE_VERSION' in bld.env: + bld.env.PACKAGE_VERSION = VERSION + bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' + + if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): + bld.SAMBA_LIBRARY('pyldb-util', + deps='ldb pytalloc-util', + source='pyldb_util.c', + public_headers='pyldb.h', + public_headers_install=not private_library, + vnum=VERSION, + private_library=private_library, + pc_files=pyldb_pc_files, + pyext=True) + + if not bld.CONFIG_SET('USING_SYSTEM_LDB'): + if Options.is_install: + modules_dir = bld.EXPAND_VARIABLES('${LDB_MODULESDIR}') + else: + # when we run from the source directory, we want to use + # the current modules, not the installed ones + modules_dir = os.path.join(os.getcwd(), 'bin/modules/ldb') + + abi_match = '!ldb_*module_ops !ldb_*backend_ops ldb_*' + + bld.SAMBA_LIBRARY('ldb', + COMMON_SRC + ' ' + LDB_MAP_SRC, + deps='tevent LIBLDB_MAIN', + includes='include', + public_headers='include/ldb.h include/ldb_errors.h '\ + 'include/ldb_module.h include/ldb_handlers.h', + public_headers_install=not private_library, + pc_files=ldb_pc_files, + vnum=VERSION, + private_library=private_library, + manpages='man/ldb.3', + abi_directory = 'ABI', + abi_match = abi_match) + + # generate a include/ldb_version.h + t = bld.SAMBA_GENERATOR('ldb_version.h', + rule='echo "#define LDB_VERSION \\"${LDB_VERSION}\\"" > ${TGT}', + target='include/ldb_version.h', + public_headers='include/ldb_version.h', + public_headers_install=not private_library) + t.env.LDB_VERSION = VERSION + bld.add_manual_dependency(bld.path.find_or_declare('include/ldb_version.h'), VERSION) + + + + bld.SAMBA_PYTHON('pyldb', 'pyldb.c', + deps='ldb pyldb-util', + realname='ldb.so', + cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) + + bld.SAMBA_MODULE('ldb_paged_results', + 'modules/paged_results.c', + init_function='ldb_paged_results_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_asq', + 'modules/asq.c', + init_function='ldb_asq_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_server_sort', + 'modules/sort.c', + init_function='ldb_server_sort_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_paged_searches', + 'modules/paged_searches.c', + init_function='ldb_paged_searches_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_rdn_name', + 'modules/rdn_name.c', + init_function='ldb_rdn_name_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_sample', + 'tests/sample_module.c', + init_function='ldb_sample_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_skel', + 'modules/skel.c', + init_function='ldb_skel_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_sqlite3', + 'sqlite3/ldb_sqlite3.c', + init_function='ldb_sqlite3_init', + internal_module=False, + module_init_name='ldb_init_module', + enabled=False, + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_tdb', + bld.SUBDIR('ldb_tdb', + '''ldb_tdb.c ldb_pack.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', + internal_module=False, + deps='tdb_compat ldb', + subsystem='ldb') + + # have a separate subsystem for common/ldb.c, so it can rebuild + # for install with a different -DLDB_MODULESDIR= + bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', + 'common/ldb.c', + deps='tevent tdb_compat', + includes='include', + cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) + + LDB_TOOLS='ldbadd ldbsearch ldbdel ldbmodify ldbedit ldbrename' + for t in LDB_TOOLS.split(): + bld.SAMBA_BINARY(t, 'tools/%s.c' % t, deps='ldb-cmdline ldb', + manpages='man/%s.1' % t) + + # ldbtest doesn't get installed + bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', + install=False) + + bld.SAMBA_LIBRARY('ldb-cmdline', + source='tools/ldbutil.c tools/cmdline.c', + deps='ldb dl popt', + private_library=True) + + +def test(ctx): + '''run ldb testsuite''' + import Utils, samba_utils, shutil + test_prefix = "%s/st" % (Utils.g_module.blddir) + shutil.rmtree(test_prefix, ignore_errors=True) + os.makedirs(test_prefix) + os.environ['TEST_DATA_PREFIX'] = test_prefix + cmd = 'tests/test-tdb.sh' + ret = samba_utils.RUN_COMMAND(cmd) + print("testsuite returned %d" % ret) + # FIXME: Run python testsuite + sys.exit(ret) + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() + +def reconfigure(ctx): + '''reconfigure if config scripts have changed''' + import samba_utils + samba_utils.reconfigure(ctx) diff --git a/script/autobuild.py b/script/autobuild.py index 545e47ed489..3a8c0f81f05 100755 --- a/script/autobuild.py +++ b/script/autobuild.py @@ -18,7 +18,7 @@ builddirs = { "samba3" : "source3", "samba3-waf": "source3", "samba4" : ".", - "ldb" : "source4/lib/ldb", + "ldb" : "lib/ldb", "tdb" : "lib/tdb", "talloc" : "lib/talloc", "replace" : "lib/replace", @@ -59,7 +59,7 @@ tasks = { ("make", "make -j", "text/plain"), ("install", "make install", "text/plain"), ("test", "TDB_NO_FSYNC=1 make test", "text/plain"), - ("check-clean-tree", "../../../script/clean-source-tree.sh", "text/plain"), + ("check-clean-tree", "../../script/clean-source-tree.sh", "text/plain"), ("distcheck", "make distcheck", "text/plain"), ("clean", "make clean", "text/plain") ], diff --git a/script/land.py b/script/land.py index f8ae7b4493d..72bdd4b8408 100755 --- a/script/land.py +++ b/script/land.py @@ -41,7 +41,7 @@ tasks = { ("install", "make install", "text/plain"), ("test", "TDB_NO_FSYNC=1 make subunit-test", "text/x-subunit") ], - "source4/lib/ldb" : [ ("configure", "./configure --enable-developer -C ${PREFIX}", "text/plain"), + "lib/ldb" : [ ("configure", "./configure --enable-developer -C ${PREFIX}", "text/plain"), ("make", "make -j", "text/plain"), ("install", "make install", "text/plain"), ("test", "make test", "text/plain") ], diff --git a/source4/lib/ldb-samba/README b/source4/lib/ldb-samba/README deleted file mode 100644 index 3fa47159ca9..00000000000 --- a/source4/lib/ldb-samba/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains Samba specific extensions to ldb. It also -serves as example code on how to extend ldb for your own application. - -The main extension Samba uses is to provide ldif encode/decode -routines for specific attributes, so users can get nice pretty -printing of attributes in ldbedit, while the attributes are stored in -the standard NDR format in the database. diff --git a/source4/lib/ldb-samba/ldb_ildap.c b/source4/lib/ldb-samba/ldb_ildap.c deleted file mode 100644 index 3c28690bd66..00000000000 --- a/source4/lib/ldb-samba/ldb_ildap.c +++ /dev/null @@ -1,879 +0,0 @@ -/* - ldb database library - ildap backend - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Simo Sorce 2008 - - ** 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_ildap - * - * Component: ldb ildap backend - * - * Description: This is a ldb backend for the internal ldap - * client library in Samba4. By using this backend we are - * independent of a system ldap library - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - -#include "includes.h" -#include "ldb_module.h" -#include "util/dlinklist.h" - -#include "libcli/ldap/libcli_ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "auth/auth.h" -#include "auth/credentials/credentials.h" - -struct ildb_private { - struct ldap_connection *ldap; - struct tevent_context *event_ctx; -}; - -struct ildb_context { - struct ldb_module *module; - struct ldb_request *req; - - struct ildb_private *ildb; - struct ldap_request *ireq; - - /* indicate we are already processing - * the ldap_request in ildb_callback() */ - bool in_ildb_callback; - - bool done; - - struct ildb_destructor_ctx *dc; -}; - -static void ildb_request_done(struct ildb_context *ctx, - struct ldb_control **ctrls, int error) -{ - struct ldb_context *ldb; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - - ctx->done = true; - - if (ctx->req == NULL) { - /* if the req has been freed already just return */ - return; - } - - ares = talloc_zero(ctx->req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - ctx->req->callback(ctx->req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->error = error; - - ctx->req->callback(ctx->req, ares); -} - -static void ildb_auto_done_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct ildb_context *ac; - - ac = talloc_get_type(private_data, struct ildb_context); - ildb_request_done(ac, NULL, LDB_SUCCESS); -} - -/* - convert a ldb_message structure to a list of ldap_mod structures - ready for ildap_add() or ildap_modify() -*/ -static struct ldap_mod **ildb_msg_to_mods(void *mem_ctx, int *num_mods, - const struct ldb_message *msg, - int use_flags) -{ - struct ldap_mod **mods; - unsigned int i; - int n = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, struct ldap_mod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[n] = talloc(mods, struct ldap_mod); - if (!mods[n]) { - goto failed; - } - mods[n + 1] = NULL; - mods[n]->type = 0; - mods[n]->attrib = *el; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[n]->type = LDAP_MODIFY_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[n]->type = LDAP_MODIFY_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[n]->type = LDAP_MODIFY_REPLACE; - break; - } - } - n++; - } - - *num_mods = n; - return mods; - -failed: - talloc_free(mods); - return NULL; -} - - -/* - map an ildap NTSTATUS to a ldb error code -*/ -static int ildb_map_error(struct ldb_module *module, NTSTATUS status) -{ - struct ildb_private *ildb; - struct ldb_context *ldb; - TALLOC_CTX *mem_ctx; - - ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); - ldb = ldb_module_get_ctx(module); - - if (NT_STATUS_IS_OK(status)) { - return LDB_SUCCESS; - } - - mem_ctx = talloc_new(ildb); - if (!mem_ctx) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ldb_set_errstring(ldb, - ldap_errstr(ildb->ldap, mem_ctx, status)); - talloc_free(mem_ctx); - if (NT_STATUS_IS_LDAP(status)) { - return NT_STATUS_LDAP_CODE(status); - } - return LDB_ERR_OPERATIONS_ERROR; -} - -static void ildb_request_timeout(struct tevent_context *ev, struct tevent_timer *te, - struct timeval t, void *private_data) -{ - struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context); - - if (ac->ireq->state == LDAP_REQUEST_PENDING) { - DLIST_REMOVE(ac->ireq->conn->pending, ac->ireq); - } - - ildb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void ildb_callback(struct ldap_request *req) -{ - struct ldb_context *ldb; - struct ildb_context *ac; - NTSTATUS status; - struct ldap_SearchResEntry *search; - struct ldap_message *msg; - struct ldb_control **controls; - struct ldb_message *ldbmsg; - char *referral; - bool callback_failed; - bool request_done; - int ret; - int i; - - ac = talloc_get_type(req->async.private_data, struct ildb_context); - ldb = ldb_module_get_ctx(ac->module); - callback_failed = false; - request_done = false; - controls = NULL; - - /* check if we are already processing this request */ - if (ac->in_ildb_callback) { - return; - } - /* mark the request as being in process */ - ac->in_ildb_callback = true; - - if (!NT_STATUS_IS_OK(req->status)) { - ret = ildb_map_error(ac->module, req->status); - ildb_request_done(ac, NULL, ret); - return; - } - - if (req->num_replies < 1) { - ret = LDB_ERR_OPERATIONS_ERROR; - ildb_request_done(ac, NULL, ret); - return; - } - - switch (req->type) { - - case LDAP_TAG_ModifyRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_AddRequest: - if (req->replies[0]->type != LDAP_TAG_AddResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_DelRequest: - if (req->replies[0]->type != LDAP_TAG_DelResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_ModifyDNRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyDNResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_SearchRequest: - /* loop over all messages */ - for (i = 0; i < req->num_replies; i++) { - - msg = req->replies[i]; - switch (msg->type) { - - case LDAP_TAG_SearchResultDone: - - status = ldap_check_response(ac->ireq->conn, &msg->r.GeneralResult); - if (!NT_STATUS_IS_OK(status)) { - ret = ildb_map_error(ac->module, status); - break; - } - - controls = talloc_steal(ac, msg->controls); - if (msg->r.SearchResultDone.resultcode) { - if (msg->r.SearchResultDone.errormessage) { - ldb_set_errstring(ldb, msg->r.SearchResultDone.errormessage); - } - } - - ret = msg->r.SearchResultDone.resultcode; - request_done = true; - break; - - case LDAP_TAG_SearchResultEntry: - - ldbmsg = ldb_msg_new(ac); - if (!ldbmsg) { - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - search = &(msg->r.SearchResultEntry); - - ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, search->dn); - if ( ! ldb_dn_validate(ldbmsg->dn)) { - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - ldbmsg->num_elements = search->num_attributes; - ldbmsg->elements = talloc_move(ldbmsg, &search->attributes); - - controls = talloc_steal(ac, msg->controls); - - ret = ldb_module_send_entry(ac->req, ldbmsg, controls); - if (ret != LDB_SUCCESS) { - callback_failed = true; - } - - break; - - case LDAP_TAG_SearchResultReference: - - referral = talloc_strdup(ac, msg->r.SearchResultReference.referral); - - ret = ldb_module_send_referral(ac->req, referral); - if (ret != LDB_SUCCESS) { - callback_failed = true; - } - - break; - - default: - /* TAG not handled, fail ! */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - break; - } - } - - talloc_free(req->replies); - req->replies = NULL; - req->num_replies = 0; - - break; - - default: - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - - /* if the callback failed the caller will have freed the - * request. Just return and don't try to use it */ - if ( ! callback_failed) { - request_done = true; - } - } - - /* mark the request as not being in progress */ - ac->in_ildb_callback = false; - - if (request_done) { - ildb_request_done(ac, controls, ret); - } - - return; -} - -static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg) -{ - struct ldb_context *ldb; - struct ldap_request *req; - - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb = ldb_module_get_ctx(ac->module); - - ldb_request_set_state(ac->req, LDB_ASYNC_PENDING); - - req = ldap_request_send(ac->ildb->ldap, msg); - if (req == NULL) { - ldb_set_errstring(ldb, "async send request failed"); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->ireq = talloc_reparent(ac->ildb->ldap, ac, req); - - if (!ac->ireq->conn) { - ldb_set_errstring(ldb, "connection to remote LDAP server dropped?"); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_free(req->time_event); - req->time_event = NULL; - if (ac->req->timeout) { - req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, - timeval_current_ofs(ac->req->timeout, 0), - ildb_request_timeout, ac); - } - - req->async.fn = ildb_callback; - req->async.private_data = ac; - - return LDB_SUCCESS; -} - -/* - search for matching records using an asynchronous function - */ -static int ildb_search(struct ildb_context *ac) -{ - struct ldb_context *ldb; - struct ldb_request *req = ac->req; - struct ldap_message *msg; - int n; - - ldb = ldb_module_get_ctx(ac->module); - - if (!req->callback || !req->context) { - ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = new_ldap_message(req); - if (msg == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_SearchRequest; - - if (req->op.search.base == NULL) { - msg->r.SearchRequest.basedn = talloc_strdup(msg, ""); - } else { - msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0); - } - if (msg->r.SearchRequest.basedn == NULL) { - ldb_set_errstring(ldb, "Unable to determine baseDN"); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.scope == LDB_SCOPE_DEFAULT) { - msg->r.SearchRequest.scope = LDB_SCOPE_SUBTREE; - } else { - msg->r.SearchRequest.scope = req->op.search.scope; - } - - msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - msg->r.SearchRequest.timelimit = 0; - msg->r.SearchRequest.sizelimit = 0; - msg->r.SearchRequest.attributesonly = 0; - msg->r.SearchRequest.tree = discard_const(req->op.search.tree); - - for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ; - msg->r.SearchRequest.num_attributes = n; - msg->r.SearchRequest.attributes = req->op.search.attrs; - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - add a record -*/ -static int ildb_add(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0); - if (msg->r.AddRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.add.message, 0); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.AddRequest.num_attributes = n; - msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); - if (msg->r.AddRequest.attributes == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.AddRequest.attributes[i] = mods[i]->attrib; - } - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - modify a record -*/ -static int ildb_modify(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0); - if (msg->r.ModifyRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.mod.message, 1); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyRequest.num_mods = n; - msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); - if (msg->r.ModifyRequest.mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.ModifyRequest.mods[i] = *mods[i]; - } - msg->controls = req->controls; - return ildb_request_send(ac, msg); -} - -/* - delete a record -*/ -static int ildb_delete(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_DelRequest; - - msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0); - if (msg->r.DelRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - rename a record -*/ -static int ildb_rename(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - const char *rdn_name; - const struct ldb_val *rdn_val; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0); - if (msg->r.ModifyDNRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); - rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); - - if ((rdn_name != NULL) && (rdn_val != NULL)) { - msg->r.ModifyDNRequest.newrdn = - talloc_asprintf(msg, "%s=%s", rdn_name, - rdn_val->length > 0 ? ldb_dn_escape_value(msg, *rdn_val) : ""); - } else { - msg->r.ModifyDNRequest.newrdn = talloc_strdup(msg, ""); - } - if (msg->r.ModifyDNRequest.newrdn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyDNRequest.newsuperior = - ldb_dn_alloc_linearized(msg, ldb_dn_get_parent(msg, req->op.rename.newdn)); - if (msg->r.ModifyDNRequest.newsuperior == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - msg->r.ModifyDNRequest.deleteolddn = true; - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -static int ildb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static bool ildb_dn_is_special(struct ldb_request *req) -{ - struct ldb_dn *dn = NULL; - - switch (req->operation) { - case LDB_ADD: - dn = req->op.add.message->dn; - break; - case LDB_MODIFY: - dn = req->op.mod.message->dn; - break; - case LDB_DELETE: - dn = req->op.del.dn; - break; - case LDB_RENAME: - dn = req->op.rename.olddn; - break; - default: - break; - } - - if (dn && ldb_dn_is_special(dn)) { - return true; - } - return false; -} - -static int ildb_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ildb_private *ildb; - struct ildb_context *ac; - struct tevent_timer *te; - int ret; - - ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); - ldb = ldb_module_get_ctx(module); - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ac = talloc_zero(req, struct ildb_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->ildb = ildb; - - if (ildb_dn_is_special(req)) { - - te = tevent_add_timer(ac->ildb->event_ctx, - ac, timeval_zero(), - ildb_auto_done_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; - } - - switch (ac->req->operation) { - case LDB_SEARCH: - ret = ildb_search(ac); - break; - case LDB_ADD: - ret = ildb_add(ac); - break; - case LDB_MODIFY: - ret = ildb_modify(ac); - break; - case LDB_DELETE: - ret = ildb_delete(ac); - break; - case LDB_RENAME: - ret = ildb_rename(ac); - break; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - return ret; -} - -static const struct ldb_module_ops ildb_ops = { - .name = "ldap", - .search = ildb_handle_request, - .add = ildb_handle_request, - .modify = ildb_handle_request, - .del = ildb_handle_request, - .rename = ildb_handle_request, -/* .request = ildb_handle_request, */ - .start_transaction = ildb_start_trans, - .end_transaction = ildb_end_trans, - .del_transaction = ildb_del_trans, -}; - -/* - connect to the database -*/ -static int ildb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct ildb_private *ildb; - NTSTATUS status; - struct cli_credentials *creds; - struct loadparm_context *lp_ctx; - - module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - ildb = talloc(module, struct ildb_private); - if (!ildb) { - ldb_oom(ldb); - goto failed; - } - ldb_module_set_private(module, ildb); - - ildb->event_ctx = ldb_get_event_context(ldb); - - lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), - struct loadparm_context); - - ildb->ldap = ldap4_new_connection(ildb, lp_ctx, - ildb->event_ctx); - if (!ildb->ldap) { - ldb_oom(ldb); - goto failed; - } - - if (flags & LDB_FLG_RECONNECT) { - ldap_set_reconn_params(ildb->ldap, 10); - } - - status = ldap_connect(ildb->ldap, url); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s", - url, ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - - /* caller can optionally setup credentials using the opaque token 'credentials' */ - creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials); - if (creds == NULL) { - struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info); - if (session_info) { - creds = session_info->credentials; - } - } - - if (creds != NULL && cli_credentials_authentication_requested(creds)) { - const char *bind_dn = cli_credentials_get_bind_dn(creds); - if (bind_dn) { - const char *password = cli_credentials_get_password(creds); - status = ldap_bind_simple(ildb->ldap, bind_dn, password); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", - ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - } else { - status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", - ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - } - } - - *_module = module; - return LDB_SUCCESS; - -failed: - talloc_free(module); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - initialise the module - */ -_PUBLIC_ int ldb_ildap_init(const char *ldb_version) -{ - int ret, i; - const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; - for (i=0; names[i]; i++) { - ret = ldb_register_backend(names[i], ildb_connect, true); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/ldb_wrap.c b/source4/lib/ldb-samba/ldb_wrap.c deleted file mode 100644 index 66213bf2881..00000000000 --- a/source4/lib/ldb-samba/ldb_wrap.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - LDB wrap functions - - Copyright (C) Andrew Tridgell 2004-2009 - - 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 . -*/ - -/* - the stupidity of the unix fcntl locking design forces us to never - allow a database file to be opened twice in the same process. These - wrappers provide convenient access to a tdb or ldb, taking advantage - of talloc destructors to ensure that only a single open is done -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include -#include -#include "lib/ldb-samba/ldif_handlers.h" -#include "ldb_wrap.h" -#include "dsdb/samdb/samdb.h" -#include "param/param.h" -#include "../lib/util/dlinklist.h" -#include "../lib/tdb_compat/tdb_compat.h" - -/* - this is used to catch debug messages from ldb -*/ -static void ldb_wrap_debug(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void ldb_wrap_debug(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - int samba_level = -1; - char *s = NULL; - switch (level) { - case LDB_DEBUG_FATAL: - samba_level = 0; - break; - case LDB_DEBUG_ERROR: - samba_level = 1; - break; - case LDB_DEBUG_WARNING: - samba_level = 2; - break; - case LDB_DEBUG_TRACE: - samba_level = 5; - break; - - }; - vasprintf(&s, fmt, ap); - if (!s) return; - DEBUG(samba_level, ("ldb: %s\n", s)); - free(s); -} - - -/* - connecting to a ldb can be a relatively expensive operation because - of the schema and partition loads. We keep a list of open ldb - contexts here, and try to re-use when possible. - - This means callers of ldb_wrap_connect() must use talloc_unlink() or - the free of a parent to destroy the context - */ -static struct ldb_wrap { - struct ldb_wrap *next, *prev; - struct ldb_wrap_context { - /* the context is what we use to tell if two ldb - * connections are exactly equivalent - */ - const char *url; - struct tevent_context *ev; - struct loadparm_context *lp_ctx; - struct auth_session_info *session_info; - struct cli_credentials *credentials; - unsigned int flags; - } context; - struct ldb_context *ldb; -} *ldb_wrap_list; - -/* - free a ldb_wrap structure - */ -static int ldb_wrap_destructor(struct ldb_wrap *w) -{ - DLIST_REMOVE(ldb_wrap_list, w); - return 0; -} - -/* - * The casefolder for s4's LDB databases - Unicode-safe - */ -char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) -{ - return strupper_talloc_n(mem_ctx, s, n); -} - - - struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_init(mem_ctx, ev); - if (ldb == NULL) { - return NULL; - } - - ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); - - ldb_set_debug(ldb, ldb_wrap_debug, NULL); - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - - if (session_info) { - if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { - talloc_free(ldb); - return NULL; - } - } - - if (credentials) { - if (ldb_set_opaque(ldb, "credentials", credentials)) { - talloc_free(ldb); - return NULL; - } - } - - if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) { - talloc_free(ldb); - return NULL; - } - - /* This must be done before we load the schema, as these - * handlers for objectSid and objectGUID etc must take - * precedence over the 'binary attribute' declaration in the - * schema */ - ret = ldb_register_samba_handlers(ldb); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - /* we usually want Samba databases to be private. If we later - find we need one public, we will need to add a parameter to - ldb_wrap_connect() */ - ldb_set_create_perms(ldb, 0600); - - return ldb; -} - - struct ldb_context *ldb_wrap_find(const char *url, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags) -{ - struct ldb_wrap *w; - /* see if we can re-use an existing ldb */ - for (w=ldb_wrap_list; w; w=w->next) { - if (w->context.ev == ev && - w->context.lp_ctx == lp_ctx && - w->context.session_info == session_info && - w->context.credentials == credentials && - w->context.flags == flags && - (w->context.url == url || strcmp(w->context.url, url) == 0)) - return w->ldb; - } - - return NULL; -} - -int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, unsigned int flags) -{ - int ret; - char *real_url = NULL; - - /* allow admins to force non-sync ldb for all databases */ - if (lpcfg_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) { - flags |= LDB_FLG_NOSYNC; - } - - if (DEBUGLVL(10)) { - flags |= LDB_FLG_ENABLE_TRACING; - } - - real_url = lpcfg_private_path(ldb, lp_ctx, url); - if (real_url == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_connect(ldb, real_url, flags, NULL); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* setup for leak detection */ - ldb_set_opaque(ldb, "wrap_url", real_url); - - return LDB_SUCCESS; -} - - bool ldb_wrap_add(const char *url, struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags, - struct ldb_context *ldb) -{ - struct ldb_wrap *w; - struct ldb_wrap_context c; - - /* add to the list of open ldb contexts */ - w = talloc(ldb, struct ldb_wrap); - if (w == NULL) { - return false; - } - - c.url = url; - c.ev = ev; - c.lp_ctx = lp_ctx; - c.session_info = session_info; - c.credentials = credentials; - c.flags = flags; - - w->context = c; - w->context.url = talloc_strdup(w, url); - if (w->context.url == NULL) { - return false; - } - - if (session_info) { - /* take a reference to the session_info, as it is - * possible for the ldb to live longer than the - * session_info. This happens when a DRS DsBind call - * reuses a handle, but the original connection is - * shutdown. The token for the new connection is still - * valid, so we need the session_info to remain valid for - * ldb modules to use - */ - if (talloc_reference(w, session_info) == NULL) { - return false; - } - } - - w->ldb = ldb; - - DLIST_ADD(ldb_wrap_list, w); - - talloc_set_destructor(w, ldb_wrap_destructor); - - return true; -} - - -/* - wrapped connection to a ldb database - to close just talloc_free() the returned ldb_context - - TODO: We need an error_string parameter - */ - struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - const char *url, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_wrap_find(url, ev, lp_ctx, session_info, credentials, flags); - if (ldb != NULL) - return talloc_reference(mem_ctx, ldb); - - ldb = samba_ldb_init(mem_ctx, ev, lp_ctx, session_info, credentials); - - if (ldb == NULL) - return NULL; - - ret = samba_ldb_connect(ldb, lp_ctx, url, flags); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - if (!ldb_wrap_add(url, ev, lp_ctx, session_info, credentials, flags, ldb)) { - talloc_free(ldb); - return NULL; - } - - DEBUG(3,("ldb_wrap open of %s\n", url)); - - return ldb; -} - -/* - when we fork() we need to make sure that any open ldb contexts have - any open transactions cancelled - */ - void ldb_wrap_fork_hook(void) -{ - struct ldb_wrap *w; - - for (w=ldb_wrap_list; w; w=w->next) { - if (ldb_transaction_cancel_noerr(w->ldb) != LDB_SUCCESS) { - smb_panic("Failed to cancel child transactions\n"); - } - } - - if (tdb_reopen_all(1) == -1) { - smb_panic("tdb_reopen_all failed\n"); - } -} - - char *ldb_relative_path(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *name) -{ - const char *base_url = - (const char *)ldb_get_opaque(ldb, "ldb_url"); - char *path, *p, *full_name; - if (name == NULL) { - return NULL; - } - if (strncmp("tdb://", base_url, 6) == 0) { - base_url = base_url+6; - } - path = talloc_strdup(mem_ctx, base_url); - if (path == NULL) { - return NULL; - } - if ( (p = strrchr(path, '/')) != NULL) { - p[0] = '\0'; - full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); - } else { - full_name = talloc_asprintf(mem_ctx, "./%s", name); - } - talloc_free(path); - return full_name; -} diff --git a/source4/lib/ldb-samba/ldb_wrap.h b/source4/lib/ldb-samba/ldb_wrap.h deleted file mode 100644 index aa7ccb3a234..00000000000 --- a/source4/lib/ldb-samba/ldb_wrap.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - database wrap headers - - Copyright (C) Andrew Tridgell 2004 - - 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 . -*/ - -#ifndef _LDB_WRAP_H_ -#define _LDB_WRAP_H_ - -#include - -struct auth_session_info; -struct ldb_message; -struct ldb_dn; -struct cli_credentials; -struct loadparm_context; -struct tevent_context; - -char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n); - -struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - const char *url, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags); - -void ldb_wrap_fork_hook(void); - -struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); -struct ldb_context *ldb_wrap_find(const char *url, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags); -bool ldb_wrap_add(const char *url, struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags, - struct ldb_context *ldb); -char *ldb_relative_path(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *name); - -int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, unsigned int flags); - -#endif /* _LDB_WRAP_H_ */ diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c deleted file mode 100644 index af3c4b46e17..00000000000 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ /dev/null @@ -1,1416 +0,0 @@ -/* - ldb database library - ldif handlers for Samba - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Andrew Bartlett 2006-2009 - Copyright (C) Matthias Dieter Wallnöfer 2009 - ** 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 . -*/ - -#include "includes.h" -#include -#include -#include "ldb_handlers.h" -#include "dsdb/samdb/samdb.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "librpc/gen_ndr/ndr_drsblobs.h" -#include "librpc/gen_ndr/ndr_dnsp.h" -#include "librpc/ndr/libndr.h" -#include "libcli/security/security.h" -#include "param/param.h" -#include "../lib/util/asn1.h" - -/* - use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob - - If mask_errors is true, then function succeeds but out data - is set to "" message - - \return 0 on success; -1 on error -*/ -static int ldif_write_NDR(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out, - size_t struct_size, - ndr_pull_flags_fn_t pull_fn, - ndr_print_fn_t print_fn, - bool mask_errors) -{ - uint8_t *p; - enum ndr_err_code err; - if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - p = talloc_size(mem_ctx, struct_size); - err = ndr_pull_struct_blob(in, mem_ctx, - p, pull_fn); - if (err != NDR_ERR_SUCCESS) { - /* fail in not in mask_error mode */ - if (!mask_errors) { - return -1; - } - talloc_free(p); - out->data = (uint8_t *)talloc_strdup(mem_ctx, ""); - out->length = strlen((const char *)out->data); - return 0; - } - out->data = (uint8_t *)ndr_print_struct_string(mem_ctx, print_fn, "NDR", p); - talloc_free(p); - if (out->data == NULL) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - convert a ldif formatted objectSid to a NDR formatted blob -*/ -static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - enum ndr_err_code ndr_err; - struct dom_sid *sid; - sid = dom_sid_parse_length(mem_ctx, in); - if (sid == NULL) { - return -1; - } - ndr_err = ndr_push_struct_blob(out, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - talloc_free(sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectSid -*/ -int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid *sid; - enum ndr_err_code ndr_err; - - sid = talloc(mem_ctx, struct dom_sid); - if (sid == NULL) { - return -1; - } - ndr_err = ndr_pull_struct_blob_all(in, sid, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(sid); - return -1; - } - *out = data_blob_string_const(dom_sid_string(mem_ctx, sid)); - talloc_free(sid); - if (out->data == NULL) { - return -1; - } - return 0; -} - -bool ldif_comparision_objectSid_isString(const struct ldb_val *v) -{ - if (v->length < 3) { - return false; - } - - if (strncmp("S-", (const char *)v->data, 2) != 0) return false; - - return true; -} - -/* - compare two objectSids -*/ -static int ldif_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldif_comparision_objectSid_isString(v1) && ldif_comparision_objectSid_isString(v2)) { - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } else if (ldif_comparision_objectSid_isString(v1) - && !ldif_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) { - /* Perhaps not a string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldif_comparision_objectSid_isString(v1) - && ldif_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) { - /* Perhaps not a string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectSid -*/ -static int ldif_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_objectSid_isString(in)) { - if (ldif_read_objectSid(ldb, mem_ctx, in, out) != 0) { - /* Perhaps not a string after all */ - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - return 0; - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - -static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid sid; - enum ndr_err_code ndr_err; - if (ldif_comparision_objectSid_isString(in)) { - if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) { - return 0; - } - } - - /* Perhaps not a string after all */ - *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); - - if (!out->data) { - return -1; - } - - (*out).length = strhex_to_str((char *)out->data, out->length, - (const char *)in->data, in->length); - - /* Check it looks like a SID */ - ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, &sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a ldif formatted objectGUID to a NDR formatted blob -*/ -static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - status = GUID_from_data_blob(in, &guid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - - status = GUID_to_ndr_blob(&guid, mem_ctx, out); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectGUID -*/ -static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - status = GUID_from_ndr_blob(in, &guid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - out->data = (uint8_t *)GUID_string(mem_ctx, &guid); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -static bool ldif_comparision_objectGUID_isString(const struct ldb_val *v) -{ - if (v->length != 36 && v->length != 38) return false; - - /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */ - return true; -} - -static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) { - return 0; - } - - /* Try as 'hex' form */ - if (in->length != 32) { - return -1; - } - - *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); - - if (!out->data) { - return -1; - } - - (*out).length = strhex_to_str((char *)out->data, out->length, - (const char *)in->data, in->length); - - /* Check it looks like a GUID */ - status = GUID_from_ndr_blob(out, &guid); - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(out); - return -1; - } - return 0; -} - -/* - compare two objectGUIDs -*/ -static int ldif_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldif_comparision_objectGUID_isString(v1) && ldif_comparision_objectGUID_isString(v2)) { - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } else if (ldif_comparision_objectGUID_isString(v1) - && !ldif_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldif_comparision_objectGUID_isString(v1) - && ldif_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectGUID -*/ -static int ldif_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_objectGUID_isString(in)) { - if (ldif_read_objectGUID(ldb, mem_ctx, in, out) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - return 0; - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - - -/* - convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob -*/ -static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - enum ndr_err_code ndr_err; - - sd = talloc(mem_ctx, struct security_descriptor); - if (sd == NULL) { - return -1; - } - - ndr_err = ndr_pull_struct_blob(in, sd, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - /* If this does not parse, then it is probably SDDL, and we should try it that way */ - - const struct dom_sid *sid = samdb_domain_sid(ldb); - talloc_free(sd); - sd = sddl_decode(mem_ctx, (const char *)in->data, sid); - if (sd == NULL) { - return -1; - } - } - - ndr_err = ndr_push_struct_blob(out, mem_ctx, sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - talloc_free(sd); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format) -*/ -static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - enum ndr_err_code ndr_err; - - if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct security_descriptor), - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor, - (ndr_print_fn_t)ndr_print_security_descriptor, - true); - - } - - sd = talloc(mem_ctx, struct security_descriptor); - if (sd == NULL) { - return -1; - } - /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ - ndr_err = ndr_pull_struct_blob(in, sd, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(sd); - return -1; - } - out->data = (uint8_t *)sddl_encode(mem_ctx, sd, samdb_domain_sid_cache_only(ldb)); - talloc_free(sd); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -/* - canonicalise an objectCategory. We use the short form as the canonical form: - cn=Person,cn=Schema,cn=Configuration, becomes 'person' -*/ - -static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn1 = NULL; - const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL); - const struct dsdb_class *sclass; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!schema) { - talloc_free(tmp_ctx); - *out = data_blob_talloc(mem_ctx, in->data, in->length); - if (in->data && !out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } - dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in); - if ( ! ldb_dn_validate(dn1)) { - const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length); - sclass = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName); - if (sclass) { - struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, - sclass->defaultObjectCategory); - *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn)); - talloc_free(tmp_ctx); - - if (!out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } else { - *out = data_blob_talloc(mem_ctx, in->data, in->length); - talloc_free(tmp_ctx); - - if (in->data && !out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } - } - *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1)); - talloc_free(tmp_ctx); - - if (!out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - -static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_objectCategory, - v1, v2); -} - -/* - convert a NDR formatted blob to a ldif formatted schemaInfo -*/ -static int ldif_write_schemaInfo(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct repsFromToBlob), - (ndr_pull_flags_fn_t)ndr_pull_schemaInfoBlob, - (ndr_print_fn_t)ndr_print_schemaInfoBlob, - true); -} - -/* - convert a ldif formatted prefixMap to a NDR formatted blob -*/ -static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct prefixMapBlob *blob; - enum ndr_err_code ndr_err; - char *string, *line, *p, *oid; - DATA_BLOB oid_blob; - - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - - if (tmp_ctx == NULL) { - return -1; - } - - blob = talloc_zero(tmp_ctx, struct prefixMapBlob); - if (blob == NULL) { - talloc_free(tmp_ctx); - return -1; - } - - /* use the switch value to detect if this is in the binary - * format - */ - if (in->length >= 4 && IVAL(in->data, 0) == PREFIX_MAP_VERSION_DSDB) { - ndr_err = ndr_pull_struct_blob(in, tmp_ctx, blob, - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - ndr_err = ndr_push_struct_blob(out, mem_ctx, - blob, - (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); - talloc_free(tmp_ctx); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; - } - } - - /* If this does not parse, then it is probably the text version, and we should try it that way */ - blob->version = PREFIX_MAP_VERSION_DSDB; - - string = talloc_strndup(mem_ctx, (const char *)in->data, in->length); - if (string == NULL) { - talloc_free(blob); - return -1; - } - - line = string; - while (line && line[0]) { - p=strchr(line, ';'); - if (p) { - p[0] = '\0'; - } else { - p=strchr(line, '\n'); - if (p) { - p[0] = '\0'; - } - } - /* allow a trailing separator */ - if (line == p) { - break; - } - - blob->ctr.dsdb.mappings = talloc_realloc(blob, - blob->ctr.dsdb.mappings, - struct drsuapi_DsReplicaOIDMapping, - blob->ctr.dsdb.num_mappings+1); - if (!blob->ctr.dsdb.mappings) { - talloc_free(tmp_ctx); - return -1; - } - - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10); - - if (oid[0] != ':') { - talloc_free(tmp_ctx); - return -1; - } - - /* we know there must be at least ":" */ - oid++; - - if (!ber_write_partial_OID_String(blob->ctr.dsdb.mappings, &oid_blob, oid)) { - talloc_free(tmp_ctx); - return -1; - } - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.length = oid_blob.length; - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.binary_oid = oid_blob.data; - - blob->ctr.dsdb.num_mappings++; - - /* Now look past the terminator we added above */ - if (p) { - line = p + 1; - } else { - line = NULL; - } - } - - ndr_err = ndr_push_struct_blob(out, mem_ctx, - blob, - (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); - talloc_free(tmp_ctx); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted prefixMap -*/ -static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct prefixMapBlob *blob; - enum ndr_err_code ndr_err; - char *string; - uint32_t i; - - if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { - int err; - /* try to decode the blob as S4 prefixMap */ - err = ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct prefixMapBlob), - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob, - (ndr_print_fn_t)ndr_print_prefixMapBlob, - false); - if (0 == err) { - return err; - } - /* try parsing it as Windows PrefixMap value */ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct drsuapi_MSPrefixMap_Ctr), - (ndr_pull_flags_fn_t)ndr_pull_drsuapi_MSPrefixMap_Ctr, - (ndr_print_fn_t)ndr_print_drsuapi_MSPrefixMap_Ctr, - true); - } - - blob = talloc(mem_ctx, struct prefixMapBlob); - if (blob == NULL) { - return -1; - } - ndr_err = ndr_pull_struct_blob_all(in, blob, - blob, - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto failed; - } - if (blob->version != PREFIX_MAP_VERSION_DSDB) { - goto failed; - } - string = talloc_strdup(mem_ctx, ""); - if (string == NULL) { - goto failed; - } - - for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { - DATA_BLOB oid_blob; - char *partial_oid = NULL; - - if (i > 0) { - string = talloc_asprintf_append(string, ";"); - } - - oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid, - blob->ctr.dsdb.mappings[i].oid.length); - if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) { - DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", - blob->ctr.dsdb.mappings[i].id_prefix)); - goto failed; - } - string = talloc_asprintf_append(string, "%u:%s", - blob->ctr.dsdb.mappings[i].id_prefix, - partial_oid); - talloc_free(discard_const(partial_oid)); - if (string == NULL) { - goto failed; - } - } - - talloc_free(blob); - *out = data_blob_string_const(string); - return 0; - -failed: - talloc_free(blob); - return -1; -} - -static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v) -{ - if (v->length < 4) { - return true; - } - - if (IVAL(v->data, 0) == PREFIX_MAP_VERSION_DSDB) { - return false; - } - - return true; -} - -/* - canonicalise a prefixMap -*/ -static int ldif_canonicalise_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_prefixMap_isString(in)) { - return ldif_read_prefixMap(ldb, mem_ctx, in, out); - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - -static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_prefixMap, - v1, v2); -} - -/* length limited conversion of a ldb_val to a int32_t */ -static int val_to_int32(const struct ldb_val *in, int32_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - /* We've to use "strtoll" here to have the intended overflows. - * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ - *v = (int32_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - -/* length limited conversion of a ldb_val to a int64_t */ -static int val_to_int64(const struct ldb_val *in, int64_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - *v = (int64_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - -/* Canonicalisation of two 32-bit integers */ -static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int32_t i; - int ret; - - ret = val_to_int32(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* Comparison of two 32-bit integers */ -static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int32_t i1=0, i2=0; - val_to_int32(v1, &i1); - val_to_int32(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* Canonicalisation of two 64-bit integers */ -static int ldif_canonicalise_int64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t i; - int ret; - - ret = val_to_int64(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* Comparison of two 64-bit integers */ -static int ldif_comparison_int64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int64_t i1=0, i2=0; - val_to_int64(v1, &i1); - val_to_int64(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* - convert a NDR formatted blob to a ldif formatted repsFromTo -*/ -static int ldif_write_repsFromTo(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct repsFromToBlob), - (ndr_pull_flags_fn_t)ndr_pull_repsFromToBlob, - (ndr_print_fn_t)ndr_print_repsFromToBlob, - true); -} - -/* - convert a NDR formatted blob to a ldif formatted replPropertyMetaData -*/ -static int ldif_write_replPropertyMetaData(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct replPropertyMetaDataBlob), - (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob, - (ndr_print_fn_t)ndr_print_replPropertyMetaDataBlob, - true); -} - -/* - convert a NDR formatted blob to a ldif formatted replUpToDateVector -*/ -static int ldif_write_replUpToDateVector(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct replUpToDateVectorBlob), - (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob, - (ndr_print_fn_t)ndr_print_replUpToDateVectorBlob, - true); -} - - -/* - convert a NDR formatted blob to a ldif formatted dnsRecord -*/ -static int ldif_write_dnsRecord(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct dnsp_DnssrvRpcRecord), - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord, - (ndr_print_fn_t)ndr_print_dnsp_DnssrvRpcRecord, - true); -} - -/* - convert a NDR formatted blob of a supplementalCredentials into text -*/ -static int ldif_write_supplementalCredentialsBlob(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct supplementalCredentialsBlob), - (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob, - (ndr_print_fn_t)ndr_print_supplementalCredentialsBlob, - true); -} - - -static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = data_blob_string_const(data_blob_hex_string_lower(mem_ctx, in)); - if (!out->data) { - return -1; - } - return 0; -} - -/* - compare two dns -*/ -static int samba_ldb_dn_link_comparison(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - int ret; - - if (dsdb_dn_is_deleted_val(v1)) { - /* If the DN is deleted, then we can't search for it */ - return -1; - } - - if (dsdb_dn_is_deleted_val(v2)) { - /* If the DN is deleted, then we can't search for it */ - return -1; - } - - dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); - if ( ! ldb_dn_validate(dn1)) return -1; - - dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); - if ( ! ldb_dn_validate(dn2)) { - talloc_free(dn1); - return -1; - } - - ret = ldb_dn_compare(dn1, dn2); - - talloc_free(dn1); - talloc_free(dn2); - return ret; -} - -static int samba_ldb_dn_link_canonicalise(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn; - int ret = -1; - - out->length = 0; - out->data = NULL; - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* By including the RMD_FLAGS of a deleted DN, we ensure it - * does not casually match a not deleted DN */ - if (dsdb_dn_is_deleted_val(in)) { - out->data = (uint8_t *)talloc_asprintf(mem_ctx, - "%s", - dsdb_dn_val_rmd_flags(in), - ldb_dn_get_casefold(dn)); - } else { - out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); - } - - if (out->data == NULL) { - goto done; - } - out->length = strlen((char *)out->data); - - ret = 0; - -done: - talloc_free(dn); - - return ret; -} - - -/* - write a 64 bit 2-part range -*/ -static int ldif_write_range64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t v; - int ret; - ret = val_to_int64(in, &v); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lu-%lu", - (unsigned long)(v&0xFFFFFFFF), - (unsigned long)(v>>32)); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return LDB_SUCCESS; -} - -/* - read a 64 bit 2-part range -*/ -static int ldif_read_range64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - unsigned long high, low; - char buf[64]; - - if (memchr(in->data, '-', in->length) == NULL) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (const char *)in->data, in->length); - buf[in->length] = 0; - - if (sscanf(buf, "%lu-%lu", &low, &high) != 2) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%llu", - (unsigned long long)(((uint64_t)high)<<32) | (low)); - - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return LDB_SUCCESS; -} - -/* - when this operator_fn is set for a syntax, the backend calls is in - preference to the comparison function. We are told the exact - comparison operation that is needed, and we can return errors - */ -static int samba_syntax_operator_fn(struct ldb_context *ldb, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) -{ - switch (operation) { - case LDB_OP_AND: - case LDB_OP_OR: - case LDB_OP_NOT: - case LDB_OP_SUBSTRING: - case LDB_OP_APPROX: - case LDB_OP_EXTENDED: - /* handled in the backends */ - return LDB_ERR_INAPPROPRIATE_MATCHING; - - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_EQUALITY: - { - TALLOC_CTX *tmp_ctx = talloc_new(ldb); - int ret; - if (tmp_ctx == NULL) { - return ldb_oom(ldb); - } - ret = a->syntax->comparison_fn(ldb, tmp_ctx, v1, v2); - talloc_free(tmp_ctx); - if (operation == LDB_OP_GREATER) { - *matched = (ret > 0); - } else if (operation == LDB_OP_LESS) { - *matched = (ret < 0); - } else { - *matched = (ret == 0); - } - return LDB_SUCCESS; - } - - case LDB_OP_PRESENT: - *matched = true; - return LDB_SUCCESS; - } - - /* we shouldn't get here */ - return LDB_ERR_INAPPROPRIATE_MATCHING; -} - -/* - special operation for DNs, to take account of the RMD_FLAGS deleted bit - */ -static int samba_syntax_operator_dn(struct ldb_context *ldb, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) -{ - if (operation == LDB_OP_PRESENT && dsdb_dn_is_deleted_val(v1)) { - /* If the DN is deleted, then we can't search for it */ - *matched = false; - return LDB_SUCCESS; - } - return samba_syntax_operator_fn(ldb, operation, a, v1, v2, matched); -} - - -static const struct ldb_schema_syntax samba_syntaxes[] = { - { - .name = LDB_SYNTAX_SAMBA_SID, - .ldif_read_fn = ldif_read_objectSid, - .ldif_write_fn = ldif_write_objectSid, - .canonicalise_fn = ldif_canonicalise_objectSid, - .comparison_fn = ldif_comparison_objectSid, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR, - .ldif_read_fn = ldif_read_ntSecurityDescriptor, - .ldif_write_fn = ldif_write_ntSecurityDescriptor, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_GUID, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldif_canonicalise_objectGUID, - .comparison_fn = ldif_comparison_objectGUID, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldif_canonicalise_objectCategory, - .comparison_fn = ldif_comparison_objectCategory, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SCHEMAINFO, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_schemaInfo, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, - .ldif_read_fn = ldif_read_prefixMap, - .ldif_write_fn = ldif_write_prefixMap, - .canonicalise_fn = ldif_canonicalise_prefixMap, - .comparison_fn = ldif_comparison_prefixMap, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_INT32, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldif_canonicalise_int32, - .comparison_fn = ldif_comparison_int32, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPSFROMTO, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_repsFromTo, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_replPropertyMetaData, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_replUpToDateVector, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = DSDB_SYNTAX_BINARY_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = dsdb_dn_binary_canonicalise, - .comparison_fn = dsdb_dn_binary_comparison, - .operator_fn = samba_syntax_operator_fn - },{ - .name = DSDB_SYNTAX_STRING_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = dsdb_dn_string_canonicalise, - .comparison_fn = dsdb_dn_string_comparison, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = samba_ldb_dn_link_canonicalise, - .comparison_fn = samba_ldb_dn_link_comparison, - .operator_fn = samba_syntax_operator_dn - },{ - .name = LDB_SYNTAX_SAMBA_RANGE64, - .ldif_read_fn = ldif_read_range64, - .ldif_write_fn = ldif_write_range64, - .canonicalise_fn = ldif_canonicalise_int64, - .comparison_fn = ldif_comparison_int64, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_DNSRECORD, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_dnsRecord, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_supplementalCredentialsBlob, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - } -}; - -static const struct ldb_dn_extended_syntax samba_dn_syntax[] = { - { - .name = "SID", - .read_fn = extended_dn_read_SID, - .write_clear_fn = ldif_write_objectSid, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "GUID", - .read_fn = extended_dn_read_GUID, - .write_clear_fn = ldif_write_objectGUID, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "WKGUID", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_INVOCID", - .read_fn = extended_dn_read_GUID, - .write_clear_fn = ldif_write_objectGUID, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "RMD_FLAGS", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_ADDTIME", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_CHANGETIME", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_LOCAL_USN", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_ORIGINATING_USN", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_VERSION", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - } -}; - -/* TODO: Should be dynamic at some point */ -static const struct { - const char *name; - const char *syntax; -} samba_attributes[] = { - { "objectSid", LDB_SYNTAX_SAMBA_SID }, - { "securityIdentifier", LDB_SYNTAX_SAMBA_SID }, - { "tokenGroups", LDB_SYNTAX_SAMBA_SID }, - { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR }, - { "oMSyntax", LDB_SYNTAX_SAMBA_INT32 }, - { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY }, - { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO }, - { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP }, - { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO }, - { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO }, - { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA }, - { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR }, - { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, - { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, - { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64 }, - - /* - * these are extracted by searching - * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4)) - */ - { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID }, - { "categoryId", LDB_SYNTAX_SAMBA_GUID }, - { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID }, - { "currMachineId", LDB_SYNTAX_SAMBA_GUID }, - { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID }, - { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID }, - { "implementedCategories", LDB_SYNTAX_SAMBA_GUID }, - { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID }, - { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID }, - { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQSites", LDB_SYNTAX_SAMBA_GUID }, - { "netbootGUID", LDB_SYNTAX_SAMBA_GUID }, - { "objectGUID", LDB_SYNTAX_SAMBA_GUID }, - { "pKTGuid", LDB_SYNTAX_SAMBA_GUID }, - { "requiredCategories", LDB_SYNTAX_SAMBA_GUID }, - { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID }, - { "siteGUID", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - - /* - * these are known to be GUIDs - */ - { "invocationId", LDB_SYNTAX_SAMBA_GUID }, - { "parentGUID", LDB_SYNTAX_SAMBA_GUID }, - { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID }, - - /* These NDR encoded things we want to be able to read with --show-binary */ - { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD }, - { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS} -}; - -const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb, const char *name) -{ - unsigned int j; - const struct ldb_schema_syntax *s = NULL; - - for (j=0; j < ARRAY_SIZE(samba_syntaxes); j++) { - if (strcmp(name, samba_syntaxes[j].name) == 0) { - s = &samba_syntaxes[j]; - break; - } - } - return s; -} - -const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context *ldb, const char *name) -{ - unsigned int j; - const struct ldb_schema_syntax *s = NULL; - - for (j=0; j < ARRAY_SIZE(samba_attributes); j++) { - if (strcmp(samba_attributes[j].name, name) == 0) { - s = ldb_samba_syntax_by_name(ldb, samba_attributes[j].syntax); - break; - } - } - - return s; -} - -/* - register the samba ldif handlers -*/ -int ldb_register_samba_handlers(struct ldb_context *ldb) -{ - unsigned int i; - int ret; - - if (ldb_get_opaque(ldb, "SAMBA_HANDLERS_REGISTERED") != NULL) { - return LDB_SUCCESS; - } - - for (i=0; i < ARRAY_SIZE(samba_attributes); i++) { - const struct ldb_schema_syntax *s = NULL; - - s = ldb_samba_syntax_by_name(ldb, samba_attributes[i].syntax); - - if (!s) { - s = ldb_standard_syntax_by_name(ldb, samba_attributes[i].syntax); - } - - if (!s) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_schema_attribute_add_with_syntax(ldb, samba_attributes[i].name, LDB_ATTR_FLAG_FIXED, s); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) { - ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]); - if (ret != LDB_SUCCESS) { - return ret; - } - - } - - ret = ldb_set_opaque(ldb, "SAMBA_HANDLERS_REGISTERED", (void*)1); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/ldif_handlers.h b/source4/lib/ldb-samba/ldif_handlers.h deleted file mode 100644 index 62903c4a964..00000000000 --- a/source4/lib/ldb-samba/ldif_handlers.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ -#define __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ - -#define LDB_SYNTAX_SAMBA_SID "LDB_SYNTAX_SAMBA_SID" -#define LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR "1.2.840.113556.1.4.907" -#define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID" -#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY" -#define LDB_SYNTAX_SAMBA_SCHEMAINFO "LDB_SYNTAX_SAMBA_SCHEMAINFO" -#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP" -#define LDB_SYNTAX_SAMBA_INT32 "LDB_SYNTAX_SAMBA_INT32" -#define LDB_SYNTAX_SAMBA_REPSFROMTO "LDB_SYNTAX_SAMBA_REPSFROMTO" -#define LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA "LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA" -#define LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR "LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR" -#define LDB_SYNTAX_SAMBA_RANGE64 "LDB_SYNTAX_SAMBA_RANGE64" -#define LDB_SYNTAX_SAMBA_DNSRECORD "LDB_SYNTAX_SAMBA_DNSRECORD" -#define LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS "LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS" -#include "lib/ldb-samba/ldif_handlers_proto.h" - -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) - -#endif /* __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ */ - diff --git a/source4/lib/ldb-samba/pyldb.c b/source4/lib/ldb-samba/pyldb.c deleted file mode 100644 index ff48a3bb040..00000000000 --- a/source4/lib/ldb-samba/pyldb.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb, Samba-specific functions - - Copyright (C) 2007-2010 Jelmer Vernooij - - 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 -#include "includes.h" -#include -#include -#include "param/pyparam.h" -#include "auth/credentials/pycredentials.h" -#include "ldb_wrap.h" -#include "lib/ldb-samba/ldif_handlers.h" -#include "auth/pyauth.h" - -void init_ldb(void); - -static PyObject *pyldb_module; -static PyObject *py_ldb_error; -staticforward PyTypeObject PySambaLdb; - -static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) -{ - if (ret == LDB_ERR_PYTHON_EXCEPTION) - return; /* Python exception should already be set, just keep that */ - - PyErr_SetObject(error, - Py_BuildValue(discard_const_p(char, "(i,s)"), ret, - ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); -} - -static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args) -{ - PyObject *py_lp_ctx; - struct loadparm_context *lp_ctx; - struct ldb_context *ldb; - - if (!PyArg_ParseTuple(args, "O", &py_lp_ctx)) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - lp_ctx = lpcfg_from_py_object(ldb, py_lp_ctx); - if (lp_ctx == NULL) { - PyErr_SetString(PyExc_TypeError, "Expected loadparm object"); - return NULL; - } - - ldb_set_opaque(ldb, "loadparm", lp_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args) -{ - PyObject *py_creds; - struct cli_credentials *creds; - struct ldb_context *ldb; - - if (!PyArg_ParseTuple(args, "O", &py_creds)) - return NULL; - - creds = cli_credentials_from_py_object(py_creds); - if (creds == NULL) { - PyErr_SetString(PyExc_TypeError, "Expected credentials object"); - return NULL; - } - - ldb = PyLdb_AsLdbContext(self); - - ldb_set_opaque(ldb, "credentials", creds); - - Py_RETURN_NONE; -} - -/* XXX: This function really should be in libldb's pyldb.c */ -static PyObject *py_ldb_set_opaque_integer(PyObject *self, PyObject *args) -{ - int value; - int *old_val, *new_val; - char *py_opaque_name, *opaque_name_talloc; - struct ldb_context *ldb; - int ret; - TALLOC_CTX *tmp_ctx; - - if (!PyArg_ParseTuple(args, "si", &py_opaque_name, &value)) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - /* see if we have a cached copy */ - old_val = (int *)ldb_get_opaque(ldb, py_opaque_name); - /* XXX: We shouldn't just blindly assume that the value that is - * already present has the size of an int and is not shared - * with other code that may rely on it not changing. - * JRV 20100403 */ - - if (old_val) { - *old_val = value; - Py_RETURN_NONE; - } - - tmp_ctx = talloc_new(ldb); - if (tmp_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - new_val = talloc(tmp_ctx, int); - if (new_val == NULL) { - talloc_free(tmp_ctx); - PyErr_NoMemory(); - return NULL; - } - - opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name); - if (opaque_name_talloc == NULL) { - talloc_free(tmp_ctx); - PyErr_NoMemory(); - return NULL; - } - - *new_val = value; - - /* cache the domain_sid in the ldb */ - ret = ldb_set_opaque(ldb, opaque_name_talloc, new_val); - - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - PyErr_SetLdbError(py_ldb_error, ret, ldb); - return NULL; - } - - talloc_steal(ldb, new_val); - talloc_steal(ldb, opaque_name_talloc); - talloc_free(tmp_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_utf8_casefold(PyObject *self) -{ - struct ldb_context *ldb; - - ldb = PyLdb_AsLdbContext(self); - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args) -{ - PyObject *py_session_info; - struct auth_session_info *info; - struct ldb_context *ldb; - PyObject *mod_samba_auth; - PyObject *PyAuthSession_Type; - bool ret; - - mod_samba_auth = PyImport_ImportModule("samba.dcerpc.auth"); - if (mod_samba_auth == NULL) - return NULL; - - PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "session_info"); - if (PyAuthSession_Type == NULL) - return NULL; - - ret = PyArg_ParseTuple(args, "O!", PyAuthSession_Type, &py_session_info); - - Py_DECREF(PyAuthSession_Type); - Py_DECREF(mod_samba_auth); - - if (!ret) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - info = PyAuthSession_AsSession(py_session_info); - - ldb_set_opaque(ldb, "sessionInfo", info); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_register_samba_handlers(PyObject *self) -{ - struct ldb_context *ldb; - int ret; - - /* XXX: Perhaps call this from PySambaLdb's init function ? */ - - ldb = PyLdb_AsLdbContext(self); - ret = ldb_register_samba_handlers(ldb); - - PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb); - - Py_RETURN_NONE; -} - -static PyMethodDef py_samba_ldb_methods[] = { - { "set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS, - "ldb_set_loadparm(session_info)\n" - "Set loadparm context to use when connecting." }, - { "set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS, - "ldb_set_credentials(credentials)\n" - "Set credentials to use when connecting." }, - { "set_opaque_integer", (PyCFunction)py_ldb_set_opaque_integer, - METH_VARARGS, NULL }, - { "set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, - METH_NOARGS, - "ldb_set_utf8_casefold()\n" - "Set the right Samba casefolding function for UTF8 charset." }, - { "register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, - METH_NOARGS, - "register_samba_handlers()\n" - "Register Samba-specific LDB modules and schemas." }, - { "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS, - "set_session_info(session_info)\n" - "Set session info to use when connecting." }, - { NULL }, -}; - -static PyTypeObject PySambaLdb = { - .tp_name = "samba._ldb.Ldb", - .tp_doc = "Connection to a LDB database.", - .tp_methods = py_samba_ldb_methods, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -void init_ldb(void) -{ - PyObject *m; - - pyldb_module = PyImport_ImportModule("ldb"); - if (pyldb_module == NULL) - return; - - PySambaLdb.tp_base = (PyTypeObject *)PyObject_GetAttrString(pyldb_module, "Ldb"); - if (PySambaLdb.tp_base == NULL) - return; - - py_ldb_error = PyObject_GetAttrString(pyldb_module, "LdbError"); - - if (PyType_Ready(&PySambaLdb) < 0) - return; - - m = Py_InitModule3("_ldb", NULL, "Samba-specific LDB python bindings"); - if (m == NULL) - return; - - Py_INCREF(&PySambaLdb); - PyModule_AddObject(m, "Ldb", (PyObject *)&PySambaLdb); -} diff --git a/source4/lib/ldb-samba/samba_extensions.c b/source4/lib/ldb-samba/samba_extensions.c deleted file mode 100644 index be9f36a5a7d..00000000000 --- a/source4/lib/ldb-samba/samba_extensions.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - ldb database library - samba extensions - - Copyright (C) Andrew Tridgell 2010 - - ** 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 . -*/ - - -#include "includes.h" -#include "ldb_module.h" -#include "lib/cmdline/popt_common.h" -#include "auth/gensec/gensec.h" -#include "auth/auth.h" -#include "param/param.h" -#include "dsdb/samdb/samdb.h" -#include "ldb_wrap.h" -#include "popt.h" - - - -/* - work out the length of a popt array - */ -static unsigned calculate_popt_array_length(struct poptOption *opts) -{ - unsigned i; - struct poptOption zero_opt = { NULL }; - for (i=0; memcmp(&zero_opt, &opts[i], sizeof(zero_opt)) != 0; i++) ; - return i; -} - -static struct poptOption cmdline_extensions[] = { - POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS - POPT_COMMON_CONNECTION - POPT_COMMON_VERSION - { NULL } -}; - -/* - called to register additional command line options - */ -static int extensions_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) -{ - switch (t) { - case LDB_MODULE_HOOK_CMDLINE_OPTIONS: { - unsigned len1, len2; - struct poptOption **popt_options = ldb_module_popt_options(ldb); - struct poptOption *new_array; - - len1 = calculate_popt_array_length(*popt_options); - len2 = calculate_popt_array_length(cmdline_extensions); - new_array = talloc_array(NULL, struct poptOption, len1+len2+1); - if (NULL == new_array) { - return ldb_oom(ldb); - } - - memcpy(new_array, *popt_options, len1*sizeof(struct poptOption)); - memcpy(new_array+len1, cmdline_extensions, (1+len2)*sizeof(struct poptOption)); - (*popt_options) = new_array; - return LDB_SUCCESS; - } - - case LDB_MODULE_HOOK_CMDLINE_PRECONNECT: { - int r = ldb_register_samba_handlers(ldb); - if (r != LDB_SUCCESS) { - return ldb_operr(ldb); - } - gensec_init(); - - if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) { - return ldb_operr(ldb); - } - if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { - return ldb_operr(ldb); - } - if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) { - return ldb_operr(ldb); - } - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - break; - } - - case LDB_MODULE_HOOK_CMDLINE_POSTCONNECT: - /* get the domain SID into the cache for SDDL processing */ - samdb_domain_sid(ldb); - break; - } - - return LDB_SUCCESS; -} - - -/* - initialise the module - */ -_PUBLIC_ int ldb_samba_extensions_init(const char *ldb_version) -{ - ldb_register_hook(extensions_hook); - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/wscript_build b/source4/lib/ldb-samba/wscript_build deleted file mode 100644 index 2e1cacba649..00000000000 --- a/source4/lib/ldb-samba/wscript_build +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -# LDBSAMBA gets included in the ldb build when we are building ldb_ildap -# as a built-in module and this delutes the symbols in the ldb library with -# the symbols of all of ldb_ildap's dependencies. - -bld.SAMBA_LIBRARY('ldbsamba', - source='ldif_handlers.c', - autoproto='ldif_handlers_proto.h', - public_deps='ldb', - deps='security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb_compat pyldb-util errors', - private_library=True - ) - -bld.SAMBA_SUBSYSTEM('ldbwrap', - source='ldb_wrap.c', - public_headers='ldb_wrap.h', - deps='ldb samba-util ldbsamba samba-hostconfig' - ) - - -bld.SAMBA_PYTHON('python_samba__ldb', 'pyldb.c', - deps='ldbsamba pyparam_util ldbwrap', - realname='samba/_ldb.so') - -bld.SAMBA_MODULE('ldbsamba_extensions', - source='samba_extensions.c', - init_function='ldb_samba_extensions_init', - module_init_name='ldb_init_module', - subsystem='ldb', - deps='ldb ldbsamba POPT_SAMBA POPT_CREDENTIALS cmdline-credentials gensec', - internal_module=False) - - -# the s4-internal ldap backend -bld.SAMBA_MODULE('ldb_ildap', - source='ldb_ildap.c', - init_function='ldb_ildap_init', - module_init_name='ldb_init_module', - deps='talloc cli-ldap credentials auth_system_session', - internal_module=False, - subsystem='ldb') diff --git a/source4/lib/ldb/ABI/ldb-0.9.10.sigs b/source4/lib/ldb/ABI/ldb-0.9.10.sigs deleted file mode 100644 index 012ac65bb78..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.10.sigs +++ /dev/null @@ -1,218 +0,0 @@ -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 *(void *, 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 *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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 *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) -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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.12.sigs b/source4/lib/ldb/ABI/ldb-0.9.12.sigs deleted file mode 100644 index 2206e790fc1..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.12.sigs +++ /dev/null @@ -1,219 +0,0 @@ -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 *(void *, 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 *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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 *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) -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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_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_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_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.15.sigs b/source4/lib/ldb/ABI/ldb-0.9.15.sigs deleted file mode 100644 index 39d2f3eac49..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.15.sigs +++ /dev/null @@ -1,226 +0,0 @@ -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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_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_location: const char *(struct ldb_request *) -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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.16.sigs b/source4/lib/ldb/ABI/ldb-0.9.16.sigs deleted file mode 100644 index 610a0a4a754..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.16.sigs +++ /dev/null @@ -1,228 +0,0 @@ -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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.17.sigs b/source4/lib/ldb/ABI/ldb-0.9.17.sigs deleted file mode 100644 index d0f56991d2c..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.17.sigs +++ /dev/null @@ -1,229 +0,0 @@ -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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.18.sigs b/source4/lib/ldb/ABI/ldb-0.9.18.sigs deleted file mode 100644 index 15913c93853..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.18.sigs +++ /dev/null @@ -1,240 +0,0 @@ -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_asq_init: int (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_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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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_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_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_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 *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_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_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_paged_results_init: int (const char *) -ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_sample_init: int (const char *) -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_server_sort_init: int (const char *) -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_skel_init: int (const char *) -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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.19.sigs b/source4/lib/ldb/ABI/ldb-0.9.19.sigs deleted file mode 100644 index 62738709e4e..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.19.sigs +++ /dev/null @@ -1,245 +0,0 @@ -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_asq_init: int (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_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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -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_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_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_paged_results_init: int (const char *) -ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_sample_init: int (const char *) -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_server_sort_init: int (const char *) -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_skel_init: int (const char *) -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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.20.sigs b/source4/lib/ldb/ABI/ldb-0.9.20.sigs deleted file mode 100644 index 62738709e4e..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.20.sigs +++ /dev/null @@ -1,245 +0,0 @@ -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_asq_init: int (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_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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -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_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_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_paged_results_init: int (const char *) -ldb_paged_searches_init: int (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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_sample_init: int (const char *) -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_server_sort_init: int (const char *) -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_skel_init: int (const char *) -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_tdb_init: int (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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.22.sigs b/source4/lib/ldb/ABI/ldb-0.9.22.sigs deleted file mode 100644 index b5a69c14a9b..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.22.sigs +++ /dev/null @@ -1,245 +0,0 @@ -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_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_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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.23.sigs b/source4/lib/ldb/ABI/ldb-0.9.23.sigs deleted file mode 100644 index 73e5caa896d..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.23.sigs +++ /dev/null @@ -1,247 +0,0 @@ -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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-0.9.24.sigs b/source4/lib/ldb/ABI/ldb-0.9.24.sigs deleted file mode 100644 index 5cb32f7c46b..00000000000 --- a/source4/lib/ldb/ABI/ldb-0.9.24.sigs +++ /dev/null @@ -1,248 +0,0 @@ -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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-1.0.0.sigs b/source4/lib/ldb/ABI/ldb-1.0.0.sigs deleted file mode 100644 index 5cb32f7c46b..00000000000 --- a/source4/lib/ldb/ABI/ldb-1.0.0.sigs +++ /dev/null @@ -1,248 +0,0 @@ -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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-1.0.1.sigs b/source4/lib/ldb/ABI/ldb-1.0.1.sigs deleted file mode 100644 index 5cb32f7c46b..00000000000 --- a/source4/lib/ldb/ABI/ldb-1.0.1.sigs +++ /dev/null @@ -1,248 +0,0 @@ -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_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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-1.0.2.sigs b/source4/lib/ldb/ABI/ldb-1.0.2.sigs deleted file mode 100644 index c13ac873d21..00000000000 --- a/source4/lib/ldb/ABI/ldb-1.0.2.sigs +++ /dev/null @@ -1,250 +0,0 @@ -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_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_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-1.1.0.sigs b/source4/lib/ldb/ABI/ldb-1.1.0.sigs deleted file mode 100644 index 149d4bc0ae8..00000000000 --- a/source4/lib/ldb/ABI/ldb-1.1.0.sigs +++ /dev/null @@ -1,253 +0,0 @@ -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_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_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_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_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_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_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_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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs b/source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs deleted file mode 100644 index 46392207599..00000000000 --- a/source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs +++ /dev/null @@ -1,224 +0,0 @@ -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 *(void *, 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 *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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 *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) -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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -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_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_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs b/source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs deleted file mode 100644 index 7f9dbb5297c..00000000000 --- a/source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs +++ /dev/null @@ -1,223 +0,0 @@ -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 *(void *, 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 *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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 *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -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_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) -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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -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_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_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs b/source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs deleted file mode 100644 index 46392207599..00000000000 --- a/source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs +++ /dev/null @@ -1,224 +0,0 @@ -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 *(void *, 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 *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, 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 *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -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_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -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 *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, 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 *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, 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 *(void *, 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_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, 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_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, 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_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_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 *(void *, 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_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -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_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_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -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_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -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_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -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_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -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_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, 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_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_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, 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 *(void *) -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_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, 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_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -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_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_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -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_val_dup: struct ldb_val (void *, 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_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/source4/lib/ldb/Doxyfile b/source4/lib/ldb/Doxyfile deleted file mode 100644 index 07b12b516a8..00000000000 --- a/source4/lib/ldb/Doxyfile +++ /dev/null @@ -1,26 +0,0 @@ -PROJECT_NAME = LDB -OUTPUT_DIRECTORY = apidocs -REPEAT_BRIEF = YES -OPTIMIZE_OUTPUT_FOR_C = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -GENERATE_TODOLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -SHOW_USED_FILES = NO -SHOW_DIRECTORIES = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -INPUT = include . -FILE_PATTERNS = *.h *.dox -EXCLUDE = include/config.h include/dlinklist.h \ - include/includes.h -EXAMPLE_PATH = examples -GENERATE_HTML = YES -HTML_OUTPUT = html -GENERATE_MAN = YES -ALWAYS_DETAILED_SEC = YES -JAVADOC_AUTOBRIEF = YES diff --git a/source4/lib/ldb/Makefile b/source4/lib/ldb/Makefile deleted file mode 100644 index a07b4a71641..00000000000 --- a/source4/lib/ldb/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# simple makefile wrapper to run waf - -WAF=WAF_MAKE=1 PATH=buildtools/bin:../../../buildtools/bin:$$PATH waf - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags diff --git a/source4/lib/ldb/README_gcov.txt b/source4/lib/ldb/README_gcov.txt deleted file mode 100644 index 2abd9378f43..00000000000 --- a/source4/lib/ldb/README_gcov.txt +++ /dev/null @@ -1,29 +0,0 @@ -Here is how to use gcov to test code coverage in ldb. - -Step 1: build ldb with gcov enabled - - make clean all WITH_GCOV=1 - -Step 3: run the test suite - make test-tdb - -Step 4: produce the gcov report - make gcov - -Step 5: read the summary reports - less *.report.gcov - -Step 6: examine the per-file reports - less ldb_tdb\#ldb_tdb.c.gcov - -You can also combine steps 2 to 4 like this: - - make clean all test-tdb gcov WITH_GCOV=1 - -Note that you should not expect 100% coverage, as some error paths -(such as memory allocation failures) are very hard to trigger. There -are ways of working around this, but they are quite tricky (they -involve allocation wrappers that "fork and fail on malloc"). - -The lines to look for in the per-file reports are the ones starting -with "#####". Those are lines that are never executed. diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c deleted file mode 100644 index 2f4454c7b41..00000000000 --- a/source4/lib/ldb/common/attrib_handlers.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Andrew Bartlett 2006-2009 - - ** 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 . -*/ -/* - attribute handlers for well known attribute types, selected by syntax OID - see rfc2252 -*/ - -#include "ldb_private.h" -#include "system/locale.h" -#include "ldb_handlers.h" - -/* - default handler that just copies a ldb_val. -*/ -int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = ldb_val_dup(mem_ctx, in); - if (in->length > 0 && out->data == NULL) { - ldb_oom(ldb); - return -1; - } - return 0; -} - -/* - a case folding copy handler, removing leading and trailing spaces and - multiple internal spaces - - We exploit the fact that utf8 never uses the space octet except for - the space itself -*/ -int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - char *s, *t; - size_t l; - - if (!in || !out || !(in->data)) { - return -1; - } - - out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length); - if (out->data == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data); - return -1; - } - - s = (char *)(out->data); - - /* remove trailing spaces if any */ - l = strlen(s); - while (l > 0 && s[l - 1] == ' ') l--; - s[l] = '\0'; - - /* remove leading spaces if any */ - if (*s == ' ') { - for (t = s; *s == ' '; s++) ; - - /* remove leading spaces by moving down the string */ - memmove(t, s, l); - - s = t; - } - - /* check middle spaces */ - while ((t = strchr(s, ' ')) != NULL) { - for (s = t; *s == ' '; s++) ; - - if ((s - t) > 1) { - l = strlen(s); - - /* remove all spaces but one by moving down the string */ - memmove(t + 1, s, l); - } - } - - out->length = strlen((char *)out->data); - return 0; -} - -/* length limited conversion of a ldb_val to a int32_t */ -static int val_to_int64(const struct ldb_val *in, int64_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - /* We've to use "strtoll" here to have the intended overflows. - * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ - *v = (int64_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - - -/* - canonicalise a ldap Integer - rfc2252 specifies it should be in decimal form -*/ -static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t i; - int ret; - - ret = val_to_int64(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - compare two Integers -*/ -static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int64_t i1=0, i2=0; - val_to_int64(v1, &i1); - val_to_int64(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* - canonicalise a ldap Boolean - rfc2252 specifies it should be either "TRUE" or "FALSE" -*/ -static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (strncasecmp((char *)in->data, "TRUE", in->length) == 0) { - out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE"); - out->length = 4; - } else if (strncasecmp((char *)in->data, "FALSE", in->length) == 0) { - out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE"); - out->length = 4; - } else { - return -1; - } - return 0; -} - -/* - compare two Booleans -*/ -static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); -} - - -/* - compare two binary blobs -*/ -int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return memcmp(v1->data, v2->data, v1->length); -} - -/* - compare two case insensitive strings, ignoring multiple whitespaces - and leading and trailing whitespaces - see rfc2252 section 8.1 - - try to optimize for the ascii case, - but if we find out an utf8 codepoint revert to slower but correct function -*/ -int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; - size_t n1 = v1->length, n2 = v2->length; - char *b1, *b2; - const char *u1, *u2; - int ret; - while (n1 && *s1 == ' ') { s1++; n1--; }; - while (n2 && *s2 == ' ') { s2++; n2--; }; - - while (n1 && n2 && *s1 && *s2) { - /* the first 127 (0x7F) chars are ascii and utf8 guarantes they - * never appear in multibyte sequences */ - if (((unsigned char)s1[0]) & 0x80) goto utf8str; - if (((unsigned char)s2[0]) & 0x80) goto utf8str; - if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) - break; - if (*s1 == ' ') { - while (n1 && s1[0] == s1[1]) { s1++; n1--; } - while (n2 && s2[0] == s2[1]) { s2++; n2--; } - } - s1++; s2++; - n1--; n2--; - } - - /* check for trailing spaces only if the other pointers has - * reached the end of the strings otherwise we can - * mistakenly match. ex. "domain users" <-> - * "domainUpdates" - */ - if (n1 && *s1 == ' ' && (!n2 || !*s2)) { - while (n1 && *s1 == ' ') { s1++; n1--; } - } - if (n2 && *s2 == ' ' && (!n1 || !*s1)) { - while (n2 && *s2 == ' ') { s2++; n2--; } - } - if (n1 == 0 && n2 != 0) { - return -(int)toupper(*s2); - } - if (n2 == 0 && n1 != 0) { - return (int)toupper(*s1); - } - if (n2 == 0 && n2 == 0) { - return 0; - } - return (int)toupper(*s1) - (int)toupper(*s2); - -utf8str: - /* no need to recheck from the start, just from the first utf8 char found */ - b1 = ldb_casefold(ldb, mem_ctx, s1, n1); - b2 = ldb_casefold(ldb, mem_ctx, s2, n2); - - if (!b1 || !b2) { - /* One of the strings was not UTF8, so we have no - * options but to do a binary compare */ - talloc_free(b1); - talloc_free(b2); - ret = memcmp(s1, s2, MIN(n1, n2)); - if (ret == 0) { - if (n1 == n2) return 0; - if (n1 > n2) { - return (int)toupper(s1[n2]); - } else { - return -(int)toupper(s2[n1]); - } - } - return ret; - } - - u1 = b1; - u2 = b2; - - while (*u1 & *u2) { - if (*u1 != *u2) - break; - if (*u1 == ' ') { - while (u1[0] == u1[1]) u1++; - while (u2[0] == u2[1]) u2++; - } - u1++; u2++; - } - if (! (*u1 && *u2)) { - while (*u1 == ' ') u1++; - while (*u2 == ' ') u2++; - } - ret = (int)(*u1 - *u2); - - talloc_free(b1); - talloc_free(b2); - - return ret; -} - - -/* - canonicalise a attribute in DN format -*/ -static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn; - int ret = -1; - - out->length = 0; - out->data = NULL; - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); - if (out->data == NULL) { - goto done; - } - out->length = strlen((char *)out->data); - - ret = 0; - -done: - talloc_free(dn); - - return ret; -} - -/* - compare two dns -*/ -static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - int ret; - - dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); - if ( ! ldb_dn_validate(dn1)) return -1; - - dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); - if ( ! ldb_dn_validate(dn2)) { - talloc_free(dn1); - return -1; - } - - ret = ldb_dn_compare(dn1, dn2); - - talloc_free(dn1); - talloc_free(dn2); - return ret; -} - -/* - compare two utc time values. 1 second resolution -*/ -static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - time_t t1=0, t2=0; - ldb_val_to_time(v1, &t1); - ldb_val_to_time(v2, &t2); - if (t1 == t2) return 0; - return t1 > t2? 1 : -1; -} - -/* - canonicalise a utc time -*/ -static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - time_t t; - int ret; - ret = ldb_val_to_time(in, &t); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *)ldb_timestring(mem_ctx, t); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - table of standard attribute handlers -*/ -static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { - { - .name = LDB_SYNTAX_INTEGER, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Integer, - .comparison_fn = ldb_comparison_Integer - }, - { - .name = LDB_SYNTAX_OCTET_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary - }, - { - .name = LDB_SYNTAX_DIRECTORY_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_fold - }, - { - .name = LDB_SYNTAX_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_dn, - .comparison_fn = ldb_comparison_dn - }, - { - .name = LDB_SYNTAX_OBJECTCLASS, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_fold - }, - { - .name = LDB_SYNTAX_UTC_TIME, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_utctime, - .comparison_fn = ldb_comparison_utctime - }, - { - .name = LDB_SYNTAX_BOOLEAN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Boolean, - .comparison_fn = ldb_comparison_Boolean - }, -}; - - -/* - return the attribute handlers for a given syntax name -*/ -const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, - const char *syntax) -{ - unsigned int i; - unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); - /* TODO: should be replaced with a binary search */ - for (i=0;i. -*/ - -/* - * Name: ldb - * - * Component: ldb core API - * - * Description: core API routines interfacing to ldb backends - * - * Author: Andrew Tridgell - */ - -#define TEVENT_DEPRECATED 1 -#include "ldb_private.h" -#include "ldb.h" - -static int ldb_context_destructor(void *ptr) -{ - struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); - - if (ldb->transaction_active) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "A transaction is still active in ldb context [%p] on %s", - ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); - } - - return 0; -} - -/* - this is used to catch debug messages from events -*/ -static void ldb_tevent_debug(void *context, enum tevent_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void ldb_tevent_debug(void *context, enum tevent_debug_level level, - const char *fmt, va_list ap) -{ - struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); - enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; - char *s = NULL; - - switch (level) { - case TEVENT_DEBUG_FATAL: - ldb_level = LDB_DEBUG_FATAL; - break; - case TEVENT_DEBUG_ERROR: - ldb_level = LDB_DEBUG_ERROR; - break; - case TEVENT_DEBUG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - break; - case TEVENT_DEBUG_TRACE: - ldb_level = LDB_DEBUG_TRACE; - break; - }; - - vasprintf(&s, fmt, ap); - if (!s) return; - ldb_debug(ldb, ldb_level, "tevent: %s", s); - free(s); -} - -/* - initialise a ldb context - The mem_ctx is required - The event_ctx is required -*/ -struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) -{ - struct ldb_context *ldb; - int ret; - const char *modules_path = getenv("LDB_MODULES_PATH"); - - if (modules_path == NULL) { - modules_path = LDB_MODULESDIR; - } - - ret = ldb_modules_load(modules_path, LDB_VERSION); - if (ret != LDB_SUCCESS) { - return NULL; - } - - ldb = talloc_zero(mem_ctx, struct ldb_context); - if (ldb == NULL) { - return NULL; - } - - /* A new event context so that callers who don't want ldb - * operating on thier global event context can work without - * having to provide their own private one explicitly */ - if (ev_ctx == NULL) { - ev_ctx = tevent_context_init(ldb); - tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); - tevent_loop_allow_nesting(ev_ctx); - } - - ret = ldb_setup_wellknown_attributes(ldb); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - ldb_set_utf8_default(ldb); - ldb_set_create_perms(ldb, 0666); - ldb_set_modules_dir(ldb, LDB_MODULESDIR); - ldb_set_event_context(ldb, ev_ctx); - - /* TODO: get timeout from options if available there */ - ldb->default_timeout = 300; /* set default to 5 minutes */ - - talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); - - return ldb; -} - -/* - try to autodetect a basedn if none specified. This fixes one of my - pet hates about ldapsearch, which is that you have to get a long, - complex basedn right to make any use of it. -*/ -void ldb_set_default_dns(struct ldb_context *ldb) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_result *res; - struct ldb_dn *tmp_dn=NULL; - static const char *attrs[] = { - "rootDomainNamingContext", - "configurationNamingContext", - "schemaNamingContext", - "defaultNamingContext", - NULL - }; - - tmp_ctx = talloc_new(ldb); - ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL), - LDB_SCOPE_BASE, attrs, "(objectClass=*)"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return; - } - - if (res->count != 1) { - talloc_free(tmp_ctx); - return; - } - - if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "rootDomainNamingContext"); - ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "configurationNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "configurationNamingContext"); - ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "schemaNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "schemaNamingContext"); - ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "defaultNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "defaultNamingContext"); - ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn); - } - - talloc_free(tmp_ctx); -} - -struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "configurationNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "schemaNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "defaultNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -/* - connect to a database. The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific -*/ -int ldb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[]) -{ - int ret; - char *url2; - /* We seem to need to do this here, or else some utilities don't - * get ldb backends */ - - ldb->flags = flags; - - url2 = talloc_strdup(ldb, url); - if (!url2) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_set_opaque(ldb, "ldb_url", url2); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (ldb_load_modules(ldb, options) != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to load modules for %s: %s", - url, ldb_errstring(ldb)); - return LDB_ERR_OTHER; - } - - /* set the default base dn */ - ldb_set_default_dns(ldb); - - return LDB_SUCCESS; -} - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) -{ - if (ldb->err_string) { - talloc_free(ldb->err_string); - } - ldb->err_string = talloc_strdup(ldb, err_string); - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_set_errstring: %s", ldb->err_string); - } -} - -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) -{ - va_list ap; - char *old_string = NULL; - - if (ldb->err_string) { - old_string = ldb->err_string; - } - - va_start(ap, format); - ldb->err_string = talloc_vasprintf(ldb, format, ap); - va_end(ap); - talloc_free(old_string); -} - -void ldb_reset_err_string(struct ldb_context *ldb) -{ - if (ldb->err_string) { - talloc_free(ldb->err_string); - ldb->err_string = NULL; - } -} - - - -/* - set an ldb error based on file:line -*/ -int ldb_error_at(struct ldb_context *ldb, int ecode, - const char *reason, const char *file, int line) -{ - if (reason == NULL) { - reason = ldb_strerror(ecode); - } - ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); - return ecode; -} - - -#define FIRST_OP_NOERR(ldb, op) do { \ - module = ldb->modules; \ - while (module && module->ops->op == NULL) module = module->next; \ - if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \ - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ - module->ops->name); \ - } \ -} while (0) - -#define FIRST_OP(ldb, op) do { \ - FIRST_OP_NOERR(ldb, op); \ - if (module == NULL) { \ - ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - - -/* - start a transaction -*/ -int ldb_transaction_start(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "start ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* explicit transaction active, count nested requests */ - if (ldb->transaction_active) { - ldb->transaction_active++; - return LDB_SUCCESS; - } - - /* start a new transaction */ - ldb->transaction_active++; - ldb->prepare_commit_done = false; - - FIRST_OP(ldb, start_transaction); - - ldb_reset_err_string(ldb); - - status = module->ops->start_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction start: %s (%d)", - ldb_strerror(status), - status); - } - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", - ldb_errstring(module->ldb)); - } - return status; -} - -/* - prepare for transaction commit (first phase of two phase commit) -*/ -int ldb_transaction_prepare_commit(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - - if (ldb->prepare_commit_done) { - return LDB_SUCCESS; - } - - /* commit only when all nested transactions are complete */ - if (ldb->transaction_active > 1) { - return LDB_SUCCESS; - } - - ldb->prepare_commit_done = true; - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "prepare commit called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - /* call prepare transaction if available */ - FIRST_OP_NOERR(ldb, prepare_commit); - if (module == NULL) { - return LDB_SUCCESS; - } - - status = module->ops->prepare_commit(module); - if (status != LDB_SUCCESS) { - /* if a module fails the prepare then we need - to call the end transaction for everyone */ - FIRST_OP(ldb, del_transaction); - module->ops->del_transaction(module); - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction prepare commit: %s (%d)", - ldb_strerror(status), - status); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", - ldb_errstring(module->ldb)); - } - } - - return status; -} - - -/* - commit a transaction -*/ -int ldb_transaction_commit(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - - status = ldb_transaction_prepare_commit(ldb); - if (status != LDB_SUCCESS) { - return status; - } - - ldb->transaction_active--; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "commit ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* commit only when all nested transactions are complete */ - if (ldb->transaction_active > 0) { - return LDB_SUCCESS; - } - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "commit called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_reset_err_string(ldb); - - FIRST_OP(ldb, end_transaction); - status = module->ops->end_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction commit: %s (%d)", - ldb_strerror(status), - status); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", - ldb_errstring(module->ldb)); - } - /* cancel the transaction */ - FIRST_OP(ldb, del_transaction); - module->ops->del_transaction(module); - } - return status; -} - - -/* - cancel a transaction -*/ -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - - ldb->transaction_active--; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "cancel ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* really cancel only if all nested transactions are complete */ - if (ldb->transaction_active > 0) { - return LDB_SUCCESS; - } - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "cancel called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - FIRST_OP(ldb, del_transaction); - - status = module->ops->del_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction cancel: %s (%d)", - ldb_strerror(status), - status); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", - ldb_errstring(module->ldb)); - } - } - return status; -} - -/* - cancel a transaction with no error if no transaction is pending - used when we fork() to clear any parent transactions -*/ -int ldb_transaction_cancel_noerr(struct ldb_context *ldb) -{ - if (ldb->transaction_active > 0) { - return ldb_transaction_cancel(ldb); - } - return LDB_SUCCESS; -} - - -/* autostarts a transacion if none active */ -static int ldb_autotransaction_request(struct ldb_context *ldb, - struct ldb_request *req) -{ - int ret; - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request(ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - return ldb_transaction_commit(ldb); - } - ldb_transaction_cancel(ldb); - - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); - } - - return ret; -} - -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct tevent_context *ev; - int ret; - - if (!handle) { - return LDB_ERR_UNAVAILABLE; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - ev = ldb_get_event_context(handle->ldb); - if (NULL == ev) { - return LDB_ERR_OPERATIONS_ERROR; - } - - switch (type) { - case LDB_WAIT_NONE: - ret = tevent_loop_once(ev); - if (ret != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (handle->state == LDB_ASYNC_DONE || - handle->status != LDB_SUCCESS) { - return handle->status; - } - break; - - case LDB_WAIT_ALL: - while (handle->state != LDB_ASYNC_DONE) { - ret = tevent_loop_once(ev); - if (ret != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (handle->status != LDB_SUCCESS) { - return handle->status; - } - } - return handle->status; - } - - return LDB_SUCCESS; -} - -/* set the specified timeout or, if timeout is 0 set the default timeout */ -int ldb_set_timeout(struct ldb_context *ldb, - struct ldb_request *req, - int timeout) -{ - if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; - - if (timeout != 0) { - req->timeout = timeout; - } else { - req->timeout = ldb->default_timeout; - } - req->starttime = time(NULL); - - return LDB_SUCCESS; -} - -/* calculates the new timeout based on the previous starttime and timeout */ -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, - struct ldb_request *oldreq, - struct ldb_request *newreq) -{ - if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; - - if (oldreq == NULL) { - return ldb_set_timeout(ldb, newreq, 0); - } - - newreq->starttime = oldreq->starttime; - newreq->timeout = oldreq->timeout; - - return LDB_SUCCESS; -} - - -/* - set the permissions for new files to be passed to open() in - backends that use local files - */ -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) -{ - ldb->create_perms = perms; -} - -unsigned int ldb_get_create_perms(struct ldb_context *ldb) -{ - return ldb->create_perms; -} - -void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev) -{ - ldb->ev_ctx = ev; -} - -struct tevent_context * ldb_get_event_context(struct ldb_context *ldb) -{ - return ldb->ev_ctx; -} - -void ldb_request_set_state(struct ldb_request *req, int state) -{ - req->handle->state = state; -} - -int ldb_request_get_status(struct ldb_request *req) -{ - return req->handle->status; -} - - -/* - trace a ldb request -*/ -static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req) -{ - TALLOC_CTX *tmp_ctx = talloc_new(req); - unsigned int i; - - switch (req->operation) { - case LDB_SEARCH: - ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n"); - ldb_debug_add(ldb, " dn: %s\n", - ldb_dn_is_null(req->op.search.base)?"": - ldb_dn_get_linearized(req->op.search.base)); - ldb_debug_add(ldb, " scope: %s\n", - req->op.search.scope==LDB_SCOPE_BASE?"base": - req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": - req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN"); - ldb_debug_add(ldb, " expr: %s\n", - ldb_filter_from_tree(tmp_ctx, req->op.search.tree)); - if (req->op.search.attrs == NULL) { - ldb_debug_add(ldb, " attr: \n"); - } else { - for (i=0; req->op.search.attrs[i]; i++) { - ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]); - } - } - break; - case LDB_DELETE: - ldb_debug_add(ldb, "ldb_trace_request: DELETE\n"); - ldb_debug_add(ldb, " dn: %s\n", - ldb_dn_get_linearized(req->op.del.dn)); - break; - case LDB_RENAME: - ldb_debug_add(ldb, "ldb_trace_request: RENAME\n"); - ldb_debug_add(ldb, " olddn: %s\n", - ldb_dn_get_linearized(req->op.rename.olddn)); - ldb_debug_add(ldb, " newdn: %s\n", - ldb_dn_get_linearized(req->op.rename.newdn)); - break; - case LDB_EXTENDED: - ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n"); - ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid); - ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no"); - break; - case LDB_ADD: - ldb_debug_add(ldb, "ldb_trace_request: ADD\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_ldif_message_string(req->handle->ldb, tmp_ctx, - LDB_CHANGETYPE_ADD, - req->op.add.message)); - break; - case LDB_MODIFY: - ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_ldif_message_string(req->handle->ldb, tmp_ctx, - LDB_CHANGETYPE_ADD, - req->op.mod.message)); - break; - case LDB_REQ_REGISTER_CONTROL: - ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - req->op.reg_control.oid); - break; - case LDB_REQ_REGISTER_PARTITION: - ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_dn_get_linearized(req->op.reg_partition.dn)); - break; - default: - ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n", - req->operation); - break; - } - - if (req->controls == NULL) { - ldb_debug_add(ldb, " control: \n"); - } else { - for (i=0; req->controls && req->controls[i]; i++) { - if (req->controls[i]->oid) { - ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", - req->controls[i]->oid, - req->controls[i]->critical, - req->controls[i]->data?"yes":"no"); - } - } - } - - ldb_debug_end(ldb, LDB_DEBUG_TRACE); - - talloc_free(tmp_ctx); -} - -/* - check that the element flags don't have any internal bits set - */ -static int ldb_msg_check_element_flags(struct ldb_context *ldb, - const struct ldb_message *message) -{ - unsigned i; - for (i=0; inum_elements; i++) { - if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { - ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", - message->elements[i].flags, message->elements[i].name, - ldb_dn_get_linearized(message->dn)); - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - return LDB_SUCCESS; -} - - -/* - start an ldb request - NOTE: the request must be a talloc context. - returns LDB_ERR_* on errors. -*/ -int ldb_request(struct ldb_context *ldb, struct ldb_request *req) -{ - struct ldb_module *module; - int ret; - - if (req->callback == NULL) { - ldb_set_errstring(ldb, "Requests MUST define callbacks"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ldb_reset_err_string(ldb); - - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_trace_request(ldb, req); - } - - /* call the first module in the chain */ - switch (req->operation) { - case LDB_SEARCH: - /* due to "ldb_build_search_req" base DN always != NULL */ - if (!ldb_dn_validate(req->op.search.base)) { - ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", - ldb_dn_get_linearized(req->op.search.base)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, search); - ret = module->ops->search(module, req); - break; - case LDB_ADD: - if (!ldb_dn_validate(req->op.add.message->dn)) { - ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", - ldb_dn_get_linearized(req->op.add.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - /* - * we have to normalize here, as so many places - * in modules and backends assume we don't have two - * elements with the same name - */ - ret = ldb_msg_normalize(ldb, req, req->op.add.message, - discard_const(&req->op.add.message)); - if (ret != LDB_SUCCESS) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - FIRST_OP(ldb, add); - ret = ldb_msg_check_element_flags(ldb, req->op.add.message); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = module->ops->add(module, req); - break; - case LDB_MODIFY: - if (!ldb_dn_validate(req->op.mod.message->dn)) { - ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, modify); - ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = module->ops->modify(module, req); - break; - case LDB_DELETE: - if (!ldb_dn_validate(req->op.del.dn)) { - ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", - ldb_dn_get_linearized(req->op.del.dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, del); - ret = module->ops->del(module, req); - break; - case LDB_RENAME: - if (!ldb_dn_validate(req->op.rename.olddn)) { - ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", - ldb_dn_get_linearized(req->op.rename.olddn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - if (!ldb_dn_validate(req->op.rename.newdn)) { - ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", - ldb_dn_get_linearized(req->op.rename.newdn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, rename); - ret = module->ops->rename(module, req); - break; - case LDB_EXTENDED: - FIRST_OP(ldb, extended); - ret = module->ops->extended(module, req); - break; - default: - FIRST_OP(ldb, request); - ret = module->ops->request(module, req); - break; - } - - return ret; -} - -int ldb_request_done(struct ldb_request *req, int status) -{ - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = status; - return status; -} - -/* - search the database given a LDAP-like search expression - - returns an LDB error code - - Use talloc_free to free the ldb_message returned in 'res', if successful - -*/ -int ldb_search_default_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_result *res; - unsigned int n; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - res->msgs = talloc_realloc(res, res->msgs, - struct ldb_message *, res->count + 2); - if (! res->msgs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->msgs[res->count + 1] = NULL; - - res->msgs[res->count] = talloc_move(res->msgs, &ares->message); - res->count++; - break; - - case LDB_REPLY_REFERRAL: - if (res->refs) { - for (n = 0; res->refs[n]; n++) /*noop*/ ; - } else { - n = 0; - } - - res->refs = talloc_realloc(res, res->refs, char *, n + 2); - if (! res->refs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->refs[n] = talloc_move(res->refs, &ares->referral); - res->refs[n + 1] = NULL; - break; - - case LDB_REPLY_DONE: - /* TODO: we should really support controls on entries - * and referrals too! */ - res->controls = talloc_move(res, &ares->controls); - - /* this is the last message, and means the request is done */ - /* we have to signal and eventual ldb_wait() waiting that the - * async request operation was completed */ - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - - return LDB_SUCCESS; -} - -int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_result *res; - unsigned int n; - int ret; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->error != LDB_SUCCESS) { - ret = ares->error; - talloc_free(ares); - return ldb_request_done(req, ret); - } - - switch (ares->type) { - case LDB_REPLY_REFERRAL: - if (res->refs) { - for (n = 0; res->refs[n]; n++) /*noop*/ ; - } else { - n = 0; - } - - res->refs = talloc_realloc(res, res->refs, char *, n + 2); - if (! res->refs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->refs[n] = talloc_move(res->refs, &ares->referral); - res->refs[n + 1] = NULL; - break; - - case LDB_REPLY_DONE: - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - default: - talloc_free(ares); - ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); -} - -int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - int ret; - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->error != LDB_SUCCESS) { - ret = ares->error; - talloc_free(ares); - return ldb_request_done(req, ret); - } - - if (ares->type != LDB_REPLY_DONE) { - talloc_free(ares); - ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); -} - -int ldb_build_search_req_ex(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEARCH; - if (base == NULL) { - req->op.search.base = ldb_dn_new(req, ldb, NULL); - } else { - req->op.search.base = base; - } - req->op.search.scope = scope; - - req->op.search.tree = tree; - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "'tree' can't be NULL"); - talloc_free(req); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.search.attrs = attrs; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_parse_tree *tree; - int ret; - - tree = ldb_parse_tree(mem_ctx, expression); - if (tree == NULL) { - ldb_set_errstring(ldb, "Unable to parse search expression"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base, - scope, tree, attrs, controls, - context, callback, parent); - if (ret == LDB_SUCCESS) { - talloc_steal(*ret_req, tree); - } - return ret; -} - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_ADD; - req->op.add.message = message; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_MODIFY; - req->op.mod.message = message; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_DELETE; - req->op.del.dn = dn; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_RENAME; - req->op.rename.olddn = olddn; - req->op.rename.newdn = newdn; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_extended_default_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_result *res; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - if (ares->type == LDB_REPLY_DONE) { - - /* TODO: we should really support controls on entries and referrals too! */ - res->extended = talloc_move(res, &ares->response); - res->controls = talloc_move(res, &ares->controls); - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); -} - -int ldb_build_extended_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *oid, - void *data, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_EXTENDED; - req->op.extended.oid = oid; - req->op.extended.data = data; - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (parent) { - req->handle->nesting++; - req->handle->parent = parent; - req->handle->flags = parent->handle->flags; - req->handle->custom_flags = parent->handle->custom_flags; - } - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_extended(struct ldb_context *ldb, - const char *oid, - void *data, - struct ldb_result **_res) -{ - struct ldb_request *req; - int ret; - struct ldb_result *res; - - *_res = NULL; - - res = talloc_zero(ldb, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_extended_req(&req, ldb, ldb, - oid, data, NULL, - res, ldb_extended_default_callback, - NULL); - if (ret != LDB_SUCCESS) goto done; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - talloc_free(req); - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - } - - *_res = res; - return ret; -} - -/* - note that ldb_search() will automatically replace a NULL 'base' value - with the defaultNamingContext from the rootDSE if available. -*/ -int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...) -{ - struct ldb_request *req; - struct ldb_result *res; - char *expression; - va_list ap; - int ret; - - expression = NULL; - *result = NULL; - req = NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (exp_fmt) { - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); - - if (!expression) { - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ret = ldb_build_search_req(&req, ldb, mem_ctx, - base?base:ldb_get_default_basedn(ldb), - scope, - expression, - attrs, - NULL, - res, - ldb_search_default_callback, - NULL); - ldb_req_set_location(req, "ldb_search"); - - if (ret != LDB_SUCCESS) goto done; - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - res = NULL; - } - - talloc_free(expression); - talloc_free(req); - - *result = res; - return ret; -} - -/* - add a record to the database. Will fail if a record with the given class - and key already exists -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&req, ldb, ldb, - message, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_add"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - modify the specified attributes of a record -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&req, ldb, ldb, - message, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_modify"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - delete a record from the database -*/ -int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_del_req(&req, ldb, ldb, - dn, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_delete"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - rename a record in the database -*/ -int ldb_rename(struct ldb_context *ldb, - struct ldb_dn *olddn, struct ldb_dn *newdn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_rename_req(&req, ldb, ldb, - olddn, - newdn, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_rename"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - return the global sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, - enum ldb_sequence_type type, uint64_t *seq_num) -{ - struct ldb_seqnum_request *seq; - struct ldb_seqnum_result *seqr; - struct ldb_result *res; - TALLOC_CTX *tmp_ctx; - int ret; - - *seq_num = 0; - - tmp_ctx = talloc_zero(ldb, struct ldb_request); - if (tmp_ctx == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request); - if (seq == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - seq->type = type; - - ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res); - if (ret != LDB_SUCCESS) { - goto done; - } - talloc_steal(tmp_ctx, res); - - if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) { - ldb_set_errstring(ldb, "Invalid OID in reply"); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - seqr = talloc_get_type(res->extended->data, - struct ldb_seqnum_result); - *seq_num = seqr->seq_num; - -done: - talloc_free(tmp_ctx); - return ret; -} - -/* - return extended error information -*/ -const char *ldb_errstring(struct ldb_context *ldb) -{ - if (ldb->err_string) { - return ldb->err_string; - } - - return NULL; -} - -/* - return a string explaining what a ldb error constant meancs -*/ -const char *ldb_strerror(int ldb_err) -{ - switch (ldb_err) { - case LDB_SUCCESS: - return "Success"; - case LDB_ERR_OPERATIONS_ERROR: - return "Operations error"; - case LDB_ERR_PROTOCOL_ERROR: - return "Protocol error"; - case LDB_ERR_TIME_LIMIT_EXCEEDED: - return "Time limit exceeded"; - case LDB_ERR_SIZE_LIMIT_EXCEEDED: - return "Size limit exceeded"; - case LDB_ERR_COMPARE_FALSE: - return "Compare false"; - case LDB_ERR_COMPARE_TRUE: - return "Compare true"; - case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: - return "Auth method not supported"; - case LDB_ERR_STRONG_AUTH_REQUIRED: - return "Strong auth required"; -/* 9 RESERVED */ - case LDB_ERR_REFERRAL: - return "Referral error"; - case LDB_ERR_ADMIN_LIMIT_EXCEEDED: - return "Admin limit exceeded"; - case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: - return "Unsupported critical extension"; - case LDB_ERR_CONFIDENTIALITY_REQUIRED: - return "Confidentiality required"; - case LDB_ERR_SASL_BIND_IN_PROGRESS: - return "SASL bind in progress"; - case LDB_ERR_NO_SUCH_ATTRIBUTE: - return "No such attribute"; - case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: - return "Undefined attribute type"; - case LDB_ERR_INAPPROPRIATE_MATCHING: - return "Inappropriate matching"; - case LDB_ERR_CONSTRAINT_VIOLATION: - return "Constraint violation"; - case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: - return "Attribute or value exists"; - case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: - return "Invalid attribute syntax"; -/* 22-31 unused */ - case LDB_ERR_NO_SUCH_OBJECT: - return "No such object"; - case LDB_ERR_ALIAS_PROBLEM: - return "Alias problem"; - case LDB_ERR_INVALID_DN_SYNTAX: - return "Invalid DN syntax"; -/* 35 RESERVED */ - case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: - return "Alias dereferencing problem"; -/* 37-47 unused */ - case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: - return "Inappropriate authentication"; - case LDB_ERR_INVALID_CREDENTIALS: - return "Invalid credentials"; - case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: - return "insufficient access rights"; - case LDB_ERR_BUSY: - return "Busy"; - case LDB_ERR_UNAVAILABLE: - return "Unavailable"; - case LDB_ERR_UNWILLING_TO_PERFORM: - return "Unwilling to perform"; - case LDB_ERR_LOOP_DETECT: - return "Loop detect"; -/* 55-63 unused */ - case LDB_ERR_NAMING_VIOLATION: - return "Naming violation"; - case LDB_ERR_OBJECT_CLASS_VIOLATION: - return "Object class violation"; - case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: - return "Not allowed on non-leaf"; - case LDB_ERR_NOT_ALLOWED_ON_RDN: - return "Not allowed on RDN"; - case LDB_ERR_ENTRY_ALREADY_EXISTS: - return "Entry already exists"; - case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: - return "Object class mods prohibited"; -/* 70 RESERVED FOR CLDAP */ - case LDB_ERR_AFFECTS_MULTIPLE_DSAS: - return "Affects multiple DSAs"; -/* 72-79 unused */ - case LDB_ERR_OTHER: - return "Other"; - } - - return "Unknown error"; -} - -/* - set backend specific opaque parameters -*/ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) -{ - struct ldb_opaque *o; - - /* allow updating an existing value */ - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - o->value = value; - return LDB_SUCCESS; - } - } - - o = talloc(ldb, struct ldb_opaque); - if (o == NULL) { - ldb_oom(ldb); - return LDB_ERR_OTHER; - } - o->next = ldb->opaque; - o->name = name; - o->value = value; - ldb->opaque = o; - return LDB_SUCCESS; -} - -/* - get a previously set opaque value -*/ -void *ldb_get_opaque(struct ldb_context *ldb, const char *name) -{ - struct ldb_opaque *o; - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - return o->value; - } - } - return NULL; -} - -int ldb_global_init(void) -{ - /* Provided for compatibility with some older versions of ldb */ - return 0; -} - -/* return the ldb flags */ -unsigned int ldb_get_flags(struct ldb_context *ldb) -{ - return ldb->flags; -} - -/* set the ldb flags */ -void ldb_set_flags(struct ldb_context *ldb, unsigned flags) -{ - ldb->flags = flags; -} - - -/* - set the location in a ldb request. Used for debugging - */ -void ldb_req_set_location(struct ldb_request *req, const char *location) -{ - if (req && req->handle) { - req->handle->location = location; - } -} - -/* - return the location set with dsdb_req_set_location - */ -const char *ldb_req_location(struct ldb_request *req) -{ - return req->handle->location; -} - -/** - mark a request as untrusted. This tells the rootdse module to remove - unregistered controls - */ -void ldb_req_mark_untrusted(struct ldb_request *req) -{ - req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; -} - -/** - mark a request as trusted. - */ -void ldb_req_mark_trusted(struct ldb_request *req) -{ - req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; -} - -/** - set custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) -{ - if (req != NULL && req->handle != NULL) { - req->handle->custom_flags = flags; - } -} - - -/** - get custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -uint32_t ldb_req_get_custom_flags(struct ldb_request *req) -{ - if (req != NULL && req->handle != NULL) { - return req->handle->custom_flags; - } - - /* - * 0 is not something any better or worse than - * anything else as req or the handle is NULL - */ - return 0; -} - - -/** - return true is a request is untrusted - */ -bool ldb_req_is_untrusted(struct ldb_request *req) -{ - return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; -} diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c deleted file mode 100644 index 21a3e6eb93b..00000000000 --- a/source4/lib/ldb/common/ldb_attributes.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** 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 . -*/ -/* - register handlers for specific attributes and objectclass relationships - - this allows a backend to store its schema information in any format - it likes (or to not have any schema information at all) while keeping the - message matching logic generic -*/ - -#include "ldb_private.h" -#include "ldb_handlers.h" - -/* - add a attribute to the ldb_schema - - if flags contains LDB_ATTR_FLAG_ALLOCATED - the attribute name string will be copied using - talloc_strdup(), otherwise it needs to be a static const - string at least with a lifetime longer than the ldb struct! - - the ldb_schema_syntax structure should be a pointer - to a static const struct or at least it needs to be - a struct with a longer lifetime than the ldb context! - -*/ -int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, - const char *attribute, - unsigned flags, - const struct ldb_schema_syntax *syntax) -{ - unsigned int i, n; - struct ldb_schema_attribute *a; - - if (!syntax) { - return LDB_ERR_OPERATIONS_ERROR; - } - - n = ldb->schema.num_attributes + 1; - - a = talloc_realloc(ldb, ldb->schema.attributes, - struct ldb_schema_attribute, n); - if (a == NULL) { - ldb_oom(ldb); - return -1; - } - ldb->schema.attributes = a; - - for (i = 0; i < ldb->schema.num_attributes; i++) { - int cmp = ldb_attr_cmp(attribute, a[i].name); - if (cmp == 0) { - /* silently ignore attempts to overwrite fixed attributes */ - if (a[i].flags & LDB_ATTR_FLAG_FIXED) { - return 0; - } - if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, a[i].name)); - } - /* To cancel out increment below */ - ldb->schema.num_attributes--; - break; - } else if (cmp < 0) { - memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i)); - break; - } - } - ldb->schema.num_attributes++; - - a[i].name = attribute; - a[i].flags = flags; - a[i].syntax = syntax; - - if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { - a[i].name = talloc_strdup(a, a[i].name); - if (a[i].name == NULL) { - ldb_oom(ldb); - return -1; - } - } - - return 0; -} - -static const struct ldb_schema_syntax ldb_syntax_default = { - .name = LDB_SYNTAX_OCTET_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary -}; - -static const struct ldb_schema_attribute ldb_attribute_default = { - .name = NULL, - .flags = 0, - .syntax = &ldb_syntax_default -}; - -/* - return the attribute handlers for a given attribute -*/ -static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal( - struct ldb_context *ldb, - const char *name) -{ - /* for binary search we need signed variables */ - unsigned int i, e, b = 0; - int r; - const struct ldb_schema_attribute *def = &ldb_attribute_default; - - /* as handlers are sorted, '*' must be the first if present */ - if (strcmp(ldb->schema.attributes[0].name, "*") == 0) { - def = &ldb->schema.attributes[0]; - b = 1; - } - - /* do a binary search on the array */ - e = ldb->schema.num_attributes - 1; - - while ((b <= e) && (e != (unsigned int) -1)) { - i = (b + e) / 2; - - r = ldb_attr_cmp(name, ldb->schema.attributes[i].name); - if (r == 0) { - return &ldb->schema.attributes[i]; - } - if (r < 0) { - e = i - 1; - } else { - b = i + 1; - } - } - - return def; -} - -/* - return the attribute handlers for a given attribute -*/ -const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, - const char *name) -{ - if (ldb->schema.attribute_handler_override) { - const struct ldb_schema_attribute *ret = - ldb->schema.attribute_handler_override(ldb, - ldb->schema.attribute_handler_override_private, - name); - if (ret) { - return ret; - } - } - - return ldb_schema_attribute_by_name_internal(ldb, name); -} - - -/* - add to the list of ldif handlers for this ldb context -*/ -void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name) -{ - const struct ldb_schema_attribute *a; - ptrdiff_t i; - - a = ldb_schema_attribute_by_name_internal(ldb, name); - if (a == NULL || a->name == NULL) { - return; - } - - /* FIXED attributes are never removed */ - if (a->flags & LDB_ATTR_FLAG_FIXED) { - return; - } - - if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, a->name)); - } - - i = a - ldb->schema.attributes; - if (i < ldb->schema.num_attributes - 1) { - memmove(&ldb->schema.attributes[i], - a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); - } - - ldb->schema.num_attributes--; -} - -/* - setup a attribute handler using a standard syntax -*/ -int ldb_schema_attribute_add(struct ldb_context *ldb, - const char *attribute, - unsigned flags, - const char *syntax) -{ - const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax); - return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s); -} - -/* - setup the attribute handles for well known attributes -*/ -int ldb_setup_wellknown_attributes(struct ldb_context *ldb) -{ - const struct { - const char *attr; - const char *syntax; - } wellknown[] = { - { "dn", LDB_SYNTAX_DN }, - { "distinguishedName", LDB_SYNTAX_DN }, - { "cn", LDB_SYNTAX_DIRECTORY_STRING }, - { "dc", LDB_SYNTAX_DIRECTORY_STRING }, - { "ou", LDB_SYNTAX_DIRECTORY_STRING }, - { "objectClass", LDB_SYNTAX_OBJECTCLASS } - }; - unsigned int i; - int ret; - - for (i=0;ischema.num_dn_extended_syntax + 1; - - a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, - struct ldb_dn_extended_syntax, n); - - if (!a) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a[ldb->schema.num_dn_extended_syntax] = *syntax; - ldb->schema.dn_extended_syntax = a; - - ldb->schema.num_dn_extended_syntax = n; - - return LDB_SUCCESS; -} - -/* - return the extended dn syntax for a given name -*/ -const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, - const char *name) -{ - unsigned int i; - for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { - if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { - return &ldb->schema.dn_extended_syntax[i]; - } - } - return NULL; -} - -/* - set an attribute handler override function - used to delegate schema handling - to external code - */ -void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, - ldb_attribute_handler_override_fn_t override, - void *private_data) -{ - ldb->schema.attribute_handler_override_private = private_data; - ldb->schema.attribute_handler_override = override; -} diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c deleted file mode 100644 index b3ef2434932..00000000000 --- a/source4/lib/ldb/common/ldb_controls.c +++ /dev/null @@ -1,1043 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** 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_controls.c - * - * Component: ldb controls utility functions - * - * Description: helper functions for control modules - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" - -/* check if a control with the specified "oid" exist and return it */ -/* returns NULL if not found */ -struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) -{ - unsigned int i; - - if (req->controls != NULL) { - for (i = 0; req->controls[i]; i++) { - if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { - break; - } - } - - return req->controls[i]; - } - - return NULL; -} - -/* check if a control with the specified "oid" exist and return it */ -/* returns NULL if not found */ -struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) -{ - unsigned int i; - - if (rep->controls != NULL) { - for (i = 0; rep->controls[i]; i++) { - if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { - break; - } - } - - return rep->controls[i]; - } - - return NULL; -} - -/* - * Saves the current controls list into the "saver" (can also be NULL) and - * replace the one in "req" with a new one excluding the "exclude" control - * (if it is NULL then the list remains the same) - * - * Returns 0 on error. - */ -int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) -{ - struct ldb_control **lcs, **lcs_old; - unsigned int i, j; - - lcs_old = req->controls; - if (saver != NULL) { - *saver = lcs_old; - } - - for (i = 0; req->controls && req->controls[i]; i++); - if (i == 0) { - req->controls = NULL; - return 1; - } - - lcs = talloc_array(req, struct ldb_control *, i + 1); - if (!lcs) { - return 0; - } - - for (i = 0, j = 0; lcs_old[i]; i++) { - if (exclude == lcs_old[i]) continue; - lcs[j] = lcs_old[i]; - j++; - } - lcs[j] = NULL; - - req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); - if (req->controls == NULL) { - return 0; - } - return 1; -} - -/* - * Returns a list of controls, except the one specified with "exclude" (can - * also be NULL). Included controls become a child of returned list if they - * were children of "controls_in". - * - * Returns NULL on error (OOM) or an empty control list. - */ -struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, - TALLOC_CTX *mem_ctx, - struct ldb_control *exclude) -{ - struct ldb_control **lcs = NULL; - unsigned int i, j, n; - - for (i = 0; controls_in && controls_in[i]; i++); - if (i == 0) { - return NULL; - } - n = i; - - for (i = 0, j = 0; controls_in && controls_in[i]; i++) { - if (exclude == controls_in[i]) continue; - - if (!lcs) { - /* Allocate here so if we remove the only - * control, or there were no controls, we - * don't allocate at all, and just return - * NULL */ - lcs = talloc_array(mem_ctx, struct ldb_control *, - n + 1); - if (!lcs) { - return NULL; - } - } - - lcs[j] = controls_in[i]; - talloc_reparent(controls_in, lcs, lcs[j]); - j++; - } - if (lcs) { - lcs[j] = NULL; - - lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); - } - - return lcs; -} - -/* check if there's any control marked as critical in the list */ -/* return True if any, False if none */ -int ldb_check_critical_controls(struct ldb_control **controls) -{ - unsigned int i; - - if (controls == NULL) { - return 0; - } - - for (i = 0; controls[i]; i++) { - if (controls[i]->critical) { - return 1; - } - } - - return 0; -} - -int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) -{ - unsigned int i, n; - struct ldb_control **ctrls; - struct ldb_control *ctrl; - - for (n=0; req->controls && req->controls[n];n++) { - /* having two controls of the same OID makes no sense */ - if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - } - - ctrls = talloc_array(req, - struct ldb_control *, - n + 2); - if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; - - for (i=0; icontrols[i]; - } - - req->controls = ctrls; - ctrls[n] = NULL; - ctrls[n+1] = NULL; - - ctrl = talloc(ctrls, struct ldb_control); - if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; - ctrl->critical = critical; - ctrl->data = data; - - ctrls[n] = ctrl; - return LDB_SUCCESS; -} - -int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) -{ - unsigned n; - struct ldb_control **ctrls; - struct ldb_control *ctrl; - - for (n=0; ares->controls && ares->controls[n];) { - /* having two controls of the same OID makes no sense */ - if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - n++; - } - - ctrls = talloc_realloc(ares, ares->controls, - struct ldb_control *, - n + 2); - if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; - ares->controls = ctrls; - ctrls[n] = NULL; - ctrls[n+1] = NULL; - - ctrl = talloc(ctrls, struct ldb_control); - if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; - ctrl->critical = critical; - ctrl->data = data; - - ctrls[n] = ctrl; - return LDB_SUCCESS; -} - -/* Add a control to the request, replacing the old one if it is already in the request */ -int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) -{ - unsigned int n; - int ret; - - ret = ldb_request_add_control(req, oid, critical, data); - if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { - return ret; - } - - for (n=0; req->controls[n];n++) { - if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { - req->controls[n]->critical = critical; - req->controls[n]->data = data; - return LDB_SUCCESS; - } - } - - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - * Return a control as string - * the project (ie. name:value1:value2:...:valuen - * The string didn't include the criticity of the critical flag - */ -char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) -{ - char *res = NULL; - - if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { - struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); - char *cookie; - - cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); - if (cookie == NULL) { - return NULL; - } - if (cookie[0] != '\0') { - res = talloc_asprintf(mem_ctx, "%s:%d:%s", - LDB_CONTROL_PAGED_RESULTS_NAME, - control->critical, - cookie); - - talloc_free(cookie); - } else { - res = talloc_asprintf(mem_ctx, "%s:%d", - LDB_CONTROL_PAGED_RESULTS_NAME, - control->critical); - } - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { - struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, - struct ldb_vlv_resp_control); - - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%d:%s", - LDB_CONTROL_VLV_RESP_NAME, - control->critical, - rep_control->targetPosition, - rep_control->contentCount, - rep_control->vlv_result, - rep_control->ctxid_len, - rep_control->contextId); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { - struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, - struct ldb_sort_resp_control); - - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", - LDB_CONTROL_SORT_RESP_NAME, - control->critical, - rep_control->result, - rep_control->attr_desc); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { - struct ldb_asq_control *rep_control = talloc_get_type(control->data, - struct ldb_asq_control); - - res = talloc_asprintf(mem_ctx, "%s:%d:%d", - LDB_CONTROL_SORT_RESP_NAME, - control->critical, - rep_control->result); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { - char *cookie; - struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, - struct ldb_dirsync_control); - - cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, - rep_control->cookie_len); - if (cookie == NULL) { - return NULL; - } - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", - LDB_CONTROL_DIRSYNC_NAME, - control->critical, - rep_control->flags, - rep_control->max_attributes, - cookie); - - talloc_free(cookie); - return res; - } - - /* - * From here we don't know the control - */ - if (control->data == NULL) { - /* - * We don't know the control but there is no real data attached to it - * so we can represent it with local_oid:oid:criticity - */ - res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", - control->oid, - control->critical); - return res; - } - - res = talloc_asprintf(mem_ctx, "unknown oid:%s", - control->oid); - return res; -} - - -/* - * A little trick to allow to use constants defined in headers rather than - * hardwritten in the file hardwritten in the file - * sizeof will return the \0 char as well so it will take the place of ":" in the - * length of the string - */ -#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) - -/* Parse one string and return associated control if parsing is successful*/ -struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) -{ - struct ldb_control *ctrl; - char *error_string = NULL; - - if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { - ldb_oom(ldb); - return NULL; - } - - if (LDB_CONTROL_CMP(control_strings, - LDB_CONTROL_VLV_REQ_NAME) == 0) { - struct ldb_vlv_req_control *control; - const char *p; - char attr[1024]; - char ctxid[1024]; - int crit, bc, ac, os, cc, ret; - - attr[0] = '\0'; - ctxid[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); - ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); - if (ret < 5) { - ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); - } - - if ((ret < 4) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):[:ctxid(o)]\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, s = string, o = b64 binary blob"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - ctrl->oid = LDB_CONTROL_VLV_REQ_OID; - ctrl->critical = crit; - if (!(control = talloc(ctrl, - struct ldb_vlv_req_control))) { - ldb_oom(ldb); - return NULL; - } - control->beforeCount = bc; - control->afterCount = ac; - if (attr[0]) { - control->type = 1; - control->match.gtOrEq.value = talloc_strdup(control, attr); - control->match.gtOrEq.value_len = strlen(attr); - } else { - control->type = 0; - control->match.byOffset.offset = os; - control->match.byOffset.contentCount = cc; - } - if (ctxid[0]) { - control->ctxid_len = ldb_base64_decode(ctxid); - control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len); - } else { - control->ctxid_len = 0; - control->contextId = NULL; - } - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { - struct ldb_dirsync_control *control; - const char *p; - char cookie[1024]; - int crit, max_attrs, ret; - uint32_t flags; - - cookie[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); - ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); - - if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) { - error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - /* w2k3 seems to ignore the parameter, - * but w2k sends a wrong cookie when this value is to small - * this would cause looping forever, while getting - * the same data and same cookie forever - */ - if (max_attrs == 0) max_attrs = 0x0FFFFFFF; - - ctrl->oid = LDB_CONTROL_DIRSYNC_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_dirsync_control); - control->flags = flags; - control->max_attributes = max_attrs; - if (*cookie) { - control->cookie_len = ldb_base64_decode(cookie); - control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); - } else { - control->cookie = NULL; - control->cookie_len = 0; - } - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { - struct ldb_asq_control *control; - const char *p; - char attr[256]; - int crit, ret; - - attr[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); - ret = sscanf(p, "%d:%255[^$]", &crit, attr); - if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { - error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_ASQ_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_asq_control); - control->request = 1; - control->source_attribute = talloc_strdup(control, attr); - control->src_attr_len = strlen(attr); - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { - struct ldb_extended_dn_control *control; - const char *p; - int crit, type, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); - ret = sscanf(p, "%d:%d", &crit, &type); - if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean\n"); - error_string = talloc_asprintf_append(error_string, " i = integer\n"); - error_string = talloc_asprintf_append(error_string, " valid values are: 0 - hexadecimal representation\n"); - error_string = talloc_asprintf_append(error_string, " 1 - normal string representation"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - control = NULL; - } else { - control = talloc(ctrl, struct ldb_extended_dn_control); - control->type = type; - } - - ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; - ctrl->critical = crit; - ctrl->data = talloc_steal(ctrl, control); - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { - struct ldb_sd_flags_control *control; - const char *p; - int crit, ret; - unsigned secinfo_flags; - - p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); - ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); - if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) { - error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_sd_flags_control); - control->secinfo_flags = secinfo_flags; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { - struct ldb_search_options_control *control; - const char *p; - int crit, ret; - unsigned search_options; - - p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); - ret = sscanf(p, "%d:%u", &crit, &search_options); - if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) { - error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_search_options_control); - control->search_options = search_options; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid bypassopreational control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid relax control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RELAX_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid recalculate_sd control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { - struct ldb_paged_control *control; - const char *p; - int crit, size, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); - ret = sscanf(p, "%d:%d", &crit, &size); - if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) { - error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_paged_control); - control->size = size; - control->cookie = NULL; - control->cookie_len = 0; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { - struct ldb_server_sort_control **control; - const char *p; - char attr[256]; - char rule[128]; - int crit, rev, ret; - - attr[0] = '\0'; - rule[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); - ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); - if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { - error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; - ctrl->critical = crit; - control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); - control[0] = talloc(control, struct ldb_server_sort_control); - control[0]->attributeName = talloc_strdup(control, attr); - if (rule[0]) - control[0]->orderingRule = talloc_strdup(control, rule); - else - control[0]->orderingRule = NULL; - control[0]->reverse = rev; - control[1] = NULL; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid tree_delete control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid reveal_internals control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (strncmp(control_strings, "local_oid:", 10) == 0) { - const char *p; - int crit = 0, ret = 0; - char oid[256]; - - oid[0] = '\0'; - p = &(control_strings[10]); - ret = sscanf(p, "%64[^:]:%d", oid, &crit); - - if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid local_oid control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: oid(s):crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) { - ldb_oom(ldb); - return NULL; - } - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid rodc_join control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - error_string = talloc_asprintf(mem_ctx, "invalid provision control syntax\n"); - error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); - error_string = talloc_asprintf_append(error_string, " note: b = boolean"); - ldb_set_errstring(ldb, error_string); - talloc_free(error_string); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PROVISION_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - /* - * When no matching control has been found. - */ - return NULL; -} - -/* - * A little trick to allow to use constants defined in headers rather than - * hardwritten in the file hardwritten in the file - * sizeof will return the \0 char as well so it will take the place of ":" in the - * length of the string - */ -#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) - -/* Parse controls from the format used on the command line and in ejs */ -struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) -{ - unsigned int i; - struct ldb_control **ctrl; - - if (control_strings == NULL || control_strings[0] == NULL) - return NULL; - - for (i = 0; control_strings[i]; i++); - - ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); - - ldb_reset_err_string(ldb); - for (i = 0; control_strings[i]; i++) { - ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); - if (ctrl[i] == NULL) { - if( ldb_errstring == NULL ) { - /* no controls matched, throw an error */ - ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); - } - talloc_free(ctrl); - return NULL; - } - } - - ctrl[i] = NULL; - - return ctrl; -} - - diff --git a/source4/lib/ldb/common/ldb_debug.c b/source4/lib/ldb/common/ldb_debug.c deleted file mode 100644 index 6aa58ccf71f..00000000000 --- a/source4/lib/ldb/common/ldb_debug.c +++ /dev/null @@ -1,142 +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 debug - * - * Description: functions for printing debug messages - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - this allows the user to choose their own debug function -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap), - void *context) -{ - ldb->debug_ops.debug = debug; - ldb->debug_ops.context = context; - return 0; -} - -/* - debug function for ldb_set_debug_stderr -*/ -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - if (level <= LDB_DEBUG_WARNING) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } -} - -static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); -} - -/* - convenience function to setup debug messages on stderr - messages of level LDB_DEBUG_WARNING and higher are printed -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb) -{ - return ldb_set_debug(ldb, ldb_debug_stderr, ldb); -} - -/* - log a message -*/ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) -{ - va_list ap; - if (ldb->debug_ops.debug == NULL) { - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_set_debug(ldb, ldb_debug_stderr_all, ldb); - } else { - ldb_set_debug_stderr(ldb); - } - } - va_start(ap, fmt); - ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); - va_end(ap); -} - -/* - add to an accumulated log message - */ -void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (ldb->partial_debug == NULL) { - ldb->partial_debug = talloc_vasprintf(ldb, fmt, ap); - } else { - ldb->partial_debug = talloc_vasprintf_append(ldb->partial_debug, - fmt, ap); - } - va_end(ap); -} - -/* - send the accumulated log message, and free it - */ -void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level) -{ - ldb_debug(ldb, level, "%s", ldb->partial_debug); - talloc_free(ldb->partial_debug); - ldb->partial_debug = NULL; -} - -/* - log a message, and set the ldb error string to the same message -*/ -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - char *msg; - va_start(ap, fmt); - msg = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - if (msg != NULL) { - ldb_set_errstring(ldb, msg); - ldb_debug(ldb, level, "%s", msg); - } - talloc_free(msg); -} - diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c deleted file mode 100644 index cd9055da928..00000000000 --- a/source4/lib/ldb/common/ldb_dn.c +++ /dev/null @@ -1,2101 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** 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 dn creation and manipulation utility functions - * - * Description: - explode a dn into it's own basic elements - * and put them in a structure (only if necessary) - * - manipulate ldb_dn structures - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" -#include - -#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed - -#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0) - -/** - internal ldb exploded dn structures -*/ -struct ldb_dn_component { - - char *name; - struct ldb_val value; - - char *cf_name; - struct ldb_val cf_value; -}; - -struct ldb_dn_ext_component { - - char *name; - struct ldb_val value; -}; - -struct ldb_dn { - - struct ldb_context *ldb; - - /* Special DNs are always linearized */ - bool special; - bool invalid; - - bool valid_case; - - char *linearized; - char *ext_linearized; - char *casefold; - - unsigned int comp_num; - struct ldb_dn_component *components; - - unsigned int ext_comp_num; - struct ldb_dn_ext_component *ext_components; -}; - -/* it is helpful to be able to break on this in gdb */ -static void ldb_dn_mark_invalid(struct ldb_dn *dn) -{ - dn->invalid = true; -} - -/* strdn may be NULL */ -struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const struct ldb_val *strdn) -{ - struct ldb_dn *dn; - - if (! ldb) return NULL; - - if (strdn && strdn->data - && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { - /* The RDN must not contain a character with value 0x0 */ - return NULL; - } - - dn = talloc_zero(mem_ctx, struct ldb_dn); - LDB_DN_NULL_FAILED(dn); - - dn->ldb = talloc_get_type(ldb, struct ldb_context); - if (dn->ldb == NULL) { - /* the caller probably got the arguments to - ldb_dn_new() mixed up */ - talloc_free(dn); - return NULL; - } - - if (strdn->data && strdn->length) { - const char *data = (const char *)strdn->data; - size_t length = strdn->length; - - if (data[0] == '@') { - dn->special = true; - } - dn->ext_linearized = talloc_strndup(dn, data, length); - LDB_DN_NULL_FAILED(dn->ext_linearized); - - if (data[0] == '<') { - const char *p_save, *p = dn->ext_linearized; - do { - p_save = p; - p = strstr(p, ">;"); - if (p) { - p = p + 2; - } - } while (p); - - if (p_save == dn->ext_linearized) { - dn->linearized = talloc_strdup(dn, ""); - } else { - dn->linearized = talloc_strdup(dn, p_save); - } - LDB_DN_NULL_FAILED(dn->linearized); - } else { - dn->linearized = dn->ext_linearized; - dn->ext_linearized = NULL; - } - } else { - dn->linearized = talloc_strdup(dn, ""); - LDB_DN_NULL_FAILED(dn->linearized); - } - - return dn; - -failed: - talloc_free(dn); - return NULL; -} - -/* strdn may be NULL */ -struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const char *strdn) -{ - struct ldb_val blob; - blob.data = discard_const_p(uint8_t, strdn); - blob.length = strdn ? strlen(strdn) : 0; - return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); -} - -struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const char *new_fmt, ...) -{ - char *strdn; - va_list ap; - - if ( (! mem_ctx) || (! ldb)) return NULL; - - va_start(ap, new_fmt); - strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); - va_end(ap); - - if (strdn) { - struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); - talloc_free(strdn); - return dn; - } - - return NULL; -} - -/* see RFC2253 section 2.4 */ -static int ldb_dn_escape_internal(char *dst, const char *src, int len) -{ - const char *p, *s; - char *d; - size_t l; - - p = s = src; - d = dst; - - while (p - src < len) { - p += strcspn(p, ",=\n\r+<>#;\\\" "); - - if (p - src == len) /* found no escapable chars */ - break; - - /* copy the part of the string before the stop */ - memcpy(d, s, p - s); - d += (p - s); /* move to current position */ - - switch (*p) { - case ' ': - if (p == src || (p-src)==(len-1)) { - /* if at the beginning or end - * of the string then escape */ - *d++ = '\\'; - *d++ = *p++; - } else { - /* otherwise don't escape */ - *d++ = *p++; - } - break; - - case '#': - /* despite the RFC, windows escapes a # - anywhere in the string */ - case ',': - case '+': - case '"': - case '\\': - case '<': - case '>': - case '?': - /* these must be escaped using \c form */ - *d++ = '\\'; - *d++ = *p++; - break; - - default: { - /* any others get \XX form */ - unsigned char v; - const char *hexbytes = "0123456789ABCDEF"; - v = *(const unsigned char *)p; - *d++ = '\\'; - *d++ = hexbytes[v>>4]; - *d++ = hexbytes[v&0xF]; - p++; - break; - } - } - s = p; /* move forward */ - } - - /* copy the last part (with zero) and return */ - l = len - (s - src); - memcpy(d, s, l + 1); - - /* return the length of the resulting string */ - return (l + (d - dst)); -} - -char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) -{ - char *dst; - - if (!value.length) - return NULL; - - /* allocate destination string, it will be at most 3 times the source */ - dst = talloc_array(mem_ctx, char, value.length * 3 + 1); - if ( ! dst) { - talloc_free(dst); - return NULL; - } - - ldb_dn_escape_internal(dst, (const char *)value.data, value.length); - - dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1); - - return dst; -} - -/* - explode a DN string into a ldb_dn structure - based on RFC4514 except that we don't support multiple valued RDNs - - TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints - DN must be compliant with RFC2253 -*/ -static bool ldb_dn_explode(struct ldb_dn *dn) -{ - char *p, *ex_name, *ex_value, *data, *d, *dt, *t; - bool trim = true; - bool in_extended = true; - bool in_ex_name = false; - bool in_ex_value = false; - bool in_attr = false; - bool in_value = false; - bool in_quote = false; - bool is_oid = false; - bool escape = false; - unsigned int x; - size_t l; - int ret; - char *parse_dn; - bool is_index; - - if ( ! dn || dn->invalid) return false; - - if (dn->components) { - return true; - } - - if (dn->ext_linearized) { - parse_dn = dn->ext_linearized; - } else { - parse_dn = dn->linearized; - } - - if ( ! parse_dn ) { - return false; - } - - is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); - - /* Empty DNs */ - if (parse_dn[0] == '\0') { - return true; - } - - /* Special DNs case */ - if (dn->special) { - return true; - } - - /* make sure we free this if allocated previously before replacing */ - LDB_FREE(dn->components); - dn->comp_num = 0; - - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - /* in the common case we have 3 or more components */ - /* make sure all components are zeroed, other functions depend on it */ - dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); - if ( ! dn->components) { - return false; - } - - /* Components data space is allocated here once */ - data = talloc_array(dn->components, char, strlen(parse_dn) + 1); - if (!data) { - return false; - } - - p = parse_dn; - t = NULL; - d = dt = data; - - while (*p) { - if (in_extended) { - - if (!in_ex_name && !in_ex_value) { - - if (p[0] == '<') { - p++; - ex_name = d; - in_ex_name = true; - continue; - } else if (p[0] == '\0') { - p++; - continue; - } else { - in_extended = false; - in_attr = true; - dt = d; - - continue; - } - } - - if (in_ex_name && *p == '=') { - *d++ = '\0'; - p++; - ex_value = d; - in_ex_name = false; - in_ex_value = true; - continue; - } - - if (in_ex_value && *p == '>') { - const struct ldb_dn_extended_syntax *ext_syntax; - struct ldb_val ex_val = { - .data = (uint8_t *)ex_value, - .length = d - ex_value - }; - - *d++ = '\0'; - p++; - in_ex_value = false; - - /* Process name and ex_value */ - - dn->ext_components = talloc_realloc(dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num + 1); - if ( ! dn->ext_components) { - /* ouch ! */ - goto failed; - } - - ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); - if (!ext_syntax) { - /* We don't know about this type of extended DN */ - goto failed; - } - - dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name); - if (!dn->ext_components[dn->ext_comp_num].name) { - /* ouch */ - goto failed; - } - ret = ext_syntax->read_fn(dn->ldb, dn->ext_components, - &ex_val, &dn->ext_components[dn->ext_comp_num].value); - if (ret != LDB_SUCCESS) { - ldb_dn_mark_invalid(dn); - goto failed; - } - - dn->ext_comp_num++; - - if (*p == '\0') { - /* We have reached the end (extended component only)! */ - talloc_free(data); - return true; - - } else if (*p == ';') { - p++; - continue; - } else { - ldb_dn_mark_invalid(dn); - goto failed; - } - } - - *d++ = *p++; - continue; - } - if (in_attr) { - if (trim) { - if (*p == ' ') { - p++; - continue; - } - - /* first char */ - trim = false; - - if (!isascii(*p)) { - /* attr names must be ascii only */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (isdigit(*p)) { - is_oid = true; - } else - if ( ! isalpha(*p)) { - /* not a digit nor an alpha, - * invalid attribute name */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - /* Copy this character across from parse_dn, - * now we have trimmed out spaces */ - *d++ = *p++; - continue; - } - - if (*p == ' ') { - p++; - /* valid only if we are at the end */ - trim = true; - continue; - } - - if (trim && (*p != '=')) { - /* spaces/tabs are not allowed */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (*p == '=') { - /* attribute terminated */ - in_attr = false; - in_value = true; - trim = true; - l = 0; - - /* Terminate this string in d - * (which is a copy of parse_dn - * with spaces trimmed) */ - *d++ = '\0'; - dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); - if ( ! dn->components[dn->comp_num].name) { - /* ouch */ - goto failed; - } - - dt = d; - - p++; - continue; - } - - if (!isascii(*p)) { - /* attr names must be ascii only */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) { - /* not a digit nor a dot, - * invalid attribute oid */ - ldb_dn_mark_invalid(dn); - goto failed; - } else - if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { - /* not ALPHA, DIGIT or HYPHEN */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - *d++ = *p++; - continue; - } - - if (in_value) { - if (in_quote) { - if (*p == '\"') { - if (p[-1] != '\\') { - p++; - in_quote = false; - continue; - } - } - *d++ = *p++; - l++; - continue; - } - - if (trim) { - if (*p == ' ') { - p++; - continue; - } - - /* first char */ - trim = false; - - if (*p == '\"') { - in_quote = true; - p++; - continue; - } - } - - switch (*p) { - - /* TODO: support ber encoded values - case '#': - */ - - case ',': - if (escape) { - *d++ = *p++; - l++; - escape = false; - continue; - } - /* ok found value terminator */ - - if ( t ) { - /* trim back */ - d -= (p - t); - l -= (p - t); - } - - in_attr = true; - in_value = false; - trim = true; - - p++; - *d++ = '\0'; - dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt); - dn->components[dn->comp_num].value.length = l; - if ( ! dn->components[dn->comp_num].value.data) { - /* ouch ! */ - goto failed; - } - - dt = d; - - dn->comp_num++; - if (dn->comp_num > 2) { - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - dn->comp_num + 1); - if ( ! dn->components) { - /* ouch ! */ - goto failed; - } - /* make sure all components are zeroed, other functions depend on this */ - memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component)); - } - - continue; - - case '+': - case '=': - /* to main compatibility with earlier - versions of ldb indexing, we have to - accept the base64 encoded binary index - values, which contain a '+' or '=' - which should normally be escaped */ - if (is_index) { - if ( t ) t = NULL; - *d++ = *p++; - l++; - break; - } - /* fall through */ - case '\"': - case '<': - case '>': - case ';': - /* a string with not escaped specials is invalid (tested) */ - if ( ! escape) { - ldb_dn_mark_invalid(dn); - goto failed; - } - escape = false; - - *d++ = *p++; - l++; - - if ( t ) t = NULL; - break; - - case '\\': - if ( ! escape) { - escape = true; - p++; - continue; - } - escape = false; - - *d++ = *p++; - l++; - - if ( t ) t = NULL; - break; - - default: - if (escape) { - if (isxdigit(p[0]) && isxdigit(p[1])) { - if (sscanf(p, "%02x", &x) != 1) { - /* invalid escaping sequence */ - ldb_dn_mark_invalid(dn); - goto failed; - } - p += 2; - *d++ = (unsigned char)x; - } else { - *d++ = *p++; - } - - escape = false; - l++; - if ( t ) t = NULL; - break; - } - - if (*p == ' ') { - if ( ! t) t = p; - } else { - if ( t ) t = NULL; - } - - *d++ = *p++; - l++; - - break; - } - - } - } - - if (in_attr || in_quote) { - /* invalid dn */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - /* save last element */ - if ( t ) { - /* trim back */ - d -= (p - t); - l -= (p - t); - } - - *d++ = '\0'; - dn->components[dn->comp_num].value.length = l; - dn->components[dn->comp_num].value.data = - (uint8_t *)talloc_strdup(dn->components, dt); - if ( ! dn->components[dn->comp_num].value.data) { - /* ouch */ - goto failed; - } - - dn->comp_num++; - - talloc_free(data); - return true; - -failed: - LDB_FREE(dn->components); /* "data" is implicitly free'd */ - dn->comp_num = 0; - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return false; -} - -bool ldb_dn_validate(struct ldb_dn *dn) -{ - return ldb_dn_explode(dn); -} - -const char *ldb_dn_get_linearized(struct ldb_dn *dn) -{ - unsigned int i; - size_t len; - char *d, *n; - - if ( ! dn || ( dn->invalid)) return NULL; - - if (dn->linearized) return dn->linearized; - - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return NULL; - } - - if (dn->comp_num == 0) { - dn->linearized = talloc_strdup(dn, ""); - if ( ! dn->linearized) return NULL; - return dn->linearized; - } - - /* calculate maximum possible length of DN */ - for (len = 0, i = 0; i < dn->comp_num; i++) { - /* name len */ - len += strlen(dn->components[i].name); - /* max escaped data len */ - len += (dn->components[i].value.length * 3); - len += 2; /* '=' and ',' */ - } - dn->linearized = talloc_array(dn, char, len); - if ( ! dn->linearized) return NULL; - - d = dn->linearized; - - for (i = 0; i < dn->comp_num; i++) { - - /* copy the name */ - n = dn->components[i].name; - while (*n) *d++ = *n++; - - *d++ = '='; - - /* and the value */ - d += ldb_dn_escape_internal( d, - (char *)dn->components[i].value.data, - dn->components[i].value.length); - *d++ = ','; - } - - *(--d) = '\0'; - - /* don't waste more memory than necessary */ - dn->linearized = talloc_realloc(dn, dn->linearized, - char, (d - dn->linearized + 1)); - - return dn->linearized; -} - -static int ldb_dn_extended_component_compare(const void *p1, const void *p2) -{ - const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; - const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; - return strcmp(ec1->name, ec2->name); -} - -char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) -{ - const char *linearized = ldb_dn_get_linearized(dn); - char *p = NULL; - unsigned int i; - - if (!linearized) { - return NULL; - } - - if (!ldb_dn_has_extended(dn)) { - return talloc_strdup(mem_ctx, linearized); - } - - if (!ldb_dn_validate(dn)) { - return NULL; - } - - /* sort the extended components by name. The idea is to make - * the resulting DNs consistent, plus to ensure that we put - * 'DELETED' first, so it can be very quickly recognised - */ - TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, - ldb_dn_extended_component_compare); - - for (i = 0; i < dn->ext_comp_num; i++) { - const struct ldb_dn_extended_syntax *ext_syntax; - const char *name = dn->ext_components[i].name; - struct ldb_val ec_val = dn->ext_components[i].value; - struct ldb_val val; - int ret; - - ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); - if (!ext_syntax) { - return NULL; - } - - if (mode == 1) { - ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx, - &ec_val, &val); - } else if (mode == 0) { - ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx, - &ec_val, &val); - } else { - ret = -1; - } - - if (ret != LDB_SUCCESS) { - return NULL; - } - - if (i == 0) { - p = talloc_asprintf(mem_ctx, "<%s=%s>", - name, val.data); - } else { - p = talloc_asprintf_append_buffer(p, ";<%s=%s>", - name, val.data); - } - - talloc_free(val.data); - - if (!p) { - return NULL; - } - } - - if (dn->ext_comp_num && *linearized) { - p = talloc_asprintf_append_buffer(p, ";%s", linearized); - } - - if (!p) { - return NULL; - } - - return p; -} - -/* - filter out all but an acceptable list of extended DN components - */ -void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) -{ - unsigned int i; - for (i=0; iext_comp_num; i++) { - if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { - memmove(&dn->ext_components[i], - &dn->ext_components[i+1], - (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); - dn->ext_comp_num--; - i--; - } - } - LDB_FREE(dn->ext_linearized); -} - - -char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); -} - -/* - casefold a dn. We need to casefold the attribute names, and canonicalize - attribute values of case insensitive attributes. -*/ - -static bool ldb_dn_casefold_internal(struct ldb_dn *dn) -{ - unsigned int i; - int ret; - - if ( ! dn || dn->invalid) return false; - - if (dn->valid_case) return true; - - if (( ! dn->components) && ( ! ldb_dn_explode(dn))) { - return false; - } - - for (i = 0; i < dn->comp_num; i++) { - const struct ldb_schema_attribute *a; - - dn->components[i].cf_name = - ldb_attr_casefold(dn->components, - dn->components[i].name); - if (!dn->components[i].cf_name) { - goto failed; - } - - a = ldb_schema_attribute_by_name(dn->ldb, - dn->components[i].cf_name); - - ret = a->syntax->canonicalise_fn(dn->ldb, dn->components, - &(dn->components[i].value), - &(dn->components[i].cf_value)); - if (ret != 0) { - goto failed; - } - } - - dn->valid_case = true; - - return true; - -failed: - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - return false; -} - -const char *ldb_dn_get_casefold(struct ldb_dn *dn) -{ - unsigned int i; - size_t len; - char *d, *n; - - if (dn->casefold) return dn->casefold; - - if (dn->special) { - dn->casefold = talloc_strdup(dn, dn->linearized); - if (!dn->casefold) return NULL; - dn->valid_case = true; - return dn->casefold; - } - - if ( ! ldb_dn_casefold_internal(dn)) { - return NULL; - } - - if (dn->comp_num == 0) { - dn->casefold = talloc_strdup(dn, ""); - return dn->casefold; - } - - /* calculate maximum possible length of DN */ - for (len = 0, i = 0; i < dn->comp_num; i++) { - /* name len */ - len += strlen(dn->components[i].cf_name); - /* max escaped data len */ - len += (dn->components[i].cf_value.length * 3); - len += 2; /* '=' and ',' */ - } - dn->casefold = talloc_array(dn, char, len); - if ( ! dn->casefold) return NULL; - - d = dn->casefold; - - for (i = 0; i < dn->comp_num; i++) { - - /* copy the name */ - n = dn->components[i].cf_name; - while (*n) *d++ = *n++; - - *d++ = '='; - - /* and the value */ - d += ldb_dn_escape_internal( d, - (char *)dn->components[i].cf_value.data, - dn->components[i].cf_value.length); - *d++ = ','; - } - *(--d) = '\0'; - - /* don't waste more memory than necessary */ - dn->casefold = talloc_realloc(dn, dn->casefold, - char, strlen(dn->casefold) + 1); - - return dn->casefold; -} - -char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); -} - -/* Determine if dn is below base, in the ldap tree. Used for - * evaluating a subtree search. - * 0 if they match, otherwise non-zero - */ - -int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn) -{ - int ret; - unsigned int n_base, n_dn; - - if ( ! base || base->invalid) return 1; - if ( ! dn || dn->invalid) return -1; - - if (( ! base->valid_case) || ( ! dn->valid_case)) { - if (base->linearized && dn->linearized) { - /* try with a normal compare first, if we are lucky - * we will avoid exploding and casfolding */ - int dif; - dif = strlen(dn->linearized) - strlen(base->linearized); - if (dif < 0) { - return dif; - } - if (strcmp(base->linearized, - &dn->linearized[dif]) == 0) { - return 0; - } - } - - if ( ! ldb_dn_casefold_internal(base)) { - return 1; - } - - if ( ! ldb_dn_casefold_internal(dn)) { - return -1; - } - - } - - /* if base has more components, - * they don't have the same base */ - if (base->comp_num > dn->comp_num) { - return (dn->comp_num - base->comp_num); - } - - if ((dn->comp_num == 0) || (base->comp_num == 0)) { - if (dn->special && base->special) { - return strcmp(base->linearized, dn->linearized); - } else if (dn->special) { - return -1; - } else if (base->special) { - return 1; - } else { - return 0; - } - } - - n_base = base->comp_num - 1; - n_dn = dn->comp_num - 1; - - while (n_base != (unsigned int) -1) { - char *b_name = base->components[n_base].cf_name; - char *dn_name = dn->components[n_dn].cf_name; - - char *b_vdata = (char *)base->components[n_base].cf_value.data; - char *dn_vdata = (char *)dn->components[n_dn].cf_value.data; - - size_t b_vlen = base->components[n_base].cf_value.length; - size_t dn_vlen = dn->components[n_dn].cf_value.length; - - /* compare attr names */ - ret = strcmp(b_name, dn_name); - if (ret != 0) return ret; - - /* compare attr.cf_value. */ - if (b_vlen != dn_vlen) { - return b_vlen - dn_vlen; - } - ret = strcmp(b_vdata, dn_vdata); - if (ret != 0) return ret; - - n_base--; - n_dn--; - } - - return 0; -} - -/* compare DNs using casefolding compare functions. - - If they match, then return 0 - */ - -int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) -{ - unsigned int i; - int ret; - - if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { - return -1; - } - - if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { - if (dn0->linearized && dn1->linearized) { - /* try with a normal compare first, if we are lucky - * we will avoid exploding and casfolding */ - if (strcmp(dn0->linearized, dn1->linearized) == 0) { - return 0; - } - } - - if ( ! ldb_dn_casefold_internal(dn0)) { - return 1; - } - - if ( ! ldb_dn_casefold_internal(dn1)) { - return -1; - } - - } - - if (dn0->comp_num != dn1->comp_num) { - return (dn1->comp_num - dn0->comp_num); - } - - if (dn0->comp_num == 0) { - if (dn0->special && dn1->special) { - return strcmp(dn0->linearized, dn1->linearized); - } else if (dn0->special) { - return 1; - } else if (dn1->special) { - return -1; - } else { - return 0; - } - } - - for (i = 0; i < dn0->comp_num; i++) { - char *dn0_name = dn0->components[i].cf_name; - char *dn1_name = dn1->components[i].cf_name; - - char *dn0_vdata = (char *)dn0->components[i].cf_value.data; - char *dn1_vdata = (char *)dn1->components[i].cf_value.data; - - size_t dn0_vlen = dn0->components[i].cf_value.length; - size_t dn1_vlen = dn1->components[i].cf_value.length; - - /* compare attr names */ - ret = strcmp(dn0_name, dn1_name); - if (ret != 0) { - return ret; - } - - /* compare attr.cf_value. */ - if (dn0_vlen != dn1_vlen) { - return dn0_vlen - dn1_vlen; - } - ret = strcmp(dn0_vdata, dn1_vdata); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -static struct ldb_dn_component ldb_dn_copy_component( - TALLOC_CTX *mem_ctx, - struct ldb_dn_component *src) -{ - struct ldb_dn_component dst; - - memset(&dst, 0, sizeof(dst)); - - if (src == NULL) { - return dst; - } - - dst.value = ldb_val_dup(mem_ctx, &(src->value)); - if (dst.value.data == NULL) { - return dst; - } - - dst.name = talloc_strdup(mem_ctx, src->name); - if (dst.name == NULL) { - LDB_FREE(dst.value.data); - return dst; - } - - if (src->cf_value.data) { - dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); - if (dst.cf_value.data == NULL) { - LDB_FREE(dst.value.data); - LDB_FREE(dst.name); - return dst; - } - - dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); - if (dst.cf_name == NULL) { - LDB_FREE(dst.cf_name); - LDB_FREE(dst.value.data); - LDB_FREE(dst.name); - return dst; - } - } else { - dst.cf_value.data = NULL; - dst.cf_name = NULL; - } - - return dst; -} - -static struct ldb_dn_ext_component ldb_dn_ext_copy_component( - TALLOC_CTX *mem_ctx, - struct ldb_dn_ext_component *src) -{ - struct ldb_dn_ext_component dst; - - memset(&dst, 0, sizeof(dst)); - - if (src == NULL) { - return dst; - } - - dst.value = ldb_val_dup(mem_ctx, &(src->value)); - if (dst.value.data == NULL) { - return dst; - } - - dst.name = talloc_strdup(mem_ctx, src->name); - if (dst.name == NULL) { - LDB_FREE(dst.value.data); - return dst; - } - - return dst; -} - -struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - if (!dn || dn->invalid) { - return NULL; - } - - new_dn = talloc_zero(mem_ctx, struct ldb_dn); - if ( !new_dn) { - return NULL; - } - - *new_dn = *dn; - - if (dn->components) { - unsigned int i; - - new_dn->components = - talloc_zero_array(new_dn, - struct ldb_dn_component, - dn->comp_num); - if ( ! new_dn->components) { - talloc_free(new_dn); - return NULL; - } - - for (i = 0; i < dn->comp_num; i++) { - new_dn->components[i] = - ldb_dn_copy_component(new_dn->components, - &dn->components[i]); - if ( ! new_dn->components[i].value.data) { - talloc_free(new_dn); - return NULL; - } - } - } - - if (dn->ext_components) { - unsigned int i; - - new_dn->ext_components = - talloc_zero_array(new_dn, - struct ldb_dn_ext_component, - dn->ext_comp_num); - if ( ! new_dn->ext_components) { - talloc_free(new_dn); - return NULL; - } - - for (i = 0; i < dn->ext_comp_num; i++) { - new_dn->ext_components[i] = - ldb_dn_ext_copy_component( - new_dn->ext_components, - &dn->ext_components[i]); - if ( ! new_dn->ext_components[i].value.data) { - talloc_free(new_dn); - return NULL; - } - } - } - - if (dn->casefold) { - new_dn->casefold = talloc_strdup(new_dn, dn->casefold); - if ( ! new_dn->casefold) { - talloc_free(new_dn); - return NULL; - } - } - - if (dn->linearized) { - new_dn->linearized = talloc_strdup(new_dn, dn->linearized); - if ( ! new_dn->linearized) { - talloc_free(new_dn); - return NULL; - } - } - - if (dn->ext_linearized) { - new_dn->ext_linearized = talloc_strdup(new_dn, - dn->ext_linearized); - if ( ! new_dn->ext_linearized) { - talloc_free(new_dn); - return NULL; - } - } - - return new_dn; -} - -/* modify the given dn by adding a base. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) -{ - const char *s; - char *t; - - if ( !base || base->invalid || !dn || dn->invalid) { - return false; - } - - if (dn->components) { - unsigned int i; - - if ( ! ldb_dn_validate(base)) { - return false; - } - - s = NULL; - if (dn->valid_case) { - if ( ! (s = ldb_dn_get_casefold(base))) { - return false; - } - } - - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - dn->comp_num + base->comp_num); - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return false; - } - - for (i = 0; i < base->comp_num; dn->comp_num++, i++) { - dn->components[dn->comp_num] = - ldb_dn_copy_component(dn->components, - &base->components[i]); - if (dn->components[dn->comp_num].value.data == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - - if (dn->casefold && s) { - if (*dn->casefold) { - t = talloc_asprintf(dn, "%s,%s", - dn->casefold, s); - } else { - t = talloc_strdup(dn, s); - } - LDB_FREE(dn->casefold); - dn->casefold = t; - } - } - - if (dn->linearized) { - - s = ldb_dn_get_linearized(base); - if ( ! s) { - return false; - } - - if (*dn->linearized) { - t = talloc_asprintf(dn, "%s,%s", - dn->linearized, s); - } else { - t = talloc_strdup(dn, s); - } - if ( ! t) { - ldb_dn_mark_invalid(dn); - return false; - } - LDB_FREE(dn->linearized); - dn->linearized = t; - } - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -/* modify the given dn by adding a base. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) -{ - struct ldb_dn *base; - char *base_str; - va_list ap; - bool ret; - - if ( !dn || dn->invalid) { - return false; - } - - va_start(ap, base_fmt); - base_str = talloc_vasprintf(dn, base_fmt, ap); - va_end(ap); - - if (base_str == NULL) { - return false; - } - - base = ldb_dn_new(base_str, dn->ldb, base_str); - - ret = ldb_dn_add_base(dn, base); - - talloc_free(base_str); - - return ret; -} - -/* modify the given dn by adding children elements. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) -{ - const char *s; - char *t; - - if ( !child || child->invalid || !dn || dn->invalid) { - return false; - } - - if (dn->components) { - unsigned int n; - unsigned int i, j; - - if (dn->comp_num == 0) { - return false; - } - - if ( ! ldb_dn_validate(child)) { - return false; - } - - s = NULL; - if (dn->valid_case) { - if ( ! (s = ldb_dn_get_casefold(child))) { - return false; - } - } - - n = dn->comp_num + child->comp_num; - - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - n); - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return false; - } - - for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; - i--, j--) { - dn->components[j] = dn->components[i]; - } - - for (i = 0; i < child->comp_num; i++) { - dn->components[i] = - ldb_dn_copy_component(dn->components, - &child->components[i]); - if (dn->components[i].value.data == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - - dn->comp_num = n; - - if (dn->casefold && s) { - t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); - LDB_FREE(dn->casefold); - dn->casefold = t; - } - } - - if (dn->linearized) { - if (dn->linearized[0] == '\0') { - return false; - } - - s = ldb_dn_get_linearized(child); - if ( ! s) { - return false; - } - - t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); - if ( ! t) { - ldb_dn_mark_invalid(dn); - return false; - } - LDB_FREE(dn->linearized); - dn->linearized = t; - } - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -/* modify the given dn by adding children elements. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) -{ - struct ldb_dn *child; - char *child_str; - va_list ap; - bool ret; - - if ( !dn || dn->invalid) { - return false; - } - - va_start(ap, child_fmt); - child_str = talloc_vasprintf(dn, child_fmt, ap); - va_end(ap); - - if (child_str == NULL) { - return false; - } - - child = ldb_dn_new(child_str, dn->ldb, child_str); - - ret = ldb_dn_add_child(dn, child); - - talloc_free(child_str); - - return ret; -} - -bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) -{ - unsigned int i; - - if ( ! ldb_dn_validate(dn)) { - return false; - } - - if (dn->comp_num < num) { - return false; - } - - /* free components */ - for (i = dn->comp_num - num; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - - dn->comp_num -= num; - - if (dn->valid_case) { - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) -{ - unsigned int i, j; - - if ( ! ldb_dn_validate(dn)) { - return false; - } - - if (dn->comp_num < num) { - return false; - } - - for (i = 0, j = num; j < dn->comp_num; i++, j++) { - if (i < num) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->components[i] = dn->components[j]; - } - - dn->comp_num -= num; - - if (dn->valid_case) { - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( !new_dn ) { - return NULL; - } - - if ( ! ldb_dn_remove_child_components(new_dn, 1)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Create a 'canonical name' string from a DN: - - ie dc=samba,dc=org -> samba.org/ - uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator - - There are two formats, - the EX format has the last '/' replaced with a newline (\n). - -*/ -static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { - unsigned int i; - TALLOC_CTX *tmpctx; - char *cracked = NULL; - const char *format = (ex_format ? "\n" : "/" ); - - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - - tmpctx = talloc_new(mem_ctx); - - /* Walk backwards down the DN, grabbing 'dc' components at first */ - for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { - if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { - break; - } - if (cracked) { - cracked = talloc_asprintf(tmpctx, "%s.%s", - ldb_dn_escape_value(tmpctx, - dn->components[i].value), - cracked); - } else { - cracked = ldb_dn_escape_value(tmpctx, - dn->components[i].value); - } - if (!cracked) { - goto done; - } - } - - /* Only domain components? Finish here */ - if (i == (unsigned int) -1) { - cracked = talloc_strdup_append_buffer(cracked, format); - talloc_steal(mem_ctx, cracked); - goto done; - } - - /* Now walk backwards appending remaining components */ - for (; i > 0; i--) { - cracked = talloc_asprintf_append_buffer(cracked, "/%s", - ldb_dn_escape_value(tmpctx, - dn->components[i].value)); - if (!cracked) { - goto done; - } - } - - /* Last one, possibly a newline for the 'ex' format */ - cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, - ldb_dn_escape_value(tmpctx, - dn->components[i].value)); - - talloc_steal(mem_ctx, cracked); -done: - talloc_free(tmpctx); - return cracked; -} - -/* Wrapper functions for the above, for the two different string formats */ -char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 0); - -} - -char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 1); -} - -int ldb_dn_get_comp_num(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return -1; - } - return dn->comp_num; -} - -int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return -1; - } - return dn->ext_comp_num; -} - -const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (num >= dn->comp_num) return NULL; - return dn->components[num].name; -} - -const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, - unsigned int num) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (num >= dn->comp_num) return NULL; - return &dn->components[num].value; -} - -const char *ldb_dn_get_rdn_name(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (dn->comp_num == 0) return NULL; - return dn->components[0].name; -} - -const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (dn->comp_num == 0) return NULL; - return &dn->components[0].value; -} - -int ldb_dn_set_component(struct ldb_dn *dn, int num, - const char *name, const struct ldb_val val) -{ - char *n; - struct ldb_val v; - - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_OTHER; - } - - if (num >= dn->comp_num) { - return LDB_ERR_OTHER; - } - - n = talloc_strdup(dn, name); - if ( ! n) { - return LDB_ERR_OTHER; - } - - v.length = val.length; - v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1); - if ( ! v.data) { - talloc_free(n); - return LDB_ERR_OTHER; - } - - talloc_free(dn->components[num].name); - talloc_free(dn->components[num].value.data); - dn->components[num].name = n; - dn->components[num].value = v; - - if (dn->valid_case) { - unsigned int i; - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return LDB_SUCCESS; -} - -const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, - const char *name) -{ - unsigned int i; - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - for (i=0; i < dn->ext_comp_num; i++) { - if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { - return &dn->ext_components[i].value; - } - } - return NULL; -} - -int ldb_dn_set_extended_component(struct ldb_dn *dn, - const char *name, const struct ldb_val *val) -{ - struct ldb_dn_ext_component *p; - unsigned int i; - struct ldb_val v2; - - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_OTHER; - } - - if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) { - /* We don't know how to handle this type of thing */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - - for (i=0; i < dn->ext_comp_num; i++) { - if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { - if (val) { - dn->ext_components[i].value = - ldb_val_dup(dn->ext_components, val); - - dn->ext_components[i].name = - talloc_strdup(dn->ext_components, name); - if (!dn->ext_components[i].name || - !dn->ext_components[i].value.data) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - if (i != (dn->ext_comp_num - 1)) { - memmove(&dn->ext_components[i], - &dn->ext_components[i+1], - ((dn->ext_comp_num-1) - i) * - sizeof(*dn->ext_components)); - } - dn->ext_comp_num--; - - dn->ext_components = talloc_realloc(dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num); - if (!dn->ext_components) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - } - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; - } - } - - if (val == NULL) { - /* removing a value that doesn't exist is not an error */ - return LDB_SUCCESS; - } - - v2 = *val; - - p = dn->ext_components - = talloc_realloc(dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num + 1); - if (!dn->ext_components) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - - p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); - p[dn->ext_comp_num].name = talloc_strdup(p, name); - - if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - dn->ext_components = p; - dn->ext_comp_num++; - - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; -} - -void ldb_dn_remove_extended_components(struct ldb_dn *dn) -{ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; -} - -bool ldb_dn_is_valid(struct ldb_dn *dn) -{ - if ( ! dn) return false; - return ! dn->invalid; -} - -bool ldb_dn_is_special(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - return dn->special; -} - -bool ldb_dn_has_extended(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true; - return dn->ext_comp_num != 0; -} - -bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) -{ - if ( ! dn || dn->invalid) return false; - return ! strcmp(dn->linearized, check); -} - -bool ldb_dn_is_null(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - if (ldb_dn_has_extended(dn)) return false; - if (dn->linearized && (dn->linearized[0] == '\0')) return true; - return false; -} - -/* - this updates dn->components, taking the components from ref_dn. - This is used by code that wants to update the DN path of a DN - while not impacting on the extended DN components - */ -int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) -{ - dn->components = talloc_realloc(dn, dn->components, - struct ldb_dn_component, ref_dn->comp_num); - if (!dn->components) { - return LDB_ERR_OPERATIONS_ERROR; - } - memcpy(dn->components, ref_dn->components, - sizeof(struct ldb_dn_component)*ref_dn->comp_num); - dn->comp_num = ref_dn->comp_num; - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; -} - -/* - minimise a DN. The caller must pass in a validated DN. - - If the DN has an extended component then only the first extended - component is kept, the DN string is stripped. - - The existing dn is modified - */ -bool ldb_dn_minimise(struct ldb_dn *dn) -{ - unsigned int i; - - if (!ldb_dn_validate(dn)) { - return false; - } - if (dn->ext_comp_num == 0) { - return true; - } - - /* free components */ - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->comp_num = 0; - dn->valid_case = false; - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* note that we don't free dn->components as this there are - * several places in ldb_dn.c that rely on it being non-NULL - * for an exploded DN - */ - - for (i = 1; i < dn->ext_comp_num; i++) { - LDB_FREE(dn->ext_components[i].name); - LDB_FREE(dn->ext_components[i].value.data); - } - dn->ext_comp_num = 1; - - dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); - if (dn->ext_components == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - - LDB_FREE(dn->ext_linearized); - - return true; -} diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c deleted file mode 100644 index 63b797c4f3d..00000000000 --- a/source4/lib/ldb/common/ldb_ldif.c +++ /dev/null @@ -1,1026 +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: ldif routines - * - * Description: ldif pack/unpack routines - * - * Author: Andrew Tridgell - */ - -/* - see RFC2849 for the LDIF format definition -*/ - -#include "ldb_private.h" -#include "system/locale.h" - -/* - -*/ -static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) -{ - struct stat statbuf; - char *buf; - int count, size, bytes; - int ret; - int f; - const char *fname = (const char *)value->data; - - if (strncmp(fname, "file://", 7) != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - fname += 7; - - f = open(fname, O_RDONLY); - if (f == -1) { - return -1; - } - - if (fstat(f, &statbuf) != 0) { - ret = -1; - goto done; - } - - if (statbuf.st_size == 0) { - ret = -1; - goto done; - } - - value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); - if (value->data == NULL) { - ret = -1; - goto done; - } - value->data[statbuf.st_size] = 0; - - count = 0; - size = statbuf.st_size; - buf = (char *)value->data; - while (count < statbuf.st_size) { - bytes = read(f, buf, size); - if (bytes == -1) { - talloc_free(value->data); - ret = -1; - goto done; - } - count += bytes; - buf += bytes; - size -= bytes; - } - - value->length = statbuf.st_size; - ret = statbuf.st_size; - -done: - close(f); - return ret; -} - -/* - this base64 decoder was taken from jitterbug (written by tridge). - we might need to replace it with a new version -*/ -int ldb_base64_decode(char *s) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset=0, byte_offset, idx, i, n; - uint8_t *d = (uint8_t *)s; - char *p=NULL; - - n=i=0; - - while (*s && (p=strchr(b64,*s))) { - idx = (int)(p - b64); - byte_offset = (i*6)/8; - bit_offset = (i*6)%8; - d[byte_offset] &= ~((1<<(8-bit_offset))-1); - if (bit_offset < 3) { - d[byte_offset] |= (idx << (2-bit_offset)); - n = byte_offset+1; - } else { - d[byte_offset] |= (idx >> (bit_offset-2)); - d[byte_offset+1] = 0; - d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; - n = byte_offset+2; - } - s++; i++; - } - if (bit_offset >= 3) { - n--; - } - - if (*s && !p) { - /* the only termination allowed */ - if (*s != '=') { - return -1; - } - } - - /* null terminate */ - d[n] = 0; - return n; -} - - -/* - encode as base64 - caller frees -*/ -char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset, byte_offset, idx, i; - const uint8_t *d = (const uint8_t *)buf; - int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; - char *out; - - out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); - if (!out) return NULL; - - for (i=0;i> (2-bit_offset)) & 0x3F; - } else { - idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; - if (byte_offset+1 < len) { - idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); - } - } - out[i] = b64[idx]; - } - - for (;idata; - - if (val->length == 0) { - return 0; - } - - if (p[0] == ' ' || p[0] == ':') { - return 1; - } - - for (i=0; ilength; i++) { - if (!isprint(p[i]) || p[i] == '\n') { - return 1; - } - } - return 0; -} - -/* this macro is used to handle the return checking on fprintf_fn() */ -#define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) - -/* - write a line folded string onto a file -*/ -static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, - const char *buf, size_t length, int start_pos) -{ - size_t i; - int total=0, ret; - - for (i=0;imsg; - p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); - ret = fprintf_fn(private_data, "dn: %s\n", p); - talloc_free(p); - CHECK_RET; - - if (ldif->changetype != LDB_CHANGETYPE_NONE) { - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_changetypes[i].changetype == ldif->changetype) { - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", - ldif->changetype); - talloc_free(mem_ctx); - return -1; - } - ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); - CHECK_RET; - } - - for (i=0;inum_elements;i++) { - const struct ldb_schema_attribute *a; - - a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); - - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - fprintf_fn(private_data, "add: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_DELETE: - fprintf_fn(private_data, "delete: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_REPLACE: - fprintf_fn(private_data, "replace: %s\n", - msg->elements[i].name); - break; - } - } - - for (j=0;jelements[i].num_values;j++) { - struct ldb_val v; - bool use_b64_encode; - ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); - if (ret != LDB_SUCCESS) { - v = msg->elements[i].values[j]; - } - use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY) - && ldb_should_b64_encode(ldb, &v); - if (ret != LDB_SUCCESS || use_b64_encode) { - ret = fprintf_fn(private_data, "%s:: ", - msg->elements[i].name); - CHECK_RET; - ret = base64_encode_f(ldb, fprintf_fn, private_data, - (char *)v.data, v.length, - strlen(msg->elements[i].name)+3); - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } else { - ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); - CHECK_RET; - if (ldb->flags & LDB_FLG_SHOW_BINARY) { - ret = fprintf_fn(private_data, "%*.*s", - v.length, v.length, (char *)v.data); - } else { - ret = fold_string(fprintf_fn, private_data, - (char *)v.data, v.length, - strlen(msg->elements[i].name)+2); - } - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } - if (v.data != msg->elements[i].values[j].data) { - talloc_free(v.data); - } - } - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - fprintf_fn(private_data, "-\n"); - } - } - ret = fprintf_fn(private_data,"\n"); - CHECK_RET; - - talloc_free(mem_ctx); - - return total; -} - -#undef CHECK_RET - - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(ldb, chunk, char, alloc_size); - if (!c2) { - talloc_free(chunk); - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - - -/* simple ldif attribute parser */ -static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) -{ - char *p; - int base64_encoded = 0; - int binary_file = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - if (*p == '<') { - binary_file = 1; - p++; - } - - *attr = *s; - - while (*p == ' ' || *p == '\t') { - p++; - } - - value->data = (uint8_t *)p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - int len = ldb_base64_decode((char *)value->data); - if (len == -1) { - /* it wasn't valid base64 data */ - return -1; - } - value->length = len; - } - - if (binary_file) { - int len = ldb_read_data_file(mem_ctx, value); - if (len == -1) { - /* an error occurred while trying to retrieve the file */ - return -1; - } - } - - return 0; -} - - -/* - free a message from a ldif_read -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) -{ - talloc_free(ldif); -} - -int ldb_ldif_parse_modrdn(struct ldb_context *ldb, - const struct ldb_ldif *ldif, - TALLOC_CTX *mem_ctx, - struct ldb_dn **_olddn, - struct ldb_dn **_newrdn, - bool *_deleteoldrdn, - struct ldb_dn **_newsuperior, - struct ldb_dn **_newdn) -{ - struct ldb_message *msg = ldif->msg; - struct ldb_val *newrdn_val = NULL; - struct ldb_val *deleteoldrdn_val = NULL; - struct ldb_val *newsuperior_val = NULL; - struct ldb_dn *olddn = NULL; - struct ldb_dn *newrdn = NULL; - bool deleteoldrdn = true; - struct ldb_dn *newsuperior = NULL; - struct ldb_dn *newdn = NULL; - struct ldb_val tmp_false; - struct ldb_val tmp_true; - bool ok; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - - if (tmp_ctx == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Error: talloc_new() failed"); - goto err_op; - } - - if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: invalid changetype '%d'", - ldif->changetype); - goto err_other; - } - - if (msg->num_elements < 2) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: num_elements[%u] < 2", - msg->num_elements); - goto err_other; - } - - if (msg->num_elements > 3) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: num_elements[%u] > 3", - msg->num_elements); - goto err_other; - } - -#define CHECK_ELEMENT(i, _name, v, needed) do { \ - v = NULL; \ - if (msg->num_elements < (i + 1)) { \ - if (needed) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: num_elements[%u] < (%u + 1)", \ - msg->num_elements, i); \ - goto err_other; \ - } \ - } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].name[%s] != [%s]", \ - i, msg->elements[i].name, _name); \ - goto err_other; \ - } else if (msg->elements[i].flags != 0) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].flags[0x%X} != [0x0]", \ - i, msg->elements[i].flags); \ - goto err_other; \ - } else if (msg->elements[i].num_values != 1) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].num_values[%u] != 1", \ - i, msg->elements[i].num_values); \ - goto err_other; \ - } else { \ - v = &msg->elements[i].values[0]; \ - } \ -} while (0) - - CHECK_ELEMENT(0, "newrdn", newrdn_val, true); - CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); - CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); - -#undef CHECK_ELEMENT - - olddn = ldb_dn_copy(tmp_ctx, msg->dn); - if (olddn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to copy olddn '%s'", - ldb_dn_get_linearized(msg->dn)); - goto err_op; - } - - newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); - if (!ldb_dn_validate(newrdn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to parse dn '%s'", - (char *)newrdn_val->data); - goto err_dn; - } - - tmp_false.length = 1; - tmp_false.data = discard_const_p(uint8_t, "0"); - tmp_true.length = 1; - tmp_true.data = discard_const_p(uint8_t, "1"); - if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { - deleteoldrdn = false; - } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { - deleteoldrdn = true; - } else { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: deleteoldrdn value invalid '%s' not '0'/'1'", - (char *)deleteoldrdn_val->data); - goto err_attr; - } - - if (newsuperior_val) { - newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); - if (!ldb_dn_validate(newsuperior)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to parse dn '%s'", - (char *)newsuperior_val->data); - goto err_dn; - } - } else { - newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); - if (newsuperior == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to get parent dn '%s'", - ldb_dn_get_linearized(msg->dn)); - goto err_dn; - } - } - - newdn = ldb_dn_copy(tmp_ctx, newrdn); - if (newdn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to copy newrdn '%s'", - ldb_dn_get_linearized(newrdn)); - goto err_op; - } - - ok = ldb_dn_add_base(newdn, newsuperior); - if (!ok) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to base '%s' to newdn '%s'", - ldb_dn_get_linearized(newsuperior), - ldb_dn_get_linearized(newdn)); - goto err_op; - } - - if (_olddn) { - *_olddn = talloc_move(mem_ctx, &olddn); - } - if (_newrdn) { - *_newrdn = talloc_move(mem_ctx, &newrdn); - } - if (_deleteoldrdn) { - *_deleteoldrdn = deleteoldrdn; - } - if (_newsuperior) { - if (newsuperior_val) { - *_newrdn = talloc_move(mem_ctx, &newrdn); - } else { - *_newrdn = NULL; - } - } - if (_newdn) { - *_newdn = talloc_move(mem_ctx, &newdn); - } - - talloc_free(tmp_ctx); - return LDB_SUCCESS; -err_other: - talloc_free(tmp_ctx); - return LDB_ERR_OTHER; -err_op: - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; -err_attr: - talloc_free(tmp_ctx); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -err_dn: - talloc_free(tmp_ctx); - return LDB_ERR_INVALID_DN_SYNTAX; -} - -/* - read from a LDIF source, creating a ldb_message -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data) -{ - struct ldb_ldif *ldif; - struct ldb_message *msg; - const char *attr=NULL; - char *chunk=NULL, *s; - struct ldb_val value; - unsigned flags = 0; - - value.data = NULL; - - ldif = talloc(ldb, struct ldb_ldif); - if (!ldif) return NULL; - - ldif->msg = talloc(ldif, struct ldb_message); - if (ldif->msg == NULL) { - talloc_free(ldif); - return NULL; - } - - ldif->changetype = LDB_CHANGETYPE_NONE; - msg = ldif->msg; - - msg->dn = NULL; - msg->elements = NULL; - msg->num_elements = 0; - - chunk = next_chunk(ldb, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - talloc_steal(ldif, chunk); - - s = chunk; - - if (next_attr(ldif, &s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (ldb_attr_cmp(attr, "dn") != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", - attr); - goto failed; - } - - msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); - - if ( ! ldb_dn_validate(msg->dn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", - (char *)value.data); - goto failed; - } - - while (next_attr(ldif, &s, &attr, &value) == 0) { - const struct ldb_schema_attribute *a; - struct ldb_message_element *el; - int ret, empty = 0; - - if (ldb_attr_cmp(attr, "changetype") == 0) { - int i; - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { - ldif->changetype = ldb_changetypes[i].changetype; - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Bad ldif changetype '%s'",(char *)value.data); - } - flags = 0; - continue; - } - - if (ldb_attr_cmp(attr, "add") == 0) { - flags = LDB_FLAG_MOD_ADD; - empty = 1; - } - if (ldb_attr_cmp(attr, "delete") == 0) { - flags = LDB_FLAG_MOD_DELETE; - empty = 1; - } - if (ldb_attr_cmp(attr, "replace") == 0) { - flags = LDB_FLAG_MOD_REPLACE; - empty = 1; - } - if (ldb_attr_cmp(attr, "-") == 0) { - flags = 0; - continue; - } - - if (empty) { - if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { - goto failed; - } - continue; - } - - el = &msg->elements[msg->num_elements-1]; - - a = ldb_schema_attribute_by_name(ldb, attr); - - if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && - flags == el->flags) { - /* its a continuation */ - el->values = - talloc_realloc(msg->elements, el->values, - struct ldb_val, el->num_values+1); - if (!el->values) { - goto failed; - } - ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]); - if (ret != 0) { - goto failed; - } - if (value.length == 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Attribute value cannot be empty for attribute '%s'", el->name); - goto failed; - } - if (value.data != el->values[el->num_values].data) { - talloc_steal(el->values, el->values[el->num_values].data); - } - el->num_values++; - } else { - /* its a new attribute */ - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, - msg->num_elements+1); - if (!msg->elements) { - goto failed; - } - el = &msg->elements[msg->num_elements]; - el->flags = flags; - el->name = talloc_strdup(msg->elements, attr); - el->values = talloc(msg->elements, struct ldb_val); - if (!el->values || !el->name) { - goto failed; - } - el->num_values = 1; - ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]); - if (ret != 0) { - goto failed; - } - if (value.data != el->values[0].data) { - talloc_steal(el->values, el->values[0].data); - } - msg->num_elements++; - } - } - - if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { - int ret; - - ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, - NULL, NULL, NULL, NULL, NULL); - if (ret != LDB_SUCCESS) { - goto failed; - } - } - - return ldif; - -failed: - talloc_free(ldif); - return NULL; -} - - - -/* - a wrapper around ldif_read() for reading from FILE* -*/ -struct ldif_read_file_state { - FILE *f; -}; - -static int fgetc_file(void *private_data) -{ - struct ldif_read_file_state *state = - (struct ldif_read_file_state *)private_data; - return fgetc(state->f); -} - -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) -{ - struct ldif_read_file_state state; - state.f = f; - return ldb_ldif_read(ldb, fgetc_file, &state); -} - - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = - (struct ldif_read_string_state *)private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) -{ - struct ldif_read_string_state state; - struct ldb_ldif *ldif; - state.s = *s; - ldif = ldb_ldif_read(ldb, fgetc_string, &state); - *s = state.s; - return ldif; -} - - -/* - wrapper around ldif_write() for a file -*/ -struct ldif_write_file_state { - FILE *f; -}; - -static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -static int fprintf_file(void *private_data, const char *fmt, ...) -{ - struct ldif_write_file_state *state = - (struct ldif_write_file_state *)private_data; - int ret; - va_list ap; - - va_start(ap, fmt); - ret = vfprintf(state->f, fmt, ap); - va_end(ap); - return ret; -} - -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) -{ - struct ldif_write_file_state state; - state.f = f; - return ldb_ldif_write(ldb, fprintf_file, &state, ldif); -} - -/* - wrapper around ldif_write() for a string -*/ -struct ldif_write_string_state { - char *string; -}; - -static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -static int ldif_printf_string(void *private_data, const char *fmt, ...) -{ - struct ldif_write_string_state *state = - (struct ldif_write_string_state *)private_data; - va_list ap; - size_t oldlen = talloc_get_size(state->string); - va_start(ap, fmt); - - state->string = talloc_vasprintf_append(state->string, fmt, ap); - va_end(ap); - if (!state->string) { - return -1; - } - - return talloc_get_size(state->string) - oldlen; -} - -char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *ldif) -{ - struct ldif_write_string_state state; - state.string = talloc_strdup(mem_ctx, ""); - if (!state.string) { - return NULL; - } - if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { - return NULL; - } - return state.string; -} - -/* - convenient function to turn a ldb_message into a string. Useful for - debugging - */ -char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg) -{ - struct ldb_ldif ldif; - - ldif.changetype = changetype; - ldif.msg = discard_const_p(struct ldb_message, msg); - - return ldb_ldif_write_string(ldb, mem_ctx, &ldif); -} diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c deleted file mode 100644 index a42cf9449d3..00000000000 --- a/source4/lib/ldb/common/ldb_match.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Simo Sorce 2005 - - ** 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 expression matching - * - * Description: ldb expression matching - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - check if the scope matches in a search result -*/ -static int ldb_match_scope(struct ldb_context *ldb, - struct ldb_dn *base, - struct ldb_dn *dn, - enum ldb_scope scope) -{ - int ret = 0; - - if (base == NULL || dn == NULL) { - return 1; - } - - switch (scope) { - case LDB_SCOPE_BASE: - if (ldb_dn_compare(base, dn) == 0) { - ret = 1; - } - break; - - case LDB_SCOPE_ONELEVEL: - if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { - if (ldb_dn_compare_base(base, dn) == 0) { - ret = 1; - } - } - break; - - case LDB_SCOPE_SUBTREE: - default: - if (ldb_dn_compare_base(base, dn) == 0) { - ret = 1; - } - break; - } - - return ret; -} - - -/* - match if node is present -*/ -static int ldb_match_present(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - const struct ldb_schema_attribute *a; - struct ldb_message_element *el; - - if (ldb_attr_dn(tree->u.present.attr) == 0) { - *matched = true; - return LDB_SUCCESS; - } - - el = ldb_msg_find_element(msg, tree->u.present.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (a->syntax->operator_fn) { - unsigned int i; - for (i = 0; i < el->num_values; i++) { - int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - *matched = false; - return LDB_SUCCESS; - } - - *matched = true; - return LDB_SUCCESS; -} - -static int ldb_match_comparison(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, - enum ldb_parse_op comp_op, bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - - /* FIXME: APPROX comparison not handled yet */ - if (comp_op == LDB_OP_APPROX) { - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - el = ldb_msg_find_element(msg, tree->u.comparison.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - for (i = 0; i < el->num_values; i++) { - if (a->syntax->operator_fn) { - int ret; - ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } else { - int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); - - if (ret == 0) { - *matched = true; - return LDB_SUCCESS; - } - if (ret > 0 && comp_op == LDB_OP_GREATER) { - *matched = true; - return LDB_SUCCESS; - } - if (ret < 0 && comp_op == LDB_OP_LESS) { - *matched = true; - return LDB_SUCCESS; - } - } - } - - *matched = false; - return LDB_SUCCESS; -} - -/* - match a simple leaf node -*/ -static int ldb_match_equality(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, - bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - struct ldb_dn *valuedn; - int ret; - - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); - if (valuedn == NULL) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - ret = ldb_dn_compare(msg->dn, valuedn); - - talloc_free(valuedn); - - *matched = (ret == 0); - return LDB_SUCCESS; - } - - /* TODO: handle the "*" case derived from an extended search - operation without the attibute type defined */ - el = ldb_msg_find_element(msg, tree->u.equality.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (a == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - for (i=0;inum_values;i++) { - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &tree->u.equality.value, &el->values[i], matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } else { - if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, - &el->values[i]) == 0) { - *matched = true; - return LDB_SUCCESS; - } - } - } - - *matched = false; - return LDB_SUCCESS; -} - -static int ldb_wildcard_compare(struct ldb_context *ldb, - const struct ldb_parse_tree *tree, - const struct ldb_val value, bool *matched) -{ - const struct ldb_schema_attribute *a; - struct ldb_val val; - struct ldb_val cnk; - struct ldb_val *chunk; - char *p, *g; - uint8_t *save_p = NULL; - unsigned int c = 0; - - a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - save_p = val.data; - cnk.data = NULL; - - if ( ! tree->u.substring.start_with_wildcard ) { - - chunk = tree->u.substring.chunks[c]; - if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; - - /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ - if (cnk.length > val.length) { - goto mismatch; - } - if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; - val.length -= cnk.length; - val.data += cnk.length; - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - while (tree->u.substring.chunks[c]) { - - chunk = tree->u.substring.chunks[c]; - if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; - - /* FIXME: case of embedded nulls */ - p = strstr((char *)val.data, (char *)cnk.data); - if (p == NULL) goto mismatch; - if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { - do { /* greedy */ - g = strstr((char *)p + cnk.length, (char *)cnk.data); - if (g) p = g; - } while(g); - } - val.length = val.length - (p - (char *)(val.data)) - cnk.length; - val.data = (uint8_t *)(p + cnk.length); - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - /* last chunk may not have reached end of string */ - if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch; - talloc_free(save_p); - *matched = true; - return LDB_SUCCESS; - -mismatch: - *matched = false; - talloc_free(save_p); - talloc_free(cnk.data); - return LDB_SUCCESS; -} - -/* - match a simple leaf node -*/ -static int ldb_match_substring(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - - el = ldb_msg_find_element(msg, tree->u.substring.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - for (i = 0; i < el->num_values; i++) { - int ret; - ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - - *matched = false; - return LDB_SUCCESS; -} - - -/* - bitwise-and comparator -*/ -static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, - bool *matched) -{ - uint64_t i1, i2; - char ibuf[100]; - char *endptr = NULL; - - if (v1->length >= sizeof(ibuf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - memcpy(ibuf, (char *)v1->data, v1->length); - ibuf[v1->length] = 0; - i1 = strtoull(ibuf, &endptr, 0); - if (endptr != NULL) { - if (endptr == ibuf || *endptr != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - - if (v2->length >= sizeof(ibuf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - endptr = NULL; - memcpy(ibuf, (char *)v2->data, v2->length); - ibuf[v2->length] = 0; - i2 = strtoull(ibuf, &endptr, 0); - if (endptr != NULL) { - if (endptr == ibuf || *endptr != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { - *matched = ((i1 & i2) == i2); - } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { - *matched = ((i1 & i2) != 0); - } else { - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - return LDB_SUCCESS; -} - - -/* - extended match, handles things like bitops -*/ -static int ldb_match_extended(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - unsigned int i; - const struct { - const char *oid; - int (*comparator)(const char *, const struct ldb_val *, const struct ldb_val *, bool *); - } rules[] = { - { LDB_OID_COMPARATOR_AND, ldb_comparator_bitmask}, - { LDB_OID_COMPARATOR_OR, ldb_comparator_bitmask} - }; - int (*comp)(const char *,const struct ldb_val *, const struct ldb_val *, bool *) = NULL; - struct ldb_message_element *el; - - if (tree->u.extended.dnAttributes) { - /* FIXME: We really need to find out what this ":dn" part in - * an extended match means and how to handle it. For now print - * only a warning to have s3 winbind and other tools working - * against us. - Matthias */ - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); - } - if (tree->u.extended.rule_id == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - if (tree->u.extended.attr == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - for (i=0;iu.extended.rule_id) == 0) { - comp = rules[i].comparator; - break; - } - } - if (comp == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", - tree->u.extended.rule_id); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - /* find the message element */ - el = ldb_msg_find_element(msg, tree->u.extended.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - for (i=0;inum_values;i++) { - int ret = comp(tree->u.extended.rule_id, &el->values[i], &tree->u.extended.value, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - - *matched = false; - return LDB_SUCCESS; -} - -/* - return 0 if the given parse tree matches the given message. Assumes - the message is in sorted order - - return 1 if it matches, and 0 if it doesn't match - - this is a recursive function, and does short-circuit evaluation - */ -static int ldb_match_message(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - unsigned int i; - int ret; - - *matched = false; - - switch (tree->operation) { - case LDB_OP_AND: - for (i=0;iu.list.num_elements;i++) { - ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); - if (ret != LDB_SUCCESS) return ret; - if (!*matched) return LDB_SUCCESS; - } - *matched = true; - return LDB_SUCCESS; - - case LDB_OP_OR: - for (i=0;iu.list.num_elements;i++) { - ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - *matched = false; - return LDB_SUCCESS; - - case LDB_OP_NOT: - ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); - if (ret != LDB_SUCCESS) return ret; - *matched = ! *matched; - return LDB_SUCCESS; - - case LDB_OP_EQUALITY: - return ldb_match_equality(ldb, msg, tree, scope, matched); - - case LDB_OP_SUBSTRING: - return ldb_match_substring(ldb, msg, tree, scope, matched); - - case LDB_OP_GREATER: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); - - case LDB_OP_LESS: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); - - case LDB_OP_PRESENT: - return ldb_match_present(ldb, msg, tree, scope, matched); - - case LDB_OP_APPROX: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); - - case LDB_OP_EXTENDED: - return ldb_match_extended(ldb, msg, tree, scope, matched); - } - - return LDB_ERR_INAPPROPRIATE_MATCHING; -} - -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope) -{ - bool matched; - int ret; - - if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { - return 0; - } - - ret = ldb_match_message(ldb, msg, tree, scope, &matched); - if (ret != LDB_SUCCESS) { - /* to match the old API, we need to consider this a - failure to match */ - return 0; - } - return matched?1:0; -} - -int ldb_match_msg_error(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope, - bool *matched) -{ - if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { - *matched = false; - return LDB_SUCCESS; - } - - return ldb_match_message(ldb, msg, tree, scope, matched); -} - -int ldb_match_msg_objectclass(const struct ldb_message *msg, - const char *objectclass) -{ - unsigned int i; - struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); - if (!el) { - return 0; - } - for (i=0; i < el->num_values; i++) { - if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { - return 1; - } - } - return 0; -} - - - diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c deleted file mode 100644 index 61d1901513a..00000000000 --- a/source4/lib/ldb/common/ldb_modules.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004-2008 - - ** 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 modules core - * - * Description: core modules routines - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" -#include "dlinklist.h" -#include "system/dir.h" - -static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) -{ - size_t i, len; - char *trimmed; - - trimmed = talloc_strdup(mem_ctx, string); - if (!trimmed) { - return NULL; - } - - len = strlen(trimmed); - for (i = 0; trimmed[i] != '\0'; i++) { - switch (trimmed[i]) { - case ' ': - case '\t': - case '\n': - memmove(&trimmed[i], &trimmed[i + 1], len -i -1); - break; - } - } - - return trimmed; -} - - -/* modules are called in inverse order on the stack. - Lets place them as an admin would think the right order is. - Modules order is important */ -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) -{ - char **modules = NULL; - const char **m; - char *modstr, *p; - unsigned int i; - - /* spaces not admitted */ - modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); - if ( ! modstr) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); - return NULL; - } - - modules = talloc_realloc(mem_ctx, modules, char *, 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); - talloc_free(modstr); - return NULL; - } - talloc_steal(modules, modstr); - - if (modstr[0] == '\0') { - modules[0] = NULL; - m = (const char **)modules; - return m; - } - - i = 0; - /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ - while ((p = strrchr(modstr, ',')) != NULL) { - *p = '\0'; - p++; - modules[i] = p; - - i++; - modules = talloc_realloc(mem_ctx, modules, char *, i + 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); - return NULL; - } - - } - modules[i] = modstr; - - modules[i + 1] = NULL; - - m = (const char **)modules; - - return m; -} - -static struct backends_list_entry { - struct ldb_backend_ops *ops; - struct backends_list_entry *prev, *next; -} *ldb_backends = NULL; - -static struct ops_list_entry { - const struct ldb_module_ops *ops; - struct ops_list_entry *next; -} *registered_modules = NULL; - -static struct backends_list_entry *ldb_find_backend(const char *url_prefix) -{ - struct backends_list_entry *backend; - - for (backend = ldb_backends; backend; backend = backend->next) { - if (strcmp(backend->ops->name, url_prefix) == 0) { - return backend; - } - } - - return NULL; -} - -/* - register a new ldb backend - - if override is true, then override any existing backend for this prefix -*/ -int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) -{ - struct backends_list_entry *be; - - be = ldb_find_backend(url_prefix); - if (be) { - if (!override) { - return LDB_SUCCESS; - } - } else { - be = talloc_zero(ldb_backends, struct backends_list_entry); - if (!be) { - return LDB_ERR_OPERATIONS_ERROR; - } - be->ops = talloc_zero(be, struct ldb_backend_ops); - if (!be->ops) { - talloc_free(be); - return LDB_ERR_OPERATIONS_ERROR; - } - DLIST_ADD_END(ldb_backends, be, struct backends_list_entry); - } - - be->ops->name = url_prefix; - be->ops->connect_fn = connectfn; - - return LDB_SUCCESS; -} - -/* - Return the ldb module form of a database. - The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific. - - This allows modules to get at only the backend module, for example where a - module may wish to direct certain requests at a particular backend. -*/ -int ldb_module_connect_backend(struct ldb_context *ldb, - const char *url, - const char *options[], - struct ldb_module **backend_module) -{ - int ret; - char *backend; - struct backends_list_entry *be; - - if (strchr(url, ':') != NULL) { - backend = talloc_strndup(ldb, url, strchr(url, ':')-url); - } else { - /* Default to tdb */ - backend = talloc_strdup(ldb, "tdb"); - } - if (backend == NULL) { - return ldb_oom(ldb); - } - - be = ldb_find_backend(backend); - - talloc_free(backend); - - if (be == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); - return LDB_ERR_OTHER; - } - - ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); - - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Failed to connect to '%s' with backend '%s'", url, be->ops->name); - return ret; - } - return ret; -} - -static struct ldb_hooks { - struct ldb_hooks *next, *prev; - ldb_hook_fn hook_fn; -} *ldb_hooks; - -/* - register a ldb hook function - */ -int ldb_register_hook(ldb_hook_fn hook_fn) -{ - struct ldb_hooks *lc; - lc = talloc_zero(ldb_hooks, struct ldb_hooks); - if (lc == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lc->hook_fn = hook_fn; - DLIST_ADD_END(ldb_hooks, lc, struct ldb_hooks); - return LDB_SUCCESS; -} - -/* - call ldb hooks of a given type - */ -int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) -{ - struct ldb_hooks *lc; - for (lc = ldb_hooks; lc; lc=lc->next) { - int ret = lc->hook_fn(ldb, t); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} - - -static const struct ldb_module_ops *ldb_find_module_ops(const char *name) -{ - struct ops_list_entry *e; - - for (e = registered_modules; e; e = e->next) { - if (strcmp(e->ops->name, name) == 0) - return e->ops; - } - - return NULL; -} - - -int ldb_register_module(const struct ldb_module_ops *ops) -{ - struct ops_list_entry *entry; - - if (ldb_find_module_ops(ops->name) != NULL) - return LDB_ERR_ENTRY_ALREADY_EXISTS; - - entry = talloc(talloc_autofree_context(), struct ops_list_entry); - if (entry == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - entry->ops = ops; - entry->next = registered_modules; - registered_modules = entry; - - return LDB_SUCCESS; -} - -/* - load a list of modules - */ -int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, - struct ldb_module *backend, struct ldb_module **out) -{ - struct ldb_module *module; - unsigned int i; - - module = backend; - - for (i = 0; module_list && module_list[i] != NULL; i++) { - struct ldb_module *current; - const struct ldb_module_ops *ops; - - if (strcmp(module_list[i], "") == 0) { - continue; - } - - ops = ldb_find_module_ops(module_list[i]); - - if (ops == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", - module_list[i]); - return LDB_ERR_OPERATIONS_ERROR; - } - - current = talloc_zero(ldb, struct ldb_module); - if (current == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - talloc_set_name(current, "ldb_module: %s", module_list[i]); - - current->ldb = ldb; - current->ops = ops; - - DLIST_ADD(module, current); - } - *out = module; - return LDB_SUCCESS; -} - -/* - initialise a chain of modules - */ -int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) -{ - while (module && module->ops->init_context == NULL) - module = module->next; - - /* init is different in that it is not an error if modules - * do not require initialization */ - - if (module) { - int ret = module->ops->init_context(module); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", - module->ops->name, ldb_strerror(ret)); - return ret; - } - } - - return LDB_SUCCESS; -} - -int ldb_load_modules(struct ldb_context *ldb, const char *options[]) -{ - const char *modules_string; - const char **modules = NULL; - int ret; - TALLOC_CTX *mem_ctx = talloc_new(ldb); - if (!mem_ctx) { - return ldb_oom(ldb); - } - - /* find out which modules we are requested to activate */ - - /* check if we have a custom module list passd as ldb option */ - if (options) { - modules_string = ldb_options_find(ldb, options, "modules"); - if (modules_string) { - modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); - } - } - - /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ - if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { - const char * const attrs[] = { "@LIST" , NULL}; - struct ldb_result *res = NULL; - struct ldb_dn *mods_dn; - - mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); - if (mods_dn == NULL) { - talloc_free(mem_ctx); - return ldb_oom(ldb); - } - - ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } else if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); - talloc_free(mem_ctx); - return ret; - } else { - const char *module_list; - if (res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } else if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%u), bailing out", res->count); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } else { - module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); - if (!module_list) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } - modules = ldb_modules_list_from_string(ldb, mem_ctx, - module_list); - } - } - - talloc_free(mods_dn); - } - - if (modules != NULL) { - ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - } else { - ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database"); - } - - ret = ldb_module_init_chain(ldb, ldb->modules); - talloc_free(mem_ctx); - return ret; -} - -/* - by using this we allow ldb modules to only implement the functions they care about, - which makes writing a module simpler, and makes it more likely to keep working - when ldb is extended -*/ -#define FIND_OP_NOERR(module, op) do { \ - module = module->next; \ - while (module && module->ops->op == NULL) module = module->next; \ - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ - module->ops->name); \ - } \ -} while (0) - -#define FIND_OP(module, op) do { \ - struct ldb_context *ldb = module->ldb; \ - FIND_OP_NOERR(module, op); \ - if (module == NULL) { \ - ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - - -struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, - struct ldb_context *ldb, - const char *module_name, - const struct ldb_module_ops *ops) -{ - struct ldb_module *module; - - module = talloc(memctx, struct ldb_module); - if (!module) { - ldb_oom(ldb); - return NULL; - } - talloc_set_name_const(module, module_name); - module->ldb = ldb; - module->prev = module->next = NULL; - module->ops = ops; - - return module; -} - -const char * ldb_module_get_name(struct ldb_module *module) -{ - return module->ops->name; -} - -struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) -{ - return module->ldb; -} - -const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) -{ - return module->ops; -} - -void *ldb_module_get_private(struct ldb_module *module) -{ - return module->private_data; -} - -void ldb_module_set_private(struct ldb_module *module, void *private_data) -{ - module->private_data = private_data; -} - -/* - helper functions to call the next module in chain -*/ - -int ldb_next_request(struct ldb_module *module, struct ldb_request *request) -{ - int ret; - - if (request->callback == NULL) { - ldb_set_errstring(module->ldb, "Requests MUST define callbacks"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - request->handle->nesting++; - - switch (request->operation) { - case LDB_SEARCH: - FIND_OP(module, search); - ret = module->ops->search(module, request); - break; - case LDB_ADD: - FIND_OP(module, add); - ret = module->ops->add(module, request); - break; - case LDB_MODIFY: - FIND_OP(module, modify); - ret = module->ops->modify(module, request); - break; - case LDB_DELETE: - FIND_OP(module, del); - ret = module->ops->del(module, request); - break; - case LDB_RENAME: - FIND_OP(module, rename); - ret = module->ops->rename(module, request); - break; - case LDB_EXTENDED: - FIND_OP(module, extended); - ret = module->ops->extended(module, request); - break; - default: - FIND_OP(module, request); - ret = module->ops->request(module, request); - break; - } - - request->handle->nesting--; - - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - - if (!(request->handle->flags & LDB_HANDLE_FLAG_DONE_CALLED)) { - /* It is _extremely_ common that a module returns a - * failure without calling ldb_module_done(), but that - * guarantees we will end up hanging in - * ldb_wait(). This fixes it without having to rewrite - * all our modules, and leaves us one less sharp - * corner for module developers to cut themselves on - */ - ret = ldb_module_done(request, NULL, NULL, ret); - } - return ret; -} - -int ldb_next_init(struct ldb_module *module) -{ - module = module->next; - - return ldb_module_init_chain(module->ldb, module); -} - -int ldb_next_start_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, start_transaction); - ret = module->ops->start_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_end_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, end_transaction); - ret = module->ops->end_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_prepare_commit(struct ldb_module *module) -{ - int ret; - FIND_OP_NOERR(module, prepare_commit); - if (module == NULL) { - /* we are allowed to have no prepare commit in - backends */ - return LDB_SUCCESS; - } - ret = module->ops->prepare_commit(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_del_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, del_transaction); - ret = module->ops->del_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) -{ - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return NULL; - } - - h->status = LDB_SUCCESS; - h->state = LDB_ASYNC_INIT; - h->ldb = ldb; - h->flags = 0; - h->location = NULL; - h->parent = NULL; - - return h; -} - -/* calls the request callback to send an entry - * - * params: - * req: the original request passed to your module - * msg: reply message (must be a talloc pointer, and it will be stolen - * on the ldb_reply that is sent to the callback) - * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen - * on the ldb_reply that is sent to the callback) - */ - -int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg, - struct ldb_control **ctrls) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_steal(ares, msg); - ares->controls = talloc_steal(ares, ctrls); - ares->error = LDB_SUCCESS; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - char *s; - ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); - s = ldb_ldif_message_string(req->handle->ldb, msg, LDB_CHANGETYPE_NONE, msg); - ldb_debug_add(req->handle->ldb, "%s\n", s); - talloc_free(s); - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* calls the request callback to send an referrals - * - * params: - * req: the original request passed to your module - * ref: referral string (must be a talloc pointeri, steal) - */ - -int ldb_module_send_referral(struct ldb_request *req, - char *ref) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_steal(ares, ref); - ares->error = LDB_SUCCESS; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - ldb_debug_add(req->handle->ldb, "ldb_trace_response: REFERRAL\n"); - ldb_debug_add(req->handle->ldb, "ref: %s\n", ref); - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* calls the original request callback - * - * params: - * req: the original request passed to your module - * ctrls: controls to send in the reply (must be a talloc pointer, steal) - * response: results for extended request (steal) - * error: LDB_SUCCESS for a successful return - * any other ldb error otherwise - */ -int ldb_module_done(struct ldb_request *req, - struct ldb_control **ctrls, - struct ldb_extended *response, - int error) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->response = talloc_steal(ares, response); - ares->error = error; - - req->handle->flags |= LDB_HANDLE_FLAG_DONE_CALLED; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - ldb_debug_add(req->handle->ldb, "ldb_trace_response: DONE\n"); - ldb_debug_add(req->handle->ldb, "error: %d\n", error); - if (ldb_errstring(req->handle->ldb)) { - ldb_debug_add(req->handle->ldb, "msg: %s\n", - ldb_errstring(req->handle->ldb)); - } - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* to be used *only* in modules init functions. - * this function is synchronous and will register - * the requested OID in the rootdse module if present - * otherwise it will return an error */ -int ldb_mod_register_control(struct ldb_module *module, const char *oid) -{ - struct ldb_request *req; - int ret; - - req = talloc_zero(module, struct ldb_request); - if (req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_REQ_REGISTER_CONTROL; - req->op.reg_control.oid = oid; - req->callback = ldb_op_default_callback; - - ldb_set_timeout(module->ldb, req, 0); - - req->handle = ldb_handle_new(req, module->ldb); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_request(module->ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - talloc_free(req); - - return ret; -} - -static int ldb_modules_load_dir(const char *modules_dir, const char *version); - - -/* - load one module. A static list of loaded module inode numbers is - used to prevent a module being loaded twice - - dlopen() is used on the module, and dlsym() is then used to look for - a ldb_init_module() function. If present, that function is called - with the ldb version number as an argument. - - The ldb_init_module() function will typically call - ldb_register_module() and ldb_register_backend() to register a - module or backend, but it may also be used to register command line - handling functions, ldif handlers or any other local - modififications. - - The ldb_init_module() function does not get a ldb_context passed in, - as modules will be used for multiple ldb context handles. The call - from the first ldb_init() is just a convenient way to ensure it is - called early enough. - */ -static int ldb_modules_load_path(const char *path, const char *version) -{ - void *handle; - int (*init_fn)(const char *); - int ret; - struct stat st; - static struct loaded { - struct loaded *next, *prev; - ino_t st_ino; - dev_t st_dev; - } *loaded; - struct loaded *le; - int dlopen_flags; - - ret = stat(path, &st); - if (ret != 0) { - fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); - return LDB_ERR_UNAVAILABLE; - } - - for (le=loaded; le; le=le->next) { - if (le->st_ino == st.st_ino && - le->st_dev == st.st_dev) { - /* its already loaded */ - return LDB_SUCCESS; - } - } - - le = talloc(loaded, struct loaded); - if (le == NULL) { - fprintf(stderr, "ldb: unable to allocated loaded entry\n"); - return LDB_ERR_UNAVAILABLE; - } - - le->st_ino = st.st_ino; - le->st_dev = st.st_dev; - - DLIST_ADD_END(loaded, le, struct loaded); - - /* if it is a directory, recurse */ - if (S_ISDIR(st.st_mode)) { - return ldb_modules_load_dir(path, version); - } - - dlopen_flags = RTLD_NOW; -#ifdef RTLD_DEEPBIND - /* use deepbind if possible, to avoid issues with different - system library varients, for example ldb modules may be linked - against Heimdal while the application may use MIT kerberos - - See the dlopen manpage for details - */ - dlopen_flags |= RTLD_DEEPBIND; -#endif - - handle = dlopen(path, dlopen_flags); - if (handle == NULL) { - fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); - return LDB_SUCCESS; - } - - init_fn = dlsym(handle, "ldb_init_module"); - if (init_fn == NULL) { - /* ignore it, it could be an old-style - * module. Once we've converted all modules we - * could consider this an error */ - dlclose(handle); - return LDB_SUCCESS; - } - - ret = init_fn(version); - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - /* the module is already registered - ignore this, as - * it can happen if LDB_MODULES_PATH points at both - * the build and install directory - */ - ret = LDB_SUCCESS; - } - return ret; -} - -static int qsort_string(const char **s1, const char **s2) -{ - return strcmp(*s1, *s2); -} - - -/* - load all modules from the given ldb modules directory. This is run once - during the first ldb_init() call. - - Modules are loaded in alphabetical order to ensure that any module - load ordering dependencies are reproducible. Modules should avoid - relying on load order - */ -static int ldb_modules_load_dir(const char *modules_dir, const char *version) -{ - DIR *dir; - struct dirent *de; - const char **modlist = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(NULL); - unsigned i, num_modules = 0; - - dir = opendir(modules_dir); - if (dir == NULL) { - if (errno == ENOENT) { - talloc_free(tmp_ctx); - /* we don't have any modules */ - return LDB_SUCCESS; - } - talloc_free(tmp_ctx); - fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", - modules_dir, strerror(errno)); - return LDB_ERR_UNAVAILABLE; - } - - - while ((de = readdir(dir))) { - if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) - continue; - - modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); - if (modlist == NULL) { - talloc_free(tmp_ctx); - closedir(dir); - fprintf(stderr, "ldb: unable to allocate modules list\n"); - return LDB_ERR_UNAVAILABLE; - } - modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); - if (modlist[num_modules] == NULL) { - talloc_free(tmp_ctx); - closedir(dir); - fprintf(stderr, "ldb: unable to allocate module list entry\n"); - return LDB_ERR_UNAVAILABLE; - } - num_modules++; - } - - closedir(dir); - - /* sort the directory, so we get consistent load ordering */ - TYPESAFE_QSORT(modlist, num_modules, qsort_string); - - for (i=0; ihandle) { - char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", - i++, req, ldb_req_location(req)); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - req = req->handle->parent; - } - return ret; -} - - -/* - return the next module in the chain - */ -struct ldb_module *ldb_module_next(struct ldb_module *module) -{ - return module->next; -} - -/* - set the next module in the module chain - */ -void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) -{ - module->next = next; -} - - -/* - get the popt_options pointer in the ldb structure. This allows a ldb - module to change the command line parsing - */ -struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) -{ - return &ldb->popt_options; -} - - -/* - return the current ldb flags LDB_FLG_* - */ -uint32_t ldb_module_flags(struct ldb_context *ldb) -{ - return ldb->flags; -} diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c deleted file mode 100644 index 28c414e6b23..00000000000 --- a/source4/lib/ldb/common/ldb_msg.c +++ /dev/null @@ -1,1187 +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 message component utility functions - * - * Description: functions for manipulating ldb_message structures - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - create a new ldb_message in a given memory context (NULL for top level) -*/ -struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldb_message); -} - -/* - find an element in a message by attribute name -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name) -{ - unsigned int i; - for (i=0;inum_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { - return &msg->elements[i]; - } - } - return NULL; -} - -/* - see if two ldb_val structures contain exactly the same data - return 1 for a match, 0 for a mis-match -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) return 0; - if (v1->data == v2->data) return 1; - if (v1->length == 0) return 1; - - if (memcmp(v1->data, v2->data, v1->length) == 0) { - return 1; - } - - return 0; -} - -/* - find a value in an element - assumes case sensitive comparison -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val) -{ - unsigned int i; - for (i=0;inum_values;i++) { - if (ldb_val_equal_exact(val, &el->values[i])) { - return &el->values[i]; - } - } - return NULL; -} - -/* - duplicate a ldb_val structure -*/ -struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) -{ - struct ldb_val v2; - v2.length = v->length; - if (v->data == NULL) { - v2.data = NULL; - return v2; - } - - /* the +1 is to cope with buggy C library routines like strndup - that look one byte beyond */ - v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); - if (!v2.data) { - v2.length = 0; - return v2; - } - - memcpy(v2.data, v->data, v->length); - ((char *)v2.data)[v->length] = 0; - return v2; -} - -/** - * Adds new empty element to msg->elements - */ -static int _ldb_msg_add_el(struct ldb_message *msg, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *els; - - /* - * TODO: Find out a way to assert on input parameters. - * msg and return_el must be valid - */ - - els = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements + 1); - if (!els) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ZERO_STRUCT(els[msg->num_elements]); - - msg->elements = els; - msg->num_elements++; - - *return_el = &els[msg->num_elements-1]; - - return LDB_SUCCESS; -} - -/** - * Add an empty element with a given name to a message - */ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) -{ - int ret; - struct ldb_message_element *el; - - ret = _ldb_msg_add_el(msg, &el); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* initialize newly added element */ - el->flags = flags; - el->name = talloc_strdup(msg->elements, attr_name); - if (!el->name) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (return_el) { - *return_el = el; - } - - return LDB_SUCCESS; -} - -/** - * Adds an element to a message. - * - * NOTE: Ownership of ldb_message_element fields - * is NOT transferred. Thus, if *el pointer - * is invalidated for some reason, this will - * corrupt *msg contents also - */ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags) -{ - int ret; - struct ldb_message_element *el_new; - /* We have to copy this, just in case *el is a pointer into - * what ldb_msg_add_empty() is about to realloc() */ - struct ldb_message_element el_copy = *el; - - ret = _ldb_msg_add_el(msg, &el_new); - if (ret != LDB_SUCCESS) { - return ret; - } - - el_new->flags = flags; - el_new->name = el_copy.name; - el_new->num_values = el_copy.num_values; - el_new->values = el_copy.values; - - return LDB_SUCCESS; -} - -/* - add a value to a message -*/ -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *el; - struct ldb_val *vals; - int ret; - - el = ldb_msg_find_element(msg, attr_name); - if (!el) { - ret = ldb_msg_add_empty(msg, attr_name, 0, &el); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - vals = talloc_realloc(msg->elements, el->values, struct ldb_val, - el->num_values+1); - if (!vals) { - return LDB_ERR_OPERATIONS_ERROR; - } - el->values = vals; - el->values[el->num_values] = *val; - el->num_values++; - - if (return_el) { - *return_el = el; - } - - return LDB_SUCCESS; -} - - -/* - add a value to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val) -{ - int ret; - struct ldb_message_element *el; - - ret = ldb_msg_add_value(msg, attr_name, val, &el); - if (ret == LDB_SUCCESS) { - talloc_steal(el->values, val->data); - } - return ret; -} - - -/* - add a string element to a message -*/ -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str) -{ - struct ldb_val val; - - val.data = discard_const_p(uint8_t, str); - val.length = strlen(str); - - if (val.length == 0) { - /* allow empty strings as non-existent attributes */ - return LDB_SUCCESS; - } - - return ldb_msg_add_value(msg, attr_name, &val, NULL); -} - -/* - add a string element to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str) -{ - struct ldb_val val; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - if (val.length == 0) { - /* allow empty strings as non-existent attributes */ - return LDB_SUCCESS; - } - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - add a DN element to a message - WARNING: this uses the linearized string from the dn, and does not - copy the string. -*/ -int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn) -{ - char *str = ldb_dn_alloc_linearized(msg, dn); - - if (str == NULL) { - /* we don't want to have unknown DNs added */ - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_msg_add_steal_string(msg, attr_name, str); -} - -/* - add a printf formatted element to a message -*/ -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) -{ - struct ldb_val val; - va_list ap; - char *str; - - va_start(ap, fmt); - str = talloc_vasprintf(msg, fmt, ap); - va_end(ap); - - if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - compare two ldb_message_element structures - assumes case sensitive comparison -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - unsigned int i; - - if (el1->num_values != el2->num_values) { - return el1->num_values - el2->num_values; - } - - for (i=0;inum_values;i++) { - if (!ldb_msg_find_val(el2, &el1->values[i])) { - return -1; - } - } - - return 0; -} - -/* - compare two ldb_message_element structures - comparing by element name -*/ -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - return ldb_attr_cmp(el1->name, el2->name); -} - -/* - convenience functions to return common types from a message - these return the first value if the attribute is multi-valued -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, - const char *attr_name) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); - if (!el || el->num_values == 0) { - return NULL; - } - return &el->values[0]; -} - -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-2147483648")]; - char *end = NULL; - int ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (int) strtoll(buf, &end, 10); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-2147483648")]; - char *end = NULL; - unsigned int ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (unsigned int) strtoll(buf, &end, 10); - if (errno != 0) { - errno = 0; - ret = (unsigned int) strtoull(buf, &end, 10); - if (errno != 0) { - return default_value; - } - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-9223372036854775808")]; - char *end = NULL; - int64_t ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (int64_t) strtoll(buf, &end, 10); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-9223372036854775808")]; - char *end = NULL; - uint64_t ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (uint64_t) strtoll(buf, &end, 10); - if (errno != 0) { - errno = 0; - ret = (uint64_t) strtoull(buf, &end, 10); - if (errno != 0) { - return default_value; - } - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char *buf; - char *end = NULL; - double ret; - - if (!v || !v->data) { - return default_value; - } - buf = talloc_strndup(msg, (const char *)v->data, v->length); - if (buf == NULL) { - return default_value; - } - - errno = 0; - ret = strtod(buf, &end); - talloc_free(buf); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) { - return 0; - } - if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) { - return 1; - } - return default_value; -} - -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - if (v->data[v->length] != '\0') { - return default_value; - } - return (const char *)v->data; -} - -struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char *attr_name) -{ - struct ldb_dn *res_dn; - const struct ldb_val *v; - - v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return NULL; - } - res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v); - if ( ! ldb_dn_validate(res_dn)) { - talloc_free(res_dn); - return NULL; - } - return res_dn; -} - -/* - sort the elements of a message by name -*/ -void ldb_msg_sort_elements(struct ldb_message *msg) -{ - TYPESAFE_QSORT(msg->elements, msg->num_elements, - ldb_msg_element_compare_name); -} - -/* - shallow copy a message - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - unsigned int i; - - msg2 = talloc(mem_ctx, struct ldb_message); - if (msg2 == NULL) return NULL; - - *msg2 = *msg; - - msg2->elements = talloc_array(msg2, struct ldb_message_element, - msg2->num_elements); - if (msg2->elements == NULL) goto failed; - - for (i=0;inum_elements;i++) { - msg2->elements[i] = msg->elements[i]; - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/* - copy a message, allocating new memory for all parts -*/ -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - unsigned int i, j; - - msg2 = ldb_msg_copy_shallow(mem_ctx, msg); - if (msg2 == NULL) return NULL; - - msg2->dn = ldb_dn_copy(msg2, msg2->dn); - if (msg2->dn == NULL) goto failed; - - for (i=0;inum_elements;i++) { - struct ldb_message_element *el = &msg2->elements[i]; - struct ldb_val *values = el->values; - el->name = talloc_strdup(msg2->elements, el->name); - if (el->name == NULL) goto failed; - el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); - for (j=0;jnum_values;j++) { - el->values[j] = ldb_val_dup(el->values, &values[j]); - if (el->values[j].data == NULL && values[j].length != 0) { - goto failed; - } - } - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/** - * Canonicalize a message, merging elements of the same name - */ -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - int ret; - struct ldb_message *msg2; - - /* - * Preserve previous behavior and allocate - * *msg2 into *ldb context - */ - ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); - if (ret != LDB_SUCCESS) { - return NULL; - } - - return msg2; -} - -/** - * Canonicalize a message, merging elements of the same name - */ -int ldb_msg_normalize(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - struct ldb_message **_msg_out) -{ - unsigned int i; - struct ldb_message *msg2; - - msg2 = ldb_msg_copy(mem_ctx, msg); - if (msg2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_msg_sort_elements(msg2); - - for (i=1; i < msg2->num_elements; i++) { - struct ldb_message_element *el1 = &msg2->elements[i-1]; - struct ldb_message_element *el2 = &msg2->elements[i]; - - if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = talloc_realloc(msg2->elements, - el1->values, struct ldb_val, - el1->num_values + el2->num_values); - if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { - talloc_free(msg2); - return LDB_ERR_OPERATIONS_ERROR; - } - memcpy(el1->values + el1->num_values, - el2->values, - sizeof(struct ldb_val) * el2->num_values); - el1->num_values += el2->num_values; - talloc_free(discard_const_p(char, el2->name)); - if ((i+1) < msg2->num_elements) { - memmove(el2, el2+1, sizeof(struct ldb_message_element) * - (msg2->num_elements - (i+1))); - } - msg2->num_elements--; - i--; - } - } - - *_msg_out = msg2; - return LDB_SUCCESS; -} - - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call, - * it can be used to save edits to a message - */ -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) -{ - int ldb_ret; - struct ldb_message *mod; - - ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); - if (ldb_ret != LDB_SUCCESS) { - return NULL; - } - - return mod; -} - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call it can be used to save edits to a message - * - * Result message is constructed as follows: - * - LDB_FLAG_MOD_ADD - elements found only in msg2 - * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 - * Value for msg2 element is used - * - LDB_FLAG_MOD_DELETE - elements found only in msg2 - * - * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR - */ -int ldb_msg_difference(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_message **_msg_out) -{ - int ldb_res; - unsigned int i; - struct ldb_message *mod; - struct ldb_message_element *el; - TALLOC_CTX *temp_ctx; - - temp_ctx = talloc_new(mem_ctx); - if (!temp_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = ldb_msg_new(temp_ctx); - if (mod == NULL) { - goto failed; - } - - mod->dn = msg1->dn; - mod->num_elements = 0; - mod->elements = NULL; - - /* - * Canonicalize *msg2 so we have no repeated elements - * Resulting message is allocated in *mod's mem context, - * as we are going to move some elements from *msg2 to - * *mod object later - */ - ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - - /* look in msg2 to find elements that need to be added or modified */ - for (i=0;inum_elements;i++) { - el = ldb_msg_find_element(msg1, msg2->elements[i].name); - - if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { - continue; - } - - ldb_res = ldb_msg_add(mod, - &msg2->elements[i], - el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - } - - /* look in msg1 to find elements that need to be deleted */ - for (i=0;inum_elements;i++) { - el = ldb_msg_find_element(msg2, msg1->elements[i].name); - if (el == NULL) { - ldb_res = ldb_msg_add_empty(mod, - msg1->elements[i].name, - LDB_FLAG_MOD_DELETE, NULL); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - } - } - - /* steal resulting message into supplied context */ - talloc_steal(mem_ctx, mod); - *_msg_out = mod; - - talloc_free(temp_ctx); - return LDB_SUCCESS; - -failed: - talloc_free(temp_ctx); - return LDB_ERR_OPERATIONS_ERROR; -} - - -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - unsigned int i, j; - - /* basic check on DN */ - if (msg->dn == NULL) { - ldb_set_errstring(ldb, "ldb message lacks a DN!"); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* basic syntax checks */ - for (i = 0; i < msg->num_elements; i++) { - for (j = 0; j < msg->elements[i].num_values; j++) { - if (msg->elements[i].values[j].length == 0) { - /* an attribute cannot be empty */ - ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", - msg->elements[i].name, - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return LDB_SUCCESS; -} - - - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers) -*/ -const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) -{ - const char **ret; - unsigned int i; - - for (i=0;attrs && attrs[i];i++) /* noop */ ; - ret = talloc_array(mem_ctx, const char *, i+1); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs && attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = attrs[i]; - return ret; -} - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers). The new attribute is added to the list. -*/ -const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) -{ - const char **ret; - unsigned int i; - bool found = false; - - for (i=0;attrs && attrs[i];i++) { - if (ldb_attr_cmp(attrs[i], new_attr) == 0) { - found = true; - } - } - if (found) { - return ldb_attr_list_copy(mem_ctx, attrs); - } - ret = talloc_array(mem_ctx, const char *, i+2); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs && attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = new_attr; - ret[i+1] = NULL; - return ret; -} - - -/* - return 1 if an attribute is in a list of attributes, or 0 otherwise -*/ -int ldb_attr_in_list(const char * const *attrs, const char *attr) -{ - unsigned int i; - for (i=0;attrs && attrs[i];i++) { - if (ldb_attr_cmp(attrs[i], attr) == 0) { - return 1; - } - } - return 0; -} - - -/* - rename the specified attribute in a search result -*/ -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - if (el == NULL) { - return LDB_SUCCESS; - } - el->name = talloc_strdup(msg->elements, replace); - if (el->name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - - -/* - copy the specified attribute in a search result to a new attribute -*/ -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - int ret; - - if (el == NULL) { - return LDB_SUCCESS; - } - ret = ldb_msg_add(msg, el, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - return ldb_msg_rename_attr(msg, attr, replace); -} - -/* - remove the specified element in a search result -*/ -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) -{ - ptrdiff_t n = (el - msg->elements); - if (n >= msg->num_elements) { - /* should we abort() here? */ - return; - } - if (n != msg->num_elements-1) { - memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); - } - msg->num_elements--; -} - - -/* - remove the specified attribute in a search result -*/ -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) -{ - struct ldb_message_element *el; - - while ((el = ldb_msg_find_element(msg, attr)) != NULL) { - ldb_msg_remove_element(msg, el); - } -} - -/* - return a LDAP formatted GeneralizedTime string -*/ -char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) -{ - struct tm *tm = gmtime(&t); - char *ts; - int r; - - if (!tm) { - return NULL; - } - - /* we now excatly how long this string will be */ - ts = talloc_array(mem_ctx, char, 18); - - /* formatted like: 20040408072012.0Z */ - r = snprintf(ts, 18, - "%04u%02u%02u%02u%02u%02u.0Z", - tm->tm_year+1900, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - if (r != 17) { - talloc_free(ts); - return NULL; - } - - return ts; -} - -/* - convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert -*/ -time_t ldb_string_to_time(const char *s) -{ - struct tm tm; - - if (s == NULL) return 0; - - memset(&tm, 0, sizeof(tm)); - if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return 0; - } - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return timegm(&tm); -} - -/* - convert a LDAP GeneralizedTime string in ldb_val format to a - time_t. -*/ -int ldb_val_to_time(const struct ldb_val *v, time_t *t) -{ - struct tm tm; - - if (v == NULL || !v->data || v->length < 17) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - memset(&tm, 0, sizeof(tm)); - - if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - *t = timegm(&tm); - - return LDB_SUCCESS; -} - -/* - return a LDAP formatted UTCTime string -*/ -char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t) -{ - struct tm *tm = gmtime(&t); - char *ts; - int r; - - if (!tm) { - return NULL; - } - - /* we now excatly how long this string will be */ - ts = talloc_array(mem_ctx, char, 14); - - /* formatted like: 20040408072012.0Z => 040408072012Z */ - r = snprintf(ts, 14, - "%02u%02u%02u%02u%02u%02uZ", - (tm->tm_year+1900)%100, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - if (r != 13) { - talloc_free(ts); - return NULL; - } - - return ts; -} - -/* - convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert -*/ -time_t ldb_string_utc_to_time(const char *s) -{ - struct tm tm; - - if (s == NULL) return 0; - - memset(&tm, 0, sizeof(tm)); - if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return 0; - } - if (tm.tm_year < 50) { - tm.tm_year += 100; - } - tm.tm_mon -= 1; - - return timegm(&tm); -} - - -/* - dump a set of results to a file. Useful from within gdb -*/ -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) -{ - unsigned int i; - - for (i = 0; i < result->count; i++) { - struct ldb_ldif ldif; - fprintf(f, "# record %d\n", i+1); - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = result->msgs[i]; - ldb_ldif_write_file(ldb, f, &ldif); - } -} - -/* - checks for a string attribute. Returns "1" on match and otherwise "0". -*/ -int ldb_msg_check_string_attribute(const struct ldb_message *msg, - const char *name, const char *value) -{ - struct ldb_message_element *el; - struct ldb_val val; - - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return 0; - } - - val.data = discard_const_p(uint8_t, value); - val.length = strlen(value); - - if (ldb_msg_find_val(el, &val)) { - return 1; - } - - return 0; -} - diff --git a/source4/lib/ldb/common/ldb_options.c b/source4/lib/ldb/common/ldb_options.c deleted file mode 100644 index f07f3935624..00000000000 --- a/source4/lib/ldb/common/ldb_options.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2010 - - ** 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 options[] handling - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - find an option within an options array - - accepts the following forms: - - NAME - NAME:value - NAME=value - - returns a pointer into an element of the options[] array, or NULL is - not found. - - For the NAME form, returns a pointer to an empty string (thus - allowing for boolean options). - */ -const char *ldb_options_find(struct ldb_context *ldb, const char *options[], - const char *option_name) -{ - size_t len = strlen(option_name); - int i; - - if (options == NULL) { - return NULL; - } - - for (i=0; options[i]; i++) { - if (strncmp(option_name, options[i], len) != 0) { - continue; - } - if (options[i][len] == ':' || options[i][len] == '=') { - return &options[i][len+1]; - } - if (options[i][len] == 0) { - return &options[i][len]; - } - } - - return NULL; -} diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c deleted file mode 100644 index b4eabf8375c..00000000000 --- a/source4/lib/ldb/common/ldb_parse.c +++ /dev/null @@ -1,903 +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 expression parsing - * - * Description: parse LDAP-like search expressions - * - * Author: Andrew Tridgell - */ - -/* - TODO: - - add RFC2254 binary string handling - - possibly add ~=, <= and >= handling - - expand the test suite - - add better parse error handling - -*/ - -#include "ldb_private.h" -#include "system/locale.h" - -static int ldb_parse_hex2char(const char *x) -{ - if (isxdigit(x[0]) && isxdigit(x[1])) { - const char h1 = x[0], h2 = x[1]; - int c = 0; - - if (h1 >= 'a') c = h1 - (int)'a' + 10; - else if (h1 >= 'A') c = h1 - (int)'A' + 10; - else if (h1 >= '0') c = h1 - (int)'0'; - c = c << 4; - if (h2 >= 'a') c += h2 - (int)'a' + 10; - else if (h2 >= 'A') c += h2 - (int)'A' + 10; - else if (h2 >= '0') c += h2 - (int)'0'; - - return c; - } - - return -1; -} - -/* -a filter is defined by: - ::= '(' ')' - ::= | | | - ::= '&' - ::= '|' - ::= '!' - ::= | - ::= - ::= '=' | '~=' | '<=' | '>=' -*/ - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) -{ - size_t i, j; - struct ldb_val ret; - size_t slen = str?strlen(str):0; - - ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;idata == NULL) return NULL; - - val++; - } - - if (ret != NULL) { - ret[val] = NULL; - } - - return ret; -} - -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); - - -/* - parse an extended match - - possible forms: - (attr:oid:=value) - (attr:dn:oid:=value) - (attr:dn:=value) - (:dn:oid:=value) - - the ':dn' part sets the dnAttributes boolean if present - the oid sets the rule_id string - -*/ -static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, - char *attr, char *value) -{ - char *p1, *p2; - - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.value = ldb_binary_decode(ret, value); - if (ret->u.extended.value.data == NULL) goto failed; - - p1 = strchr(attr, ':'); - if (p1 == NULL) goto failed; - p2 = strchr(p1+1, ':'); - - *p1 = 0; - if (p2) *p2 = 0; - - ret->u.extended.attr = attr; - if (strcmp(p1+1, "dn") == 0) { - ret->u.extended.dnAttributes = 1; - if (p2) { - ret->u.extended.rule_id = talloc_strdup(ret, p2+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } else { - ret->u.extended.rule_id = NULL; - } - } else { - ret->u.extended.dnAttributes = 0; - ret->u.extended.rule_id = talloc_strdup(ret, p1+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) -{ - enum ldb_parse_op filter = 0; - char *name, *val, *k; - const char *p = *s; - const char *t, *t1; - - /* retrieve attributetype name */ - t = p; - - if (*p == '@') { /* for internal attributes the first char can be @ */ - p++; - } - - while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { - /* attribute names can only be alphanums */ - p++; - } - - if (*p == ':') { /* but extended searches have : and . chars too */ - p = strstr(p, ":="); - if (p == NULL) { /* malformed attribute name */ - return 0; - } - } - - t1 = p; - - while (isspace((unsigned char)*p)) p++; - - if (!strchr("=<>~:", *p)) { - return 0; - } - - /* save name */ - name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); - if (name == NULL) return 0; - name[t1 - t] = '\0'; - - /* retrieve filtertype */ - - if (*p == '=') { - filter = LDB_OP_EQUALITY; - } else if (*(p + 1) == '=') { - switch (*p) { - case '<': - filter = LDB_OP_LESS; - p++; - break; - case '>': - filter = LDB_OP_GREATER; - p++; - break; - case '~': - filter = LDB_OP_APPROX; - p++; - break; - case ':': - filter = LDB_OP_EXTENDED; - p++; - break; - } - } - if (!filter) { - talloc_free(name); - return filter; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - /* retrieve value */ - t = p; - - while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; - - val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); - if (val == NULL) { - talloc_free(name); - return 0; - } - val[p - t] = '\0'; - - k = &(val[p - t]); - - /* remove trailing spaces from value */ - while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; - *k = '\0'; - - *type = name; - *value = val; - *s = p; - return filter; -} - -/* - ::= -*/ -static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) -{ - char *attr, *value; - struct ldb_parse_tree *ret; - enum ldb_parse_op filtertype; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - filtertype = ldb_parse_filtertype(ret, &attr, &value, s); - if (!filtertype) { - talloc_free(ret); - return NULL; - } - - switch (filtertype) { - - case LDB_OP_PRESENT: - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - - case LDB_OP_EQUALITY: - - if (strcmp(value, "*") == 0) { - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - } - - if (ldb_parse_find_wildcard(value) != NULL) { - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = attr; - ret->u.substring.start_with_wildcard = 0; - ret->u.substring.end_with_wildcard = 0; - ret->u.substring.chunks = ldb_wildcard_decode(ret, value); - if (ret->u.substring.chunks == NULL){ - talloc_free(ret); - return NULL; - } - if (value[0] == '*') - ret->u.substring.start_with_wildcard = 1; - if (value[strlen(value) - 1] == '*') - ret->u.substring.end_with_wildcard = 1; - talloc_free(value); - - break; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = attr; - ret->u.equality.value = ldb_binary_decode(ret, value); - if (ret->u.equality.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_GREATER: - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_LESS: - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_APPROX: - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_EXTENDED: - - ret = ldb_parse_extended(ret, attr, value); - break; - - default: - talloc_free(ret); - return NULL; - } - - return ret; -} - - -/* - parse a filterlist - ::= '&' - ::= '|' - ::= | -*/ -static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret, *next; - enum ldb_parse_op op; - const char *p = *s; - - switch (*p) { - case '&': - op = LDB_OP_AND; - break; - case '|': - op = LDB_OP_OR; - break; - default: - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - - ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); - if (!ret->u.list.elements[0]) { - talloc_free(ret); - return NULL; - } - - while (isspace((unsigned char)*p)) p++; - - while (*p && (next = ldb_parse_filter(ret->u.list.elements, &p))) { - struct ldb_parse_tree **e; - e = talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements + 1); - if (!e) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace((unsigned char)*p)) p++; - } - - *s = p; - - return ret; -} - - -/* - ::= '!' -*/ -static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '!') { - return NULL; - } - p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldb_parse_filter(ret, &p); - if (!ret->u.isnot.child) { - talloc_free(ret); - return NULL; - } - - *s = p; - - return ret; -} - -/* - parse a filtercomp - ::= | | | -*/ -static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - while (isspace((unsigned char)*p)) p++; - - switch (*p) { - case '&': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '|': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '!': - ret = ldb_parse_not(mem_ctx, &p); - break; - - case '(': - case ')': - return NULL; - - default: - ret = ldb_parse_simple(mem_ctx, &p); - - } - - *s = p; - return ret; -} - - -/* - ::= '(' ')' -*/ -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '(') { - return NULL; - } - p++; - - ret = ldb_parse_filtercomp(mem_ctx, &p); - - if (*p != ')') { - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) { - p++; - } - - *s = p; - - return ret; -} - - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= | -*/ -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) -{ - if (s == NULL || *s == 0) { - s = "(|(objectClass=*)(distinguishedName=*))"; - } - - while (isspace((unsigned char)*s)) s++; - - if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); - } - - return ldb_parse_simple(mem_ctx, &s); -} - - -/* - construct a ldap parse filter given a parse tree -*/ -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) -{ - char *s, *s2, *ret; - unsigned int i; - - if (tree == NULL) { - return NULL; - } - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); - if (ret == NULL) return NULL; - for (i=0;iu.list.num_elements;i++) { - s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - s2 = talloc_asprintf_append(ret, "%s", s); - talloc_free(s); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - ret = s2; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - return s; - case LDB_OP_NOT: - s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); - if (s == NULL) return NULL; - - ret = talloc_asprintf(mem_ctx, "(!%s)", s); - talloc_free(s); - return ret; - case LDB_OP_EQUALITY: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_SUBSTRING: - ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, - tree->u.substring.start_with_wildcard?"*":""); - if (ret == NULL) return NULL; - for (i = 0; tree->u.substring.chunks[i]; i++) { - s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - if (tree->u.substring.chunks[i+1] || - tree->u.substring.end_with_wildcard) { - s = talloc_asprintf_append(ret, "%s*", s2); - } else { - s = talloc_asprintf_append(ret, "%s", s2); - } - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - return ret; - case LDB_OP_GREATER: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s>=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_LESS: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s<=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_PRESENT: - ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); - return ret; - case LDB_OP_APPROX: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s~=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_EXTENDED: - s = ldb_binary_encode(mem_ctx, tree->u.extended.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", - tree->u.extended.attr?tree->u.extended.attr:"", - tree->u.extended.dnAttributes?":dn":"", - tree->u.extended.rule_id?":":"", - tree->u.extended.rule_id?tree->u.extended.rule_id:"", - s); - talloc_free(s); - return ret; - } - - return NULL; -} - - -/* - replace any occurrences of an attribute name in the parse tree with a - new name -*/ -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace) -{ - unsigned int i; - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - for (i=0;iu.list.num_elements;i++) { - ldb_parse_tree_attr_replace(tree->u.list.elements[i], - attr, replace); - } - break; - case LDB_OP_NOT: - ldb_parse_tree_attr_replace(tree->u.isnot.child, attr, replace); - break; - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) { - tree->u.equality.attr = replace; - } - break; - case LDB_OP_SUBSTRING: - if (ldb_attr_cmp(tree->u.substring.attr, attr) == 0) { - tree->u.substring.attr = replace; - } - break; - case LDB_OP_PRESENT: - if (ldb_attr_cmp(tree->u.present.attr, attr) == 0) { - tree->u.present.attr = replace; - } - break; - case LDB_OP_EXTENDED: - if (tree->u.extended.attr && - ldb_attr_cmp(tree->u.extended.attr, attr) == 0) { - tree->u.extended.attr = replace; - } - break; - } -} - -/* - shallow copy a tree - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_parse_tree *ot) -{ - unsigned int i; - struct ldb_parse_tree *nt; - - nt = talloc(mem_ctx, struct ldb_parse_tree); - if (!nt) { - return NULL; - } - - *nt = *ot; - - switch (ot->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *, - ot->u.list.num_elements); - if (!nt->u.list.elements) { - talloc_free(nt); - return NULL; - } - - for (i=0;iu.list.num_elements;i++) { - nt->u.list.elements[i] = - ldb_parse_tree_copy_shallow(nt->u.list.elements, - ot->u.list.elements[i]); - if (!nt->u.list.elements[i]) { - talloc_free(nt); - return NULL; - } - } - break; - case LDB_OP_NOT: - nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt, - ot->u.isnot.child); - if (!nt->u.isnot.child) { - talloc_free(nt); - return NULL; - } - break; - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - case LDB_OP_SUBSTRING: - case LDB_OP_PRESENT: - case LDB_OP_EXTENDED: - break; - } - - return nt; -} diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c deleted file mode 100644 index 55d8f905d35..00000000000 --- a/source4/lib/ldb/common/ldb_utf8.c +++ /dev/null @@ -1,136 +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 utf8 handling - * - * Description: case folding and case comparison for UTF8 strings - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" -#include "system/locale.h" - - -/* - this allow the user to pass in a caseless comparison - function to handle utf8 caseless comparisons - */ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *, size_t)) -{ - if (context) - ldb->utf8_fns.context = context; - if (casefold) - ldb->utf8_fns.casefold = casefold; -} - -/* - a simple case folding function - NOTE: does not handle UTF8 -*/ -char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) -{ - size_t i; - char *ret = talloc_strndup(mem_ctx, s, n); - if (!s) { - errno = ENOMEM; - return NULL; - } - for (i=0;ret[i];i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -void ldb_set_utf8_default(struct ldb_context *ldb) -{ - ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); -} - -char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) -{ - return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); -} - -/* - check the attribute name is valid according to rfc2251 - returns 1 if the name is ok - */ - -int ldb_valid_attr_name(const char *s) -{ - size_t i; - - if (!s || !s[0]) - return 0; - - /* handle special ldb_tdb wildcard */ - if (strcmp(s, "*") == 0) return 1; - - for (i = 0; s[i]; i++) { - if (! isascii(s[i])) { - return 0; - } - if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ - if (! (isalpha(s[i]) || (s[i] == '@'))) { - return 0; - } - } else { - if (! (isalnum(s[i]) || (s[i] == '-'))) { - return 0; - } - } - } - return 1; -} - -char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) -{ - size_t i; - char *ret = talloc_strdup(mem_ctx, s); - if (!ret) { - errno = ENOMEM; - return NULL; - } - for (i = 0; ret[i]; i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -/* - we accept either 'dn' or 'distinguishedName' for a distinguishedName -*/ -int ldb_attr_dn(const char *attr) -{ - if (ldb_attr_cmp(attr, "dn") == 0 || - ldb_attr_cmp(attr, "distinguishedName") == 0) { - return 0; - } - return -1; -} diff --git a/source4/lib/ldb/common/qsort.c b/source4/lib/ldb/common/qsort.c deleted file mode 100644 index 1a0b886b8c2..00000000000 --- a/source4/lib/ldb/common/qsort.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - - 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 2.1 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 - Lesser 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; if not, see . */ - -/* If you consider tuning this algorithm, you should consult first: - Engineering a sort function; Jon Bentley and M. Douglas McIlroy; - Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ - -/* Modified to be used in samba4 by - * Simo Sorce 2005 - */ - -#include "ldb_private.h" - -/* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations. */ -typedef struct - { - char *lo; - char *hi; - } stack_node; - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif -#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) -#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) -#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) -#define STACK_NOT_EMPTY (stack < top) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, - void *opaque, ldb_qsort_cmp_fn_t cmp) -{ - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - stack_node *top = stack; - - PUSH (NULL, NULL); - - while (STACK_NOT_EMPTY) - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) - left_ptr += size; - - while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - -#define min(x, y) ((x) < (y) ? (x) : (y)) - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } -} diff --git a/source4/lib/ldb/configure b/source4/lib/ldb/configure deleted file mode 100755 index 137a26bcbe0..00000000000 --- a/source4/lib/ldb/configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -if [ -f $PREVPATH/../../../buildtools/bin/waf ]; then - WAF=../../../buildtools/bin/waf -elif [ -f $PREVPATH/buildtools/bin/waf ]; then - WAF=./buildtools/bin/waf -else - echo "ldb: Unable to find waf" - exit 1 -fi - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd . || exit 1 -$WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/source4/lib/ldb/docs/builddocs.sh b/source4/lib/ldb/docs/builddocs.sh deleted file mode 100755 index 449dcb26815..00000000000 --- a/source4/lib/ldb/docs/builddocs.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# build ldb docs -# tridge@samba.org August 2006 - -XSLTPROC="$1" -SRCDIR="$2" - -if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then - echo "xsltproc not installed" - exit 0 -fi - -MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" -HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" - -mkdir -p man - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`" - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing manpage $f - $XSLTPROC --nonet -o "$out" "$MANXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $MANXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`".html - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing html $f - $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $HTMLXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done diff --git a/source4/lib/ldb/docs/design.txt b/source4/lib/ldb/docs/design.txt deleted file mode 100644 index 0bb278b5b42..00000000000 --- a/source4/lib/ldb/docs/design.txt +++ /dev/null @@ -1,41 +0,0 @@ -The list of indexed fields --------------------------- - -dn=@INDEXLIST - list of field names that are indexed - - contains fields of type @IDXATTR which contain attriute names - of indexed fields - - -Data records ------------- - -for each user record in the db there is: - main record - key: DN=dn - data: packed attribute/value list - - a index record for each indexed field in the record - - -Index Records -------------- - -The index records contain the list of dn's that contain records -matching the index key - -All index records are of the form: - dn=@INDEX:field:value - -and contain fields of type @IDX which are the dns of the records -that have that value for some attribute - - -Search Expressions ------------------- - -Very similar to LDAP search expressions, but does not allow ~=, <= or >= - - attrib0 := (field=value) - attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib diff --git a/source4/lib/ldb/docs/installdocs.sh b/source4/lib/ldb/docs/installdocs.sh deleted file mode 100755 index 6cc7b74ad51..00000000000 --- a/source4/lib/ldb/docs/installdocs.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# install ldb docs -# tridge@samba.org August 2006 - -MANDIR="$1" - -MAN1="`/bin/ls man/*.1`" -MAN3="`/bin/ls man/*.3`" - -if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then - echo "No manpages have been built" - exit 0 -fi - -mkdir -p "$MANDIR/man1" "$MANDIR/man3" -cp $MAN1 "$MANDIR/man1/" || exit 1 -cp $MAN3 "$MANDIR/man3/" || exit 1 diff --git a/source4/lib/ldb/examples.dox b/source4/lib/ldb/examples.dox deleted file mode 100644 index ef4b4f0a400..00000000000 --- a/source4/lib/ldb/examples.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ diff --git a/source4/lib/ldb/examples/ldbreader.c b/source4/lib/ldb/examples/ldbreader.c deleted file mode 100644 index 3496baf4ce2..00000000000 --- a/source4/lib/ldb/examples/ldbreader.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** 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 . -*/ - -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - -#include "ldb.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - const char *expression = "(dn=*)"; - struct ldb_result *resultMsg; - int i; - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL, NULL); - - /* - We now open the database. In this example we just hard code the connection path. - - Also note that the database is being opened read-only. This means that the - call will fail unless the database already exists. - */ - if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ - printf("Problem on connection\n"); - exit(-1); - } - - /* - At this stage we have an open database, and can start using it. It is opened - read-only, so a query is possible. - - We construct a search that just returns all the (sensible) contents. You can do - quite fine grained results with the LDAP search syntax, however it is a bit - confusing to start with. See RFC2254. - */ - if (LDB_SUCCESS != ldb_search(ldb, ldb, &resultMsg, - NULL, LDB_SCOPE_DEFAULT, NULL, - "%s", expression)) { - printf("Problem in search\n"); - exit(-1); - } - - printf("%i records returned\n", resultMsg->count); - - /* - We can now iterate through the results, writing them out - (to standard output) with our custom output routine as defined - at the top of this file - */ - for (i = 0; i < resultMsg->count; ++i) { - struct ldb_ldif ldifMsg; - - printf("Message: %i\n", i+1); - - ldifMsg.changetype = LDB_CHANGETYPE_NONE; - ldifMsg.msg = resultMsg->msgs[i]; - ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); - } - - /* - There are two objects to clean up - the result from the - ldb_search() query, and the original ldb context. - */ - talloc_free(resultMsg); - - talloc_free(ldb); - - return 0; -} diff --git a/source4/lib/ldb/examples/ldifreader.c b/source4/lib/ldb/examples/ldifreader.c deleted file mode 100644 index dcd9daf8121..00000000000 --- a/source4/lib/ldb/examples/ldifreader.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** 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 . -*/ - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ - -#include "ldb.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - FILE *fileStream; - struct ldb_ldif *ldifMsg; - - if (argc != 2) { - printf("Usage %s filename.ldif\n", argv[0]); - exit(1); - } - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL, NULL); - - fileStream = fopen(argv[1], "r"); - if (0 == fileStream) { - perror(argv[1]); - exit(1); - } - - /* - We now work through the filestream to get each entry. - */ - while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { - /* - Each message has a particular change type. For Add, - Modify and Delete, this will also appear in the - output listing (as changetype: add, changetype: - modify or changetype:delete, respectively). - */ - switch (ldifMsg->changetype) { - case LDB_CHANGETYPE_NONE: - printf("ChangeType: None\n"); - break; - case LDB_CHANGETYPE_ADD: - printf("ChangeType: Add\n"); - break; - case LDB_CHANGETYPE_MODIFY: - printf("ChangeType: Modify\n"); - break; - case LDB_CHANGETYPE_DELETE: - printf("ChangeType: Delete\n"); - break; - default: - printf("ChangeType: Unknown\n"); - } - - /* - We can now write out the results, using our custom - output routine as defined at the top of this file. - */ - ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); - - /* - Clean up the message - */ - ldb_ldif_read_free(ldb, ldifMsg); - } - - /* - Clean up the context - */ - talloc_free(ldb); - - return 0; -} diff --git a/source4/lib/ldb/include/dlinklist.h b/source4/lib/ldb/include/dlinklist.h deleted file mode 100644 index 1c577bb6b90..00000000000 --- a/source4/lib/ldb/include/dlinklist.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - Unix SMB/CIFS implementation. - some simple double linked list macros - - Copyright (C) Andrew Tridgell 1998-2010 - - ** 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 . -*/ - -/* To use these macros you must have a structure containing a next and - prev pointer */ - -#ifndef _DLINKLIST_H -#define _DLINKLIST_H - -/* - February 2010 - changed list format to have a prev pointer from the - list head. This makes DLIST_ADD_END() O(1) even though we only have - one list pointer. - - The scheme is as follows: - - 1) with no entries in the list: - list_head == NULL - - 2) with 1 entry in the list: - list_head->next == NULL - list_head->prev == list_head - - 3) with 2 entries in the list: - list_head->next == element2 - list_head->prev == element2 - element2->prev == list_head - element2->next == NULL - - 4) with N entries in the list: - list_head->next == element2 - list_head->prev == elementN - elementN->prev == element{N-1} - elementN->next == NULL - - This allows us to find the tail of the list by using - list_head->prev, which means we can add to the end of the list in - O(1) time - - - Note that the 'type' arguments below are no longer needed, but - are kept for now to prevent an incompatible argument change - */ - - -/* - add an element at the front of a list -*/ -#define DLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (p)->prev = (list) = (p); \ - (p)->next = NULL; \ - } else { \ - (p)->prev = (list)->prev; \ - (list)->prev = (p); \ - (p)->next = (list); \ - (list) = (p); \ - } \ -} while (0) - -/* - remove an element from a list - Note that the element doesn't have to be in the list. If it - isn't then this is a no-op -*/ -#define DLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - (list) = (p)->next; \ - } else if ((list) && (p) == (list)->prev) { \ - (p)->prev->next = NULL; \ - (list)->prev = (p)->prev; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) != (list)) (p)->next = (p)->prev = NULL; \ -} while (0) - -/* - find the head of the list given any element in it. - Note that this costs O(N), so you should avoid this macro - if at all possible! -*/ -#define DLIST_HEAD(p, result_head) \ -do { \ - (result_head) = (p); \ - while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ -} while(0) - -/* return the last element in the list */ -#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) - -/* return the previous element in the list. */ -#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) - -/* insert 'p' after the given element 'el' in a list. If el is NULL then - this is the same as a DLIST_ADD() */ -#define DLIST_ADD_AFTER(list, p, el) \ -do { \ - if (!(list) || !(el)) { \ - DLIST_ADD(list, p); \ - } else { \ - (p)->prev = (el); \ - (p)->next = (el)->next; \ - (el)->next = (p); \ - if ((p)->next) (p)->next->prev = (p); \ - if ((list)->prev == (el)) (list)->prev = (p); \ - }\ -} while (0) - - -/* - add to the end of a list. - Note that 'type' is ignored -*/ -#define DLIST_ADD_END(list, p, type) \ -do { \ - if (!(list)) { \ - DLIST_ADD(list, p); \ - } else { \ - DLIST_ADD_AFTER(list, p, (list)->prev); \ - } \ -} while (0) - -/* promote an element to the from of a list */ -#define DLIST_PROMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD(list, p); \ -} while (0) - -/* - demote an element to the end of a list. - Note that 'type' is ignored -*/ -#define DLIST_DEMOTE(list, p, type) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD_END(list, p, NULL); \ -} while (0) - -/* - concatenate two lists - putting all elements of the 2nd list at the - end of the first list. - Note that 'type' is ignored -*/ -#define DLIST_CONCATENATE(list1, list2, type) \ -do { \ - if (!(list1)) { \ - (list1) = (list2); \ - } else { \ - (list1)->prev->next = (list2); \ - if (list2) { \ - void *_tmplist = (void *)(list1)->prev; \ - (list1)->prev = (list2)->prev; \ - (list2)->prev = _tmplist; \ - } \ - } \ -} while (0) - -#endif /* _DLINKLIST_H */ diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h deleted file mode 100644 index d745f377b61..00000000000 --- a/source4/lib/ldb/include/ldb.h +++ /dev/null @@ -1,2254 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2005-2006 - - ** 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 header - * - * Description: defines for base ldb API - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -/** - \file ldb.h Samba's ldb database - - This header file provides the main API for ldb. -*/ - -#ifndef _LDB_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_H_ 1 -/*! \endcond */ - -#include -#include -#include -#include -#include - -/* - major restrictions as compared to normal LDAP: - - - each record must have a unique key field - - the key must be representable as a NULL terminated C string and may not - contain a comma or braces - - major restrictions as compared to tdb: - - - no explicit locking calls, but we have transactions when using ldb_tdb - -*/ - -#ifndef ldb_val -/** - Result value - - An individual lump of data in a result comes in this format. The - pointer will usually be to a UTF-8 string if the application is - sensible, but it can be to anything you like, including binary data - blobs of arbitrary size. - - \note the data is null (0x00) terminated, but the length does not - include the terminator. -*/ -struct ldb_val { - uint8_t *data; /*!< result data */ - size_t length; /*!< length of data */ -}; -#endif - -/*! \cond DOXYGEN_IGNORE */ -#ifndef PRINTF_ATTRIBUTE -#define PRINTF_ATTRIBUTE(a,b) -#endif - -#ifndef _DEPRECATED_ -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif -/*! \endcond */ - -/* opaque ldb_dn structures, see ldb_dn.c for internals */ -struct ldb_dn_component; -struct ldb_dn; - -/** - There are a number of flags that are used with ldap_modify() in - ldb_message_element.flags fields. The LDB_FLAGS_MOD_ADD, - LDB_FLAGS_MOD_DELETE and LDB_FLAGS_MOD_REPLACE flags are used in - ldap_modify() calls to specify whether attributes are being added, - deleted or modified respectively. -*/ -#define LDB_FLAG_MOD_MASK 0x3 - -/** - use this to extract the mod type from the operation - */ -#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) - -/** - Flag value used in ldap_modify() to indicate that attributes are - being added. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_ADD 1 - -/** - Flag value used in ldap_modify() to indicate that attributes are - being replaced. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_REPLACE 2 - -/** - Flag value used in ldap_modify() to indicate that attributes are - being deleted. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_DELETE 3 - -/** - flag bits on an element usable only by the internal implementation -*/ -#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 - -/** - OID for logic AND comaprison. - - This is the well known object ID for a logical AND comparitor. -*/ -#define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" - -/** - OID for logic OR comparison. - - This is the well known object ID for a logical OR comparitor. -*/ -#define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" - -/** - results are given back as arrays of ldb_message_element -*/ -struct ldb_message_element { - unsigned int flags; - const char *name; - unsigned int num_values; - struct ldb_val *values; -}; - - -/** - a ldb_message represents all or part of a record. It can contain an arbitrary - number of elements. -*/ -struct ldb_message { - struct ldb_dn *dn; - unsigned int num_elements; - struct ldb_message_element *elements; -}; - -enum ldb_changetype { - LDB_CHANGETYPE_NONE=0, - LDB_CHANGETYPE_ADD, - LDB_CHANGETYPE_DELETE, - LDB_CHANGETYPE_MODIFY, - LDB_CHANGETYPE_MODRDN -}; - -/** - LDIF record - - This structure contains a LDIF record, as returned from ldif_read() - and equivalent functions. -*/ -struct ldb_ldif { - enum ldb_changetype changetype; /*!< The type of change */ - struct ldb_message *msg; /*!< The changes */ -}; - -enum ldb_scope {LDB_SCOPE_DEFAULT=-1, - LDB_SCOPE_BASE=0, - LDB_SCOPE_ONELEVEL=1, - LDB_SCOPE_SUBTREE=2}; - -struct ldb_context; -struct tevent_context; - -/* debugging uses one of the following levels */ -enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, - LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; - -/** - the user can optionally supply a debug function. The function - is based on the vfprintf() style of interface, but with the addition - of a severity level -*/ -struct ldb_debug_ops { - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - void *context; -}; - -/** - The user can optionally supply a custom utf8 functions, - to handle comparisons and casefolding. -*/ -struct ldb_utf8_fns { - void *context; - char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); -}; - -/** - Flag value for database connection mode. - - If LDB_FLG_RDONLY is used in ldb_connect, then the database will be - opened read-only, if possible. -*/ -#define LDB_FLG_RDONLY 1 - -/** - Flag value for database connection mode. - - If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be - opened without synchronous operations, if possible. -*/ -#define LDB_FLG_NOSYNC 2 - -/** - Flag value to specify autoreconnect mode. - - If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will - be opened in a way that makes it try to auto reconnect if the - connection is dropped (actually make sense only with ldap). -*/ -#define LDB_FLG_RECONNECT 4 - -/** - Flag to tell backends not to use mmap -*/ -#define LDB_FLG_NOMMAP 8 - -/** - Flag to tell ldif handlers not to force encoding of binary - structures in base64 -*/ -#define LDB_FLG_SHOW_BINARY 16 - -/** - Flags to enable ldb tracing -*/ -#define LDB_FLG_ENABLE_TRACING 32 - -/* - structures for ldb_parse_tree handling code -*/ -enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, - LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, - LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, - LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; - -struct ldb_parse_tree { - enum ldb_parse_op operation; - union { - struct { - struct ldb_parse_tree *child; - } isnot; - struct { - const char *attr; - struct ldb_val value; - } equality; - struct { - const char *attr; - int start_with_wildcard; - int end_with_wildcard; - struct ldb_val **chunks; - } substring; - struct { - const char *attr; - } present; - struct { - const char *attr; - struct ldb_val value; - } comparison; - struct { - const char *attr; - int dnAttributes; - char *rule_id; - struct ldb_val value; - } extended; - struct { - unsigned int num_elements; - struct ldb_parse_tree **elements; - } list; - } u; -}; - -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); - -/** - Encode a binary blob - - This function encodes a binary blob using the encoding rules in RFC - 2254 (Section 4). This function also escapes any non-printable - characters. - - \param mem_ctx the memory context to allocate the return string in. - \param val the (potentially) binary data to be encoded - - \return the encoded data as a null terminated string - - \sa RFC 2252. -*/ -char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val); - -/** - Encode a string - - This function encodes a string using the encoding rules in RFC 2254 - (Section 4). This function also escapes any non-printable - characters. - - \param mem_ctx the memory context to allocate the return string in. - \param string the string to be encoded - - \return the encoded data as a null terminated string - - \sa RFC 2252. -*/ -char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string); - -/* - functions for controlling attribute handling -*/ -typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); -typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); -struct ldb_schema_attribute; -typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *, const struct ldb_val *, bool *matched); - -/* - attribute handler structure - - attr -> The attribute name - ldif_read_fn -> convert from ldif to binary format - ldif_write_fn -> convert from binary to ldif format - canonicalise_fn -> canonicalise a value, for use by indexing and dn construction - comparison_fn -> compare two values -*/ - -struct ldb_schema_syntax { - const char *name; - ldb_attr_handler_t ldif_read_fn; - ldb_attr_handler_t ldif_write_fn; - ldb_attr_handler_t canonicalise_fn; - ldb_attr_comparison_t comparison_fn; - ldb_attr_operator_t operator_fn; -}; - -struct ldb_schema_attribute { - const char *name; - unsigned flags; - const struct ldb_schema_syntax *syntax; -}; - -const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, - const char *name); - -struct ldb_dn_extended_syntax { - const char *name; - ldb_attr_handler_t read_fn; - ldb_attr_handler_t write_clear_fn; - ldb_attr_handler_t write_hex_fn; -}; - -const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, - const char *name); - -/** - The attribute is not returned by default -*/ -#define LDB_ATTR_FLAG_HIDDEN (1<<0) - -/* the attribute handler name should be freed when released */ -#define LDB_ATTR_FLAG_ALLOCATED (1<<1) - -/** - The attribute is supplied by the application and should not be removed -*/ -#define LDB_ATTR_FLAG_FIXED (1<<2) - -/* - when this is set, attempts to create two records which have the same - value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS - */ -#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3) - -/* - when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION - */ -#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) - -/** - LDAP attribute syntax for a DN - - This is the well-known LDAP attribute syntax for a DN. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" - -/** - LDAP attribute syntax for a Directory String - - This is the well-known LDAP attribute syntax for a Directory String. - - \sa RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" - -/** - LDAP attribute syntax for an integer - - This is the well-known LDAP attribute syntax for an integer. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" - -/** - LDAP attribute syntax for a boolean - - This is the well-known LDAP attribute syntax for a boolean. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_BOOLEAN "1.3.6.1.4.1.1466.115.121.1.7" - -/** - LDAP attribute syntax for an octet string - - This is the well-known LDAP attribute syntax for an octet string. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" - -/** - LDAP attribute syntax for UTC time. - - This is the well-known LDAP attribute syntax for a UTC time. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" - -#define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" - -/* sorting helpers */ -typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); - -/* Individual controls */ - -/** - OID for getting and manipulating attributes from the ldb - without interception in the operational module. - It can be used to access attribute that used to be stored in the sam - and that are now calculated. -*/ -#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" -#define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" - -/** - OID for recalculate SD control. This control force the - dsdb code to recalculate the SD of the object as if the - object was just created. - -*/ -#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" -#define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" - -/** - REVEAL_INTERNALS is used to reveal internal attributes and DN - components which are not normally shown to the user -*/ -#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" -#define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" - -/** - LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations - that are performed by the system, but with a user's credentials, e.g. - updating prefix map -*/ -#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" - -/** - LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is - mainly thought to be used for the provisioning. -*/ -#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" -#define LDB_CONTROL_PROVISION_NAME "provision" - -/* AD controls */ - -/** - OID for the paged results control. This control is included in the - searchRequest and searchResultDone messages as part of the controls - field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa RFC 2696. -*/ -#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" -#define LDB_CONTROL_PAGED_RESULTS_NAME "paged_results" - -/** - OID for specifying the returned elements of the ntSecurityDescriptor - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" -#define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" - -/** - OID for specifying an advanced scope for the search (one partition) - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" -#define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" - -/** - OID for specifying an advanced scope for a search - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" -#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" - -/** - OID for notification - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" -#define LDB_CONTROL_NOTIFICATION_NAME "notification" - -/** - OID for performing subtree deletes - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" -#define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" - -/** - OID for getting deleted objects - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" -#define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" - -/** - OID for getting recycled objects - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" -#define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" - -/** - OID for getting deactivated linked attributes - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" -#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" - -/** - OID for extended DN - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" -#define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" - -/** - OID for LDAP server sort result extension. - - This control is included in the searchRequest message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 - of LDAP v3. The controlType is set to - "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or - FALSE (where absent is also equivalent to FALSE) at the client's - option. - - \sa RFC 2891. -*/ -#define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" -#define LDB_CONTROL_SERVER_SORT_NAME "server_sort" - -/** - OID for LDAP server sort result response extension. - - This control is included in the searchResultDone message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa RFC 2891. -*/ -#define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" -#define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" - -/** - OID for LDAP Attribute Scoped Query extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" -#define LDB_CONTROL_ASQ_NAME "asq" - -/** - OID for LDAP Directory Sync extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" -#define LDB_CONTROL_DIRSYNC_NAME "dirsync" - - -/** - OID for LDAP Virtual List View Request extension. - - This control is included in SearchRequest messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" -#define LDB_CONTROL_VLV_REQ_NAME "vlv" - -/** - OID for LDAP Virtual List View Response extension. - - This control is included in SearchResponse messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" -#define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" - -/** - OID to let modifies don't give an error when adding an existing - attribute with the same value or deleting an nonexisting one attribute - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" -#define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" - -/** - OID to allow the server to be more 'fast and loose' with the data being added. - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" - -/** - Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" -#define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" - -/* Other standardised controls */ - -/** - OID for the allowing client to request temporary relaxed - enforcement of constraints of the x.500 model. - - Mainly used for the OpenLDAP backend. - - \sa draft managedit. -*/ -#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" -#define LDB_CONTROL_RELAX_NAME "relax" - -/* Extended operations */ - -/** - OID for LDAP Extended Operation SEQUENCE_NUMBER - - This extended operation is used to retrieve the extended sequence number. -*/ -#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" - -/** - OID for LDAP Extended Operation PASSWORD_CHANGE. - - This Extended operation is used to allow user password changes by the user - itself. -*/ -#define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" - - -/** - OID for LDAP Extended Operation FAST_BIND - - This Extended operations is used to perform a fast bind. -*/ -#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" - -/** - OID for LDAP Extended Operation START_TLS. - - This Extended operation is used to start a new TLS channel on top of a clear - text channel. -*/ -#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" - -/** - OID for LDAP Extended Operation DYNAMIC_REFRESH. - - This Extended operation is used to create and maintain objects which exist - only a specific time, e.g. when a certain client or a certain person is - logged in. Data refreshes have to be periodically sent in a specific - interval. Otherwise the entry is going to be removed. -*/ -#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" - -struct ldb_sd_flags_control { - /* - * request the owner 0x00000001 - * request the group 0x00000002 - * request the DACL 0x00000004 - * request the SACL 0x00000008 - */ - unsigned secinfo_flags; -}; - -/* - * DOMAIN_SCOPE 0x00000001 - * this limits the search to one partition, - * and no referrals will be returned. - * (Note this doesn't limit the entries by there - * objectSid belonging to a domain! Builtin and Foreign Sids - * are still returned) - * - * PHANTOM_ROOT 0x00000002 - * this search on the whole tree on a domain controller - * over multiple partitions without referrals. - * (This is the default behavior on the Global Catalog Port) - */ - -#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001 -#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002 - -struct ldb_search_options_control { - unsigned search_options; -}; - -struct ldb_paged_control { - int size; - int cookie_len; - char *cookie; -}; - -struct ldb_extended_dn_control { - int type; -}; - -struct ldb_server_sort_control { - const char *attributeName; - const char *orderingRule; - int reverse; -}; - -struct ldb_sort_resp_control { - int result; - char *attr_desc; -}; - -struct ldb_asq_control { - int request; - char *source_attribute; - int src_attr_len; - int result; -}; - -struct ldb_dirsync_control { - int flags; - int max_attributes; - int cookie_len; - char *cookie; -}; - -struct ldb_vlv_req_control { - int beforeCount; - int afterCount; - int type; - union { - struct { - int offset; - int contentCount; - } byOffset; - struct { - int value_len; - char *value; - } gtOrEq; - } match; - int ctxid_len; - char *contextId; -}; - -struct ldb_vlv_resp_control { - int targetPosition; - int contentCount; - int vlv_result; - int ctxid_len; - char *contextId; -}; - -struct ldb_control { - const char *oid; - int critical; - void *data; -}; - -enum ldb_request_type { - LDB_SEARCH, - LDB_ADD, - LDB_MODIFY, - LDB_DELETE, - LDB_RENAME, - LDB_EXTENDED, - LDB_REQ_REGISTER_CONTROL, - LDB_REQ_REGISTER_PARTITION -}; - -enum ldb_reply_type { - LDB_REPLY_ENTRY, - LDB_REPLY_REFERRAL, - LDB_REPLY_DONE -}; - -enum ldb_wait_type { - LDB_WAIT_ALL, - LDB_WAIT_NONE -}; - -enum ldb_state { - LDB_ASYNC_INIT, - LDB_ASYNC_PENDING, - LDB_ASYNC_DONE -}; - -struct ldb_extended { - const char *oid; - void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ -}; - -enum ldb_sequence_type { - LDB_SEQ_HIGHEST_SEQ, - LDB_SEQ_HIGHEST_TIMESTAMP, - LDB_SEQ_NEXT -}; - -#define LDB_SEQ_GLOBAL_SEQUENCE 0x01 -#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 - -struct ldb_seqnum_request { - enum ldb_sequence_type type; -}; - -struct ldb_seqnum_result { - uint64_t seq_num; - uint32_t flags; -}; - -struct ldb_result { - unsigned int count; - struct ldb_message **msgs; - struct ldb_extended *extended; - struct ldb_control **controls; - char **refs; -}; - -struct ldb_reply { - int error; - enum ldb_reply_type type; - struct ldb_message *message; - struct ldb_extended *response; - struct ldb_control **controls; - char *referral; -}; - -struct ldb_request; -struct ldb_handle; - -struct ldb_search { - struct ldb_dn *base; - enum ldb_scope scope; - struct ldb_parse_tree *tree; - const char * const *attrs; - struct ldb_result *res; -}; - -struct ldb_add { - const struct ldb_message *message; -}; - -struct ldb_modify { - const struct ldb_message *message; -}; - -struct ldb_delete { - struct ldb_dn *dn; -}; - -struct ldb_rename { - struct ldb_dn *olddn; - struct ldb_dn *newdn; -}; - -struct ldb_register_control { - const char *oid; -}; - -struct ldb_register_partition { - struct ldb_dn *dn; -}; - -typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *); - -struct ldb_request { - - enum ldb_request_type operation; - - union { - struct ldb_search search; - struct ldb_add add; - struct ldb_modify mod; - struct ldb_delete del; - struct ldb_rename rename; - struct ldb_extended extended; - struct ldb_register_control reg_control; - struct ldb_register_partition reg_partition; - } op; - - struct ldb_control **controls; - - void *context; - ldb_request_callback_t callback; - - int timeout; - time_t starttime; - struct ldb_handle *handle; -}; - -int ldb_request(struct ldb_context *ldb, struct ldb_request *request); -int ldb_request_done(struct ldb_request *req, int status); -bool ldb_request_is_done(struct ldb_request *req); - -int ldb_modules_wait(struct ldb_handle *handle); -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); - -int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); -void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); -struct tevent_context; -void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev); -struct tevent_context * ldb_get_event_context(struct ldb_context *ldb); - -/** - Initialise ldbs' global information - - This is required before any other LDB call - - \return 0 if initialisation succeeded, -1 otherwise -*/ -int ldb_global_init(void); - -/** - Initialise an ldb context - - This is required before any other LDB call. - - \param mem_ctx pointer to a talloc memory context. Pass NULL if there is - no suitable context available. - - \return pointer to ldb_context that should be free'd (using talloc_free()) - at the end of the program. -*/ -struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); - -/** - Connect to a database. - - This is typically called soon after ldb_init(), and is required prior to - any search or database modification operations. - - The URL can be one of the following forms: - - tdb://path - - ldapi://path - - ldap://host - - sqlite://path - - \param ldb the context associated with the database (from ldb_init()) - \param url the URL of the database to connect to, as noted above - \param flags a combination of LDB_FLG_* to modify the connection behaviour - \param options backend specific options - passed uninterpreted to the backend - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note It is an error to connect to a database that does not exist in readonly mode - (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[]); - -/* - return an automatic basedn from the rootDomainNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb); - -/* - return an automatic basedn from the configurationNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb); - -/* - return an automatic basedn from the schemaNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb); - -/* - return an automatic baseDN from the defaultNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); - -/** - The default async search callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note this function expects req->context to always be an struct ldb_result pointer - AND a talloc context, this function will steal on the context each message - from the ares reply passed on by the async core so that in the end all the - messages will be in the context (ldb_result) memory tree. - Freeing the passed context (ldb_result tree) will free all the resources - (the request need to be freed separately and the result doe not depend on the - request that can be freed as sson as the search request is finished) -*/ - -int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -/** - The default async extended operation callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -/** - Helper function to build a search request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param expression the search expression to use for this query - \param attrs the search attributes for the query (pass NULL if none required) - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -int ldb_build_search_req_ex(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build an add request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param message contains the entry to be added - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a modify request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param message contains the entry to be modified - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a delete request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param dn the DN to be deleted - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a rename request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param olddn the old DN - \param newdn the new DN - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Add a ldb_control to a ldb_request - - \param req the request struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data); - -/** - replace a ldb_control in a ldb_request - - \param req the request struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); - -/** - check if a control with the specified "oid" exist and return it - \param req the request struct where to add the control - \param oid the object identifier of the control as string - - \return the control, NULL if not found -*/ -struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); - -/** - check if a control with the specified "oid" exist and return it - \param rep the reply struct where to add the control - \param oid the object identifier of the control as string - - \return the control, NULL if not found -*/ -struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); - -/** - Search the database - - This function searches the database, and returns - records that match an LDAP-like search expression - - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx the memory context to use for the request and the results - \param result the return result - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param attrs the search attributes for the query (pass NULL if none required) - \param exp_fmt the search expression to use for this query (printf like) - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note use talloc_free() to free the ldb_result returned -*/ -int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); - -/** - Add a record to the database. - - This function adds a record to the database. This function will fail - if a record with the specified class and key already exists in the - database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the record to add. - - \return result code (LDB_SUCCESS if the record was added, otherwise - a failure code) -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Modify the specified attributes of a record - - This function modifies a record that is in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the changes required. - - \return result code (LDB_SUCCESS if the record was modified as - requested, otherwise a failure code) -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Rename a record in the database - - This function renames a record in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param olddn the DN for the record to be renamed. - \param newdn the new DN - - \return result code (LDB_SUCCESS if the record was renamed as - requested, otherwise a failure code) -*/ -int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn); - -/** - Delete a record from the database - - This function deletes a record from the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param dn the DN for the record to be deleted. - - \return result code (LDB_SUCCESS if the record was deleted, - otherwise a failure code) -*/ -int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn); - -/** - The default async extended operation callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note this function expects req->context to always be an struct ldb_result pointer - AND a talloc context, this function will steal on the context each message - from the ares reply passed on by the async core so that in the end all the - messages will be in the context (ldb_result) memory tree. - Freeing the passed context (ldb_result tree) will free all the resources - (the request need to be freed separately and the result doe not depend on the - request that can be freed as sson as the search request is finished) -*/ - -int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares); - - -/** - Helper function to build a extended request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param oid the OID of the extended operation. - \param data a void pointer a the extended operation specific parameters, - it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_build_extended_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *oid, - void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - call an extended operation - - This function deletes a record from the database. - - \param ldb the context associated with the database (from ldb_init()) - \param oid the OID of the extended operation. - \param data a void pointer a the extended operation specific parameters, - it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it - \param res the result of the extended operation - - \return result code (LDB_SUCCESS if the extended operation returned fine, - otherwise a failure code) -*/ -int ldb_extended(struct ldb_context *ldb, - const char *oid, - void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ - struct ldb_result **res); - -/** - Obtain current/next database sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); - -/** - start a transaction -*/ -int ldb_transaction_start(struct ldb_context *ldb); - -/** - first phase of two phase commit - */ -int ldb_transaction_prepare_commit(struct ldb_context *ldb); - -/** - commit a transaction -*/ -int ldb_transaction_commit(struct ldb_context *ldb); - -/** - cancel a transaction -*/ -int ldb_transaction_cancel(struct ldb_context *ldb); - -/* - cancel a transaction with no error if no transaction is pending - used when we fork() to clear any parent transactions -*/ -int ldb_transaction_cancel_noerr(struct ldb_context *ldb); - - -/** - return extended error information from the last call -*/ -const char *ldb_errstring(struct ldb_context *ldb); - -/** - return a string explaining what a ldb error constant meancs -*/ -const char *ldb_strerror(int ldb_err); - -/** - setup the default utf8 functions - FIXME: these functions do not yet handle utf8 -*/ -void ldb_set_utf8_default(struct ldb_context *ldb); - -/** - Casefold a string - - \param ldb the ldb context - \param mem_ctx the memory context to allocate the result string - memory from. - \param s the string that is to be folded - \return a copy of the string, converted to upper case - - \note The default function is not yet UTF8 aware. Provide your own - set of functions through ldb_set_utf8_fns() -*/ -char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n); - -/** - Check the attribute name is valid according to rfc2251 - \param s the string to check - - \return 1 if the name is ok -*/ -int ldb_valid_attr_name(const char *s); - -/* - ldif manipulation functions -*/ - -/** - Write an LDIF message - - This function writes an LDIF message using a caller supplied write - function. - - \param ldb the ldb context (from ldb_init()) - \param fprintf_fn a function pointer for the write function. This must take - a private data pointer, followed by a format string, and then a variable argument - list. - \param private_data pointer that will be provided back to the write - function. This is useful for maintaining state or context. - \param ldif the message to write out - - \return the total number of bytes written, or an error code as returned - from the write function. - - \sa ldb_ldif_write_file for a more convenient way to write to a - file stream. - - \sa ldb_ldif_read for the reader equivalent to this function. -*/ -int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), - void *private_data, - const struct ldb_ldif *ldif); - -/** - Clean up an LDIF message - - This function cleans up a LDIF message read using ldb_ldif_read() - or related functions (such as ldb_ldif_read_string() and - ldb_ldif_read_file(). - - \param ldb the ldb context (from ldb_init()) - \param msg the message to clean up and free - -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); - -/** - Read an LDIF message - - This function creates an LDIF message using a caller supplied read - function. - - \param ldb the ldb context (from ldb_init()) - \param fgetc_fn a function pointer for the read function. This must - take a private data pointer, and must return a pointer to an - integer corresponding to the next byte read (or EOF if there is no - more data to be read). - \param private_data pointer that will be provided back to the read - function. This is udeful for maintaining state or context. - - \return the LDIF message that has been read in - - \note You must free the LDIF message when no longer required, using - ldb_ldif_read_free(). - - \sa ldb_ldif_read_file for a more convenient way to read from a - file stream. - - \sa ldb_ldif_read_string for a more convenient way to read from a - string (char array). - - \sa ldb_ldif_write for the writer equivalent to this function. -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data); - -/** - Read an LDIF message from a file - - This function reads the next LDIF message from the contents of a - file stream. If you want to get all of the LDIF messages, you will - need to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to read from (typically from fdopen()) - - \sa ldb_ldif_read_string for an equivalent function that will read - from a string (char array). - - \sa ldb_ldif_write_file for the writer equivalent to this function. - -*/ -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); - -/** - Read an LDIF message from a string - - This function reads the next LDIF message from the contents of a char - array. If you want to get all of the LDIF messages, you will need - to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param s pointer to the char array to read from - - \sa ldb_ldif_read_file for an equivalent function that will read - from a file stream. - - \sa ldb_ldif_write for a more general (arbitrary read function) - version of this function. -*/ -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); - -/** - Parse a modrdn LDIF message from a struct ldb_message - - \param ldb the ldb context (from ldb_init()) - \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) - - \param mem_ctx the memory context that's used for return values - - \param olddn the old dn as struct ldb_dn, if not needed pass NULL - \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL - \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL - \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL - *newsuperior can be NULL as it is optional in the LDIF - \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL - -*/ -int ldb_ldif_parse_modrdn(struct ldb_context *ldb, - const struct ldb_ldif *ldif, - TALLOC_CTX *mem_ctx, - struct ldb_dn **olddn, - struct ldb_dn **newrdn, - bool *deleteoldrdn, - struct ldb_dn **newsuperior, - struct ldb_dn **newdn); - -/** - Write an LDIF message to a file - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to write to (typically from fdopen()) - \param msg the message to write out - - \return the total number of bytes written, or a negative error code - - \sa ldb_ldif_read_file for the reader equivalent to this function. -*/ -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); - -/** - Write an LDIF message to a string - - \param ldb the ldb context (from ldb_init()) - \param mem_ctx the talloc context on which to attach the string) - \param msg the message to write out - - \return the string containing the LDIF, or NULL on error - - \sa ldb_ldif_read_string for the reader equivalent to this function. -*/ -char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *msg); - - -/* - Produce a string form of an ldb message - - convenient function to turn a ldb_message into a string. Useful for - debugging - */ -char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg); - - -/** - Base64 encode a buffer - - \param mem_ctx the memory context that the result is allocated - from. - \param buf pointer to the array that is to be encoded - \param len the number of elements in the array to be encoded - - \return pointer to an array containing the encoded data - - \note The caller is responsible for freeing the result -*/ -char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len); - -/** - Base64 decode a buffer - - This function decodes a base64 encoded string in place. - - \param s the string to decode. - - \return the length of the returned (decoded) string. - - \note the string is null terminated, but the null terminator is not - included in the length. -*/ -int ldb_base64_decode(char *s); - -/* The following definitions come from lib/ldb/common/ldb_dn.c */ - -/** - Get the linear form of a DN (without any extended components) - - \param dn The DN to linearize -*/ - -const char *ldb_dn_get_linearized(struct ldb_dn *dn); - -/** - Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context - - \param dn The DN to linearize - \param mem_ctx TALLOC context to return result on -*/ - -char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); - -/** - Get the linear form of a DN (with any extended components) - - \param mem_ctx TALLOC context to return result on - \param dn The DN to linearize - \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) -*/ -char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); -const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); -int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); -void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); -void ldb_dn_remove_extended_components(struct ldb_dn *dn); -bool ldb_dn_has_extended(struct ldb_dn *dn); - -int ldb_dn_extended_add_syntax(struct ldb_context *ldb, - unsigned flags, - const struct ldb_dn_extended_syntax *syntax); - -/** - Allocate a new DN from a string - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param dn The new DN - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); -/** - Allocate a new DN from a printf style format string and arguments - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param new_fms The new DN as a format string (plus arguments) - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); -/** - Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param dn The new DN - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); - -/** - Determine if this DN is syntactically valid - - \param dn The DN to validate -*/ - -bool ldb_dn_validate(struct ldb_dn *dn); - -char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); -const char *ldb_dn_get_casefold(struct ldb_dn *dn); -char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); - -int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); -int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); - -bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base); -bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) PRINTF_ATTRIBUTE(2,3); -bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child); -bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_ATTRIBUTE(2,3); -bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num); -bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num); - -struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -int ldb_dn_get_comp_num(struct ldb_dn *dn); -int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); -const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); -const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); -const char *ldb_dn_get_rdn_name(struct ldb_dn *dn); -const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn); -int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); - -bool ldb_dn_is_valid(struct ldb_dn *dn); -bool ldb_dn_is_special(struct ldb_dn *dn); -bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); -bool ldb_dn_is_null(struct ldb_dn *dn); -int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); - - -/** - Compare two attributes - - This function compares to attribute names. Note that this is a - case-insensitive comparison. - - \param a the first attribute name to compare - \param b the second attribute name to compare - - \return 0 if the attribute names are the same, or only differ in - case; non-zero if there are any differences - - attribute names are restricted by rfc2251 so using - strcasecmp and toupper here is ok. - return 0 for match -*/ -#define ldb_attr_cmp(a, b) strcasecmp(a, b) -char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s); -int ldb_attr_dn(const char *attr); - -/** - Create an empty message - - \param mem_ctx the memory context to create in. You can pass NULL - to get the top level context, however the ldb context (from - ldb_init()) may be a better choice -*/ -struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx); - -/** - Find an element within an message -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name); - -/** - Compare two ldb_val values - - \param v1 first ldb_val structure to be tested - \param v2 second ldb_val structure to be tested - - \return 1 for a match, 0 if there is any difference -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); - -/** - find a value within an ldb_message_element - - \param el the element to search - \param val the value to search for - - \note This search is case sensitive -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val); - -/** - add a new empty element to a ldb_message -*/ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el); - -/** - add a element to a ldb_message -*/ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags); -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el); -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val); -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str); -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str); -int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn); -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -/** - compare two message elements - return 0 on match -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2); -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2); - -/** - Find elements in a message. - - This function finds elements and converts to a specific type, with - a give default value if not found. Assumes that elements are - single valued. -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value); -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value); -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value); -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value); -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value); -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value); -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value); - -struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char *attr_name); - -void ldb_msg_sort_elements(struct ldb_message *msg); - -struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg); -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg); - -/* - * ldb_msg_canonicalize() is now depreciated - * Please use ldb_msg_normalize() instead - * - * NOTE: Returned ldb_message object is allocated - * into *ldb's context. Callers are recommended - * to steal the returned object into a TALLOC_CTX - * with short lifetime. - */ -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg) _DEPRECATED_; - -int ldb_msg_normalize(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - struct ldb_message **_msg_out); - - -/* - * ldb_msg_diff() is now depreciated - * Please use ldb_msg_difference() instead - * - * NOTE: Returned ldb_message object is allocated - * into *ldb's context. Callers are recommended - * to steal the returned object into a TALLOC_CTX - * with short lifetime. - */ -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) _DEPRECATED_; - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call, - * it can be used to save edits to a message - * - * Result message is constructed as follows: - * - LDB_FLAG_MOD_ADD - elements found only in msg2 - * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have - * different value in msg1 - * Value for msg2 element is used - * - LDB_FLAG_MOD_DELETE - elements found only in msg2 - * - * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR - */ -int ldb_msg_difference(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_message **_msg_out); - -/** - Tries to find a certain string attribute in a message - - \param msg the message to check - \param name attribute name - \param value attribute value - - \return 1 on match and 0 otherwise. -*/ -int ldb_msg_check_string_attribute(const struct ldb_message *msg, - const char *name, - const char *value); - -/** - Integrity check an ldb_message - - This function performs basic sanity / integrity checks on an - ldb_message. - - \param ldb context in which to perform the checks - \param msg the message to check - - \return LDB_SUCCESS if the message is OK, or a non-zero error code - (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or - LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a - message. -*/ -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg); - -/** - Duplicate an ldb_val structure - - This function copies an ldb value structure. - - \param mem_ctx the memory context that the duplicated value will be - allocated from - \param v the ldb_val to be duplicated. - - \return the duplicated ldb_val structure. -*/ -struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v); - -/** - this allows the user to set a debug function for error reporting -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), - void *context); - -/** - this allows the user to set custom utf8 function for error reporting -*/ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *, size_t n)); - -/** - this sets up debug to print messages on stderr -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb); - -/* control backend specific opaque values */ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); -void *ldb_get_opaque(struct ldb_context *ldb, const char *name); - -const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs); -const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr); -int ldb_attr_in_list(const char * const *attrs, const char *attr); - -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); - - -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace); - -/* - shallow copy a tree - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_parse_tree *ot); - -/** - Convert a time structure to a string - - This function converts a time_t structure to an LDAP formatted - GeneralizedTime string. - - \param mem_ctx the memory context to allocate the return string in - \param t the time structure to convert - - \return the formatted string, or NULL if the time structure could - not be converted -*/ -char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t); - -/** - Convert a string to a time structure - - This function converts an LDAP formatted GeneralizedTime string - to a time_t structure. - - \param s the string to convert - - \return the time structure, or 0 if the string cannot be converted -*/ -time_t ldb_string_to_time(const char *s); - -/** - convert a LDAP GeneralizedTime string in ldb_val format to a - time_t. -*/ -int ldb_val_to_time(const struct ldb_val *v, time_t *t); - -/** - Convert a time structure to a string - - This function converts a time_t structure to an LDAP formatted - UTCTime string. - - \param mem_ctx the memory context to allocate the return string in - \param t the time structure to convert - - \return the formatted string, or NULL if the time structure could - not be converted -*/ -char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t); - -/** - Convert a string to a time structure - - This function converts an LDAP formatted UTCTime string - to a time_t structure. - - \param s the string to convert - - \return the time structure, or 0 if the string cannot be converted -*/ -time_t ldb_string_utc_to_time(const char *s); - - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); - -#ifndef discard_const -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) -#endif - -/* - a wrapper around ldb_qsort() that ensures the comparison function is - type safe. This will produce a compilation warning if the types - don't match - */ -#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ -do { \ - if (numel > 1) { \ - ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ - comparison(&((base)[0]), &((base)[1]), opaque); \ - } \ -} while (0) - -/* allow ldb to also call TYPESAFE_QSORT() */ -#ifndef TYPESAFE_QSORT -#define TYPESAFE_QSORT(base, numel, comparison) \ -do { \ - if (numel > 1) { \ - qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ - comparison(&((base)[0]), &((base)[1])); \ - } \ -} while (0) -#endif - - - -/** - Convert a control into its string representation. - - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control A struct ldb_control to convert - - \return string representation of the control -*/ -char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); -/** - Convert a string representing a control into a ldb_control structure - - \param ldb LDB context - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control_strings A string-formatted control - - \return a ldb_control element -*/ -struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); -/** - Convert an array of string represention of a control into an array of ldb_control structures - - \param ldb LDB context - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control_strings Array of string-formatted controls - - \return array of ldb_control elements -*/ -struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings); - -/** - return the ldb flags -*/ -unsigned int ldb_get_flags(struct ldb_context *ldb); - -/* set the ldb flags */ -void ldb_set_flags(struct ldb_context *ldb, unsigned flags); - - -struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const struct ldb_val *strdn); - -int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); -int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); - -/* debugging functions for ldb requests */ -void ldb_req_set_location(struct ldb_request *req, const char *location); -const char *ldb_req_location(struct ldb_request *req); - -/* set the location marker on a request handle - used for debugging */ -#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) - -/* - minimise a DN. The caller must pass in a validated DN. - - If the DN has an extended component then only the first extended - component is kept, the DN string is stripped. - - The existing dn is modified - */ -bool ldb_dn_minimise(struct ldb_dn *dn); - -#endif diff --git a/source4/lib/ldb/include/ldb_errors.h b/source4/lib/ldb/include/ldb_errors.h deleted file mode 100644 index b247fbe09c4..00000000000 --- a/source4/lib/ldb/include/ldb_errors.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** 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 header - * - * Description: defines error codes following RFC 2251 ldap error codes - * - * Author: Simo Sorce - */ - -#ifndef _LDB_ERRORS_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_ERRORS_H_ 1 -/*! \endcond */ - -/** - \file ldb_errors.h - - This header provides a set of result codes for LDB function calls. - - Many LDB function calls return an integer value (int). As shown in - the function documentation, those return values may indicate - whether the function call worked correctly (in which case it - returns LDB_SUCCESS) or some problem occurred (in which case some - other value will be returned). As a special case, - LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, - which does not indicate an error. - - \note Not all error codes make sense for LDB, however they are - based on the LDAP error codes, and are kept for reference and to - avoid overlap. - - \note Some of this documentation is based on information in - the OpenLDAP documentation, as developed and maintained by the - The OpenLDAP Project. - */ - -/** - The function call succeeded. - - If a function returns LDB_SUCCESS, then that function, and the - underlying transactions that may have been required, completed - successfully. -*/ -#define LDB_SUCCESS 0 - -/** - The function call failed for some non-specific reason. -*/ -#define LDB_ERR_OPERATIONS_ERROR 1 - -/** - The function call failed because of a protocol violation. -*/ -#define LDB_ERR_PROTOCOL_ERROR 2 - -/** - The function call failed because a time limit was exceeded. -*/ -#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 - -/** - The function call failed because a size limit was exceeded. -*/ -#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 - -/** - The function was for value comparison, and the comparison operation - returned false. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_FALSE 5 - -/** - The function was for value comparison, and the comparison operation - returned true. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_TRUE 6 - -/** - The function used an authentication method that is not supported by - the database. -*/ -#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 - -/** - The function call required a underlying operation that required - strong authentication. - - This will normally only occur if you are using LDB with a LDAP - backend. -*/ -#define LDB_ERR_STRONG_AUTH_REQUIRED 8 - -/* 9 RESERVED */ - -/** - The function resulted in a referral to another server. -*/ -#define LDB_ERR_REFERRAL 10 - -/** - The function failed because an administrative / policy limit was - exceeded. -*/ -#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 - -/** - The function required an extension or capability that the - database cannot provide. -*/ -#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 - -/** - The function involved a transaction or database operation that - could not be performed without a secure link. -*/ -#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 - -/** - This is an intermediate result code for SASL bind operations that - have more than one step. - - \note This is a result code that does not normally indicate an - error has occurred. -*/ -#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 - -/** - The function referred to an attribute type that is not present in - the entry. -*/ -#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 - -/** - The function referred to an attribute type that is invalid -*/ -#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 - -/** - The function required a filter type that is not available for the - specified attribute. -*/ -#define LDB_ERR_INAPPROPRIATE_MATCHING 18 - -/** - The function would have violated an attribute constraint. -*/ -#define LDB_ERR_CONSTRAINT_VIOLATION 19 - -/** - The function involved an attribute type or attribute value that - already exists in the entry. -*/ -#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 - -/** - The function used an invalid (incorrect syntax) attribute value. -*/ -#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 - -/* 22-31 unused */ - -/** - The function referred to an object that does not exist in the - database. -*/ -#define LDB_ERR_NO_SUCH_OBJECT 32 - -/** - The function referred to an alias which points to a non-existent - object in the database. -*/ -#define LDB_ERR_ALIAS_PROBLEM 33 - -/** - The function used a DN which was invalid (incorrect syntax). -*/ -#define LDB_ERR_INVALID_DN_SYNTAX 34 - -/* 35 RESERVED */ - -/** - The function required dereferencing of an alias, and something went - wrong during the dereferencing process. -*/ -#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 - -/* 37-47 unused */ - -/** - The function passed in the wrong authentication method. -*/ -#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 - -/** - The function passed in or referenced incorrect credentials during - authentication. -*/ -#define LDB_ERR_INVALID_CREDENTIALS 49 - -/** - The function required access permissions that the user does not - possess. -*/ -#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 - -/** - The function required a transaction or call that the database could - not perform because it is busy. -*/ -#define LDB_ERR_BUSY 51 - -/** - The function required a transaction or call to a database that is - not available. -*/ -#define LDB_ERR_UNAVAILABLE 52 - -/** - The function required a transaction or call to a database that the - database declined to perform. -*/ -#define LDB_ERR_UNWILLING_TO_PERFORM 53 - -/** - The function failed because it resulted in a loop being detected. -*/ -#define LDB_ERR_LOOP_DETECT 54 - -/* 55-63 unused */ - -/** - The function failed because it would have violated a naming rule. -*/ -#define LDB_ERR_NAMING_VIOLATION 64 - -/** - The function failed because it would have violated the schema. -*/ -#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 - -/** - The function required an operation that is only allowed on leaf - objects, but the object is not a leaf. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 - -/** - The function required an operation that cannot be performed on a - Relative DN, but the object is a Relative DN. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 - -/** - The function failed because the entry already exists. -*/ -#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 - -/** - The function failed because modifications to an object class are - not allowable. -*/ -#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 - -/* 70 RESERVED FOR CLDAP */ - -/** - The function failed because it needed to be applied to multiple - databases. -*/ -#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 - -/* 72-79 unused */ - -/** - The function failed for unknown reasons. -*/ -#define LDB_ERR_OTHER 80 - -/* 81-90 RESERVED for APIs */ - -#endif /* _LDB_ERRORS_H_ */ diff --git a/source4/lib/ldb/include/ldb_handlers.h b/source4/lib/ldb/include/ldb_handlers.h deleted file mode 100644 index 6e71f1fa014..00000000000 --- a/source4/lib/ldb/include/ldb_handlers.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** 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 header - * - * Description: defines attribute handlers - * - * Author: Simo Sorce - */ - -int ldb_handler_copy( struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out); -int ldb_comparison_binary( struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2); -int ldb_comparison_fold( struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2); - diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h deleted file mode 100644 index 6d6fff251cd..00000000000 --- a/source4/lib/ldb/include/ldb_module.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2008 - - ** 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 module header - * - * Description: defines ldb modules structures and helpers - * - */ - -#ifndef _LDB_MODULE_H_ -#define _LDB_MODULE_H_ - -#include - -struct ldb_context; -struct ldb_module; - -/** - internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK - */ -#define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 - -/* disable any single value checking on this attribute */ -#define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 - -/* attribute has failed access check and must not be exposed */ -#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 - -/* force single value checking on this attribute */ -#define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 - - -/* - these function pointers define the operations that a ldb module can intercept -*/ -struct ldb_module_ops { - const char *name; - int (*init_context) (struct ldb_module *); - int (*search)(struct ldb_module *, struct ldb_request *); /* search */ - int (*add)(struct ldb_module *, struct ldb_request *); /* add */ - int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ - int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ - int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ - int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ - int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ - int (*start_transaction)(struct ldb_module *); - int (*prepare_commit)(struct ldb_module *); - int (*end_transaction)(struct ldb_module *); - int (*del_transaction)(struct ldb_module *); - int (*sequence_number)(struct ldb_module *, struct ldb_request *); - void *private_data; -}; - - -/* The following definitions come from lib/ldb/common/ldb_debug.c */ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); -void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); - -#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) - -#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") -#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) -#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") - -/* The following definitions come from lib/ldb/common/ldb.c */ - -void ldb_request_set_state(struct ldb_request *req, int state); -int ldb_request_get_status(struct ldb_request *req); - -unsigned int ldb_get_create_perms(struct ldb_context *ldb); - -const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, - const char *syntax); - -/* The following definitions come from lib/ldb/common/ldb_attributes.c */ - -int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, - const char *name, - unsigned flags, - const struct ldb_schema_syntax *syntax); -int ldb_schema_attribute_add(struct ldb_context *ldb, - const char *name, - unsigned flags, - const char *syntax); -void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name); - -/* we allow external code to override the name -> schema_attribute function */ -typedef const struct ldb_schema_attribute *(*ldb_attribute_handler_override_fn_t)(struct ldb_context *, void *, const char *); - -void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, - ldb_attribute_handler_override_fn_t override, - void *private_data); - -/* A useful function to build comparison functions with */ -int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, - ldb_attr_handler_t canonicalise_fn, - const struct ldb_val *v1, - const struct ldb_val *v2); - -/* The following definitions come from lib/ldb/common/ldb_controls.c */ -int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); -/* Returns a list of controls, except the one specified. Included - * controls become a child of returned list if they were children of - * controls_in */ -struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, - TALLOC_CTX *mem_ctx, - struct ldb_control *exclude); -int ldb_check_critical_controls(struct ldb_control **controls); - -/* The following definitions come from lib/ldb/common/ldb_ldif.c */ -int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val); - -/* The following definitions come from lib/ldb/common/ldb_match.c */ -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope); - -int ldb_match_msg_error(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope, - bool *matched); - -int ldb_match_msg_objectclass(const struct ldb_message *msg, - const char *objectclass); - -/* The following definitions come from lib/ldb/common/ldb_modules.c */ - -struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, - struct ldb_context *ldb, - const char *module_name, - const struct ldb_module_ops *ops); - -const char * ldb_module_get_name(struct ldb_module *module); -struct ldb_context *ldb_module_get_ctx(struct ldb_module *module); -void *ldb_module_get_private(struct ldb_module *module); -void ldb_module_set_private(struct ldb_module *module, void *private_data); -const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); - -int ldb_next_request(struct ldb_module *module, struct ldb_request *request); -int ldb_next_start_trans(struct ldb_module *module); -int ldb_next_end_trans(struct ldb_module *module); -int ldb_next_del_trans(struct ldb_module *module); -int ldb_next_prepare_commit(struct ldb_module *module); -int ldb_next_init(struct ldb_module *module); - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); -void ldb_reset_err_string(struct ldb_context *ldb); -int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); - -const char *ldb_default_modules_dir(void); - -int ldb_register_module(const struct ldb_module_ops *); - -typedef int (*ldb_connect_fn)(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **module); - -struct ldb_backend_ops { - const char *name; - ldb_connect_fn connect_fn; -}; - -const char *ldb_default_modules_dir(void); - -int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); - -struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); - -int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg, - struct ldb_control **ctrls); - -int ldb_module_send_referral(struct ldb_request *req, - char *ref); - -int ldb_module_done(struct ldb_request *req, - struct ldb_control **ctrls, - struct ldb_extended *response, - int error); - -int ldb_mod_register_control(struct ldb_module *module, const char *oid); - -void ldb_set_default_dns(struct ldb_context *ldb); -/** - Add a ldb_control to a ldb_reply - - \param ares the reply struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); - -/** - mark a request as untrusted. This tells the rootdse module to remove - unregistered controls - */ -void ldb_req_mark_untrusted(struct ldb_request *req); - -/** - mark a request as trusted. - */ -void ldb_req_mark_trusted(struct ldb_request *req); - -/** - return true is a request is untrusted - */ -bool ldb_req_is_untrusted(struct ldb_request *req); - -/** - set custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); - -/** - get custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -uint32_t ldb_req_get_custom_flags(struct ldb_request *req); - -/* load all modules from the given directory */ -int ldb_modules_load(const char *modules_path, const char *version); - -/* init functions prototype */ -typedef int (*ldb_module_init_fn)(const char *); - -/* - general ldb hook function - */ -enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, - LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, - LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; - -typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); - -/* - register a ldb hook function - */ -int ldb_register_hook(ldb_hook_fn hook_fn); - -/* - call ldb hooks of a given type - */ -int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); - -#define LDB_MODULE_CHECK_VERSION(version) do { \ - if (strcmp(version, LDB_VERSION) != 0) { \ - fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ - __FILE__, version, LDB_VERSION); \ - return LDB_ERR_UNAVAILABLE; \ - }} while (0) - - -/* - return a string representation of the calling chain for the given - ldb request - */ -char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); - -/* - return the next module in the chain - */ -struct ldb_module *ldb_module_next(struct ldb_module *module); - -/* - set the next module in the module chain - */ -void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); - -/* - load a list of modules - */ -int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, - struct ldb_module *backend, struct ldb_module **out); - -/* - get the popt_options pointer in the ldb structure. This allows a ldb - module to change the command line parsing - */ -struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); - -/* modules are called in inverse order on the stack. - Lets place them as an admin would think the right order is. - Modules order is important */ -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); - -/* - return the current ldb flags LDB_FLG_* - */ -uint32_t ldb_module_flags(struct ldb_context *ldb); - -int ldb_module_connect_backend(struct ldb_context *ldb, - const char *url, - const char *options[], - struct ldb_module **backend_module); - -/* - initialise a chain of modules - */ -int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); - -/* - * prototype for the init function defined by dynamically loaded modules - */ -int ldb_init_module(const char *version); - - -#endif diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h deleted file mode 100644 index cafc020e291..00000000000 --- a/source4/lib/ldb/include/ldb_private.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004-2005 - - ** 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 private header - * - * Description: defines internal ldb structures used by the subsystem and modules - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#ifndef _LDB_PRIVATE_H_ -#define _LDB_PRIVATE_H_ 1 - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "ldb_module.h" - -struct ldb_context; - -struct ldb_module_ops; - -struct ldb_backend_ops; - -#define LDB_HANDLE_FLAG_DONE_CALLED 1 -/* call is from an untrusted source - eg. over ldap:// */ -#define LDB_HANDLE_FLAG_UNTRUSTED 2 - -struct ldb_handle { - int status; - enum ldb_state state; - struct ldb_context *ldb; - unsigned flags; - /* flags dedicated to be set by application using ldb */ - uint32_t custom_flags; - unsigned nesting; - - /* used for debugging */ - struct ldb_request *parent; - const char *location; -}; - -/* basic module structure */ -struct ldb_module { - struct ldb_module *prev, *next; - struct ldb_context *ldb; - void *private_data; - const struct ldb_module_ops *ops; -}; - -/* - schema related information needed for matching rules -*/ -struct ldb_schema { - void *attribute_handler_override_private; - ldb_attribute_handler_override_fn_t attribute_handler_override; - - /* attribute handling table */ - unsigned num_attributes; - struct ldb_schema_attribute *attributes; - - unsigned num_dn_extended_syntax; - struct ldb_dn_extended_syntax *dn_extended_syntax; -}; - -/* - every ldb connection is started by establishing a ldb_context -*/ -struct ldb_context { - /* the operations provided by the backend */ - struct ldb_module *modules; - - /* debugging operations */ - struct ldb_debug_ops debug_ops; - - /* custom utf8 functions */ - struct ldb_utf8_fns utf8_fns; - - /* backend specific opaque parameters */ - struct ldb_opaque { - struct ldb_opaque *next; - const char *name; - void *value; - } *opaque; - - struct ldb_schema schema; - - char *err_string; - - int transaction_active; - - int default_timeout; - - unsigned int flags; - - unsigned int create_perms; - - struct tevent_context *ev_ctx; - - bool prepare_commit_done; - - char *partial_debug; - - struct poptOption *popt_options; -}; - -/* The following definitions come from lib/ldb/common/ldb.c */ - -extern const struct ldb_module_ops ldb_objectclass_module_ops; -extern const struct ldb_module_ops ldb_paged_results_module_ops; -extern const struct ldb_module_ops ldb_rdn_name_module_ops; -extern const struct ldb_module_ops ldb_schema_module_ops; -extern const struct ldb_module_ops ldb_asq_module_ops; -extern const struct ldb_module_ops ldb_server_sort_module_ops; -extern const struct ldb_module_ops ldb_ldap_module_ops; -extern const struct ldb_module_ops ldb_ildap_module_ops; -extern const struct ldb_module_ops ldb_paged_searches_module_ops; -extern const struct ldb_module_ops ldb_tdb_module_ops; -extern const struct ldb_module_ops ldb_skel_module_ops; -extern const struct ldb_module_ops ldb_subtree_rename_module_ops; -extern const struct ldb_module_ops ldb_subtree_delete_module_ops; -extern const struct ldb_module_ops ldb_sqlite3_module_ops; -extern const struct ldb_module_ops ldb_wins_ldb_module_ops; -extern const struct ldb_module_ops ldb_ranged_results_module_ops; - -extern const struct ldb_backend_ops ldb_tdb_backend_ops; -extern const struct ldb_backend_ops ldb_sqlite3_backend_ops; -extern const struct ldb_backend_ops ldb_ldap_backend_ops; -extern const struct ldb_backend_ops ldb_ldapi_backend_ops; -extern const struct ldb_backend_ops ldb_ldaps_backend_ops; - -int ldb_setup_wellknown_attributes(struct ldb_context *ldb); - -const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); -void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); -int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); - -/* The following definitions come from lib/ldb/common/ldb_utf8.c */ -char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); - -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); - - -/* The following definitions come from lib/ldb/common/ldb_modules.c */ - -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); -int ldb_load_modules(struct ldb_context *ldb, const char *options[]); - -struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); - - -/* The following definitions come from lib/ldb/common/ldb_options.c */ - -const char *ldb_options_find(struct ldb_context *ldb, const char *options[], - const char *option_name); - -#endif diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in deleted file mode 100644 index aeba17a6775..00000000000 --- a/source4/lib/ldb/ldb.pc.in +++ /dev/null @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -modulesdir=@LDB_MODULESDIR@ - -Name: ldb -Description: An LDAP-like embedded database -Version: @PACKAGE_VERSION@ -Requires.private: tdb -Requires: talloc -Libs: @LIB_RPATH@ -L${libdir} -lldb -Libs.private: @LDAP_LIBS@ -Cflags: -I${includedir} -Modulesdir: ${modulesdir} -URL: http://ldb.samba.org/ diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c deleted file mode 100644 index 7e6ac903c8a..00000000000 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Simo Sorce 2006 - - ** 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_ldap - * - * Component: ldb ldap backend - * - * Description: core files for LDAP backend - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" -#include "ldb_private.h" - -#define LDAP_DEPRECATED 1 -#include - -struct lldb_private { - LDAP *ldap; -}; - -struct lldb_context { - struct ldb_module *module; - struct ldb_request *req; - - struct lldb_private *lldb; - - struct ldb_control **controls; - int msgid; -}; - -static int lldb_ldap_to_ldb(int err) { - /* Ldap errors and ldb errors are defined to the same values */ - return err; -} - -/* - convert a ldb_message structure to a list of LDAPMod structures - ready for ldap_add() or ldap_modify() -*/ -static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) -{ - LDAPMod **mods; - unsigned int i, j; - int num_mods = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i=0;inum_elements;i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[num_mods] = talloc(mods, LDAPMod); - if (!mods[num_mods]) { - goto failed; - } - mods[num_mods+1] = NULL; - mods[num_mods]->mod_op = LDAP_MOD_BVALUES; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[num_mods]->mod_op |= LDAP_MOD_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[num_mods]->mod_op |= LDAP_MOD_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; - break; - } - } - mods[num_mods]->mod_type = discard_const_p(char, el->name); - mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], - struct berval *, - 1+el->num_values); - if (!mods[num_mods]->mod_vals.modv_bvals) { - goto failed; - } - - for (j=0;jnum_values;j++) { - mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, - struct berval); - if (!mods[num_mods]->mod_vals.modv_bvals[j]) { - goto failed; - } - mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; - mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; - } - mods[num_mods]->mod_vals.modv_bvals[j] = NULL; - num_mods++; - } - - return mods; - -failed: - talloc_free(mods); - return NULL; -} - -/* - add a single set of ldap message values to a ldb_message -*/ -static int lldb_add_msg_attr(struct ldb_context *ldb, - struct ldb_message *msg, - const char *attr, struct berval **bval) -{ - int count, i; - struct ldb_message_element *el; - - count = ldap_count_values_len(bval); - - if (count <= 0) { - return -1; - } - - el = talloc_realloc(msg, msg->elements, struct ldb_message_element, - msg->num_elements + 1); - if (!el) { - errno = ENOMEM; - return -1; - } - - msg->elements = el; - - el = &msg->elements[msg->num_elements]; - - el->name = talloc_strdup(msg->elements, attr); - if (!el->name) { - errno = ENOMEM; - return -1; - } - el->flags = 0; - - el->num_values = 0; - el->values = talloc_array(msg->elements, struct ldb_val, count); - if (!el->values) { - errno = ENOMEM; - return -1; - } - - for (i=0;ivalues[i].data = talloc_size(el->values, bval[i]->bv_len+1); - if (!el->values[i].data) { - errno = ENOMEM; - return -1; - } - memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); - el->values[i].data[bval[i]->bv_len] = 0; - el->values[i].length = bval[i]->bv_len; - el->num_values++; - } - - msg->num_elements++; - - return 0; -} - -/* - search for matching records -*/ -static int lldb_search(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - struct timeval tv; - int ldap_scope; - char *search_base; - char *expression; - int ret; - - ldb = ldb_module_get_ctx(module); - - if (!req->callback || !req->context) { - ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->controls != NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base); - if (req->op.search.base == NULL) { - search_base = talloc_strdup(lldb_ac, ""); - } - if (search_base == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree); - if (expression == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - switch (req->op.search.scope) { - case LDB_SCOPE_BASE: - ldap_scope = LDAP_SCOPE_BASE; - break; - case LDB_SCOPE_ONELEVEL: - ldap_scope = LDAP_SCOPE_ONELEVEL; - break; - default: - ldap_scope = LDAP_SCOPE_SUBTREE; - break; - } - - tv.tv_sec = req->timeout; - tv.tv_usec = 0; - - ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, - expression, - discard_const_p(char *, req->op.search.attrs), - 0, - NULL, - NULL, - &tv, - LDAP_NO_LIMIT, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - add a record -*/ -static int lldb_add(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - LDAPMod **mods; - char *dn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_add_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - modify a record -*/ -static int lldb_modify(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - LDAPMod **mods; - char *dn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_modify_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - delete a record -*/ -static int lldb_delete(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - char *dnstr; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn); - - ret = ldap_delete_ext(lldb->ldap, dnstr, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - rename a record -*/ -static int lldb_rename(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - const char *rdn_name; - const struct ldb_val *rdn_val; - char *old_dn; - char *newrdn; - char *parentdn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); - if (old_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); - rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); - - if ((rdn_name != NULL) && (rdn_val != NULL)) { - newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, - rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); - } else { - newrdn = talloc_strdup(lldb_ac, ""); - } - if (!newrdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); - if (!parentdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, - 1, NULL, NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -static int lldb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static void lldb_request_done(struct lldb_context *ac, - struct ldb_control **ctrls, int error) -{ - struct ldb_request *req; - struct ldb_reply *ares; - - req = ac->req; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb_module_get_ctx(ac->module)); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->error = error; - - req->callback(req, ares); -} - -/* return false if the request is still in progress - * return true if the request is completed - */ -static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = ac->lldb; - LDAPControl **serverctrlsp = NULL; - char **referralsp = NULL; - char *matcheddnp = NULL; - char *errmsgp = NULL; - LDAPMessage *msg; - int type; - struct ldb_message *ldbmsg; - char *referral; - bool callback_failed; - bool request_done; - bool lret; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - type = ldap_msgtype(result); - callback_failed = false; - request_done = false; - - switch (type) { - case LDAP_RES_SEARCH_ENTRY: - - msg = ldap_first_entry(lldb->ldap, result); - if (msg != NULL) { - BerElement *berptr = NULL; - char *attr, *dn; - - ldbmsg = ldb_msg_new(ac); - if (!ldbmsg) { - ldb_oom(ldb); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - dn = ldap_get_dn(lldb->ldap, msg); - if (!dn) { - ldb_oom(ldb); - talloc_free(ldbmsg); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); - if ( ! ldb_dn_validate(ldbmsg->dn)) { - ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); - talloc_free(ldbmsg); - ret = LDB_ERR_OPERATIONS_ERROR; - ldap_memfree(dn); - break; - } - ldap_memfree(dn); - - ldbmsg->num_elements = 0; - ldbmsg->elements = NULL; - - /* loop over all attributes */ - for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); - attr; - attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { - struct berval **bval; - bval = ldap_get_values_len(lldb->ldap, msg, attr); - - if (bval) { - lldb_add_msg_attr(ldb, ldbmsg, attr, bval); - ldap_value_free_len(bval); - } - } - if (berptr) ber_free(berptr, 0); - - ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "entry send failed: %s", - ldb_errstring(ldb)); - callback_failed = true; - } - } else { - ret = LDB_ERR_OPERATIONS_ERROR; - } - break; - - case LDAP_RES_SEARCH_REFERENCE: - - ret = ldap_parse_reference(lldb->ldap, result, - &referralsp, &serverctrlsp, 0); - if (ret != LDAP_SUCCESS) { - ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", - ldap_err2string(ret), errmsgp); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - if (referralsp == NULL) { - ldb_asprintf_errstring(ldb, "empty ldap referrals list"); - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - for (i = 0; referralsp[i]; i++) { - referral = talloc_strdup(ac, referralsp[i]); - - ret = ldb_module_send_referral(ac->req, referral); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "referral send failed: %s", - ldb_errstring(ldb)); - callback_failed = true; - break; - } - } - break; - - case LDAP_RES_SEARCH_RESULT: - case LDAP_RES_MODIFY: - case LDAP_RES_ADD: - case LDAP_RES_DELETE: - case LDAP_RES_MODDN: - - if (ldap_parse_result(lldb->ldap, result, &ret, - &matcheddnp, &errmsgp, - &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - } - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", - type, ldap_err2string(ret), errmsgp); - break; - } - - if (serverctrlsp != NULL) { - /* FIXME: transform the LDAPControl list into an ldb_control one */ - ac->controls = NULL; - } - - request_done = true; - break; - - default: - ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - - /* if the callback failed the caller will have freed the - * request. Just return and don't try to use it */ - if (callback_failed) { - - /* tell lldb_wait to remove the request from the - * queue */ - lret = true; - goto free_and_return; - } - - request_done = true; - } - - if (request_done) { - lldb_request_done(ac, ac->controls, ret); - lret = true; - goto free_and_return; - } - - lret = false; - -free_and_return: - - if (matcheddnp) ldap_memfree(matcheddnp); - if (errmsgp && *errmsgp) { - ldb_set_errstring(ldb, errmsgp); - } - if (errmsgp) { - ldap_memfree(errmsgp); - } - if (referralsp) ldap_value_free(referralsp); - if (serverctrlsp) ldap_controls_free(serverctrlsp); - - ldap_msgfree(result); - - return lret; -} - -static void lldb_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - ac = talloc_get_type(private_data, struct lldb_context); - - lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void lldb_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - struct tevent_timer *lte; - struct timeval tv; - LDAPMessage *result; - int lret; - - ac = talloc_get_type(private_data, struct lldb_context); - - if (!ac->msgid) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - return; - } - - tv.tv_sec = 0; - tv.tv_usec = 0; - lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result); - if (lret == 0) { - goto respin; - } - if (lret == -1) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - return; - } - - if ( ! lldb_parse_result(ac, result)) { - goto respin; - } - - return; - -respin: - tv.tv_sec = 0; - tv.tv_usec = 100; - lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac); - if (NULL == lte) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - } -} - -static bool lldb_dn_is_special(struct ldb_request *req) -{ - struct ldb_dn *dn = NULL; - - switch (req->operation) { - case LDB_ADD: - dn = req->op.add.message->dn; - break; - case LDB_MODIFY: - dn = req->op.mod.message->dn; - break; - case LDB_DELETE: - dn = req->op.del.dn; - break; - case LDB_RENAME: - dn = req->op.rename.olddn; - break; - default: - break; - } - - if (dn && ldb_dn_is_special(dn)) { - return true; - } - return false; -} - -static void lldb_auto_done_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - - ac = talloc_get_type(private_data, struct lldb_context); - lldb_request_done(ac, NULL, LDB_SUCCESS); -} - -static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct lldb_private *lldb; - struct lldb_context *ac; - struct tevent_context *ev; - struct tevent_timer *te; - struct timeval tv; - int ret; - - lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); - ldb = ldb_module_get_ctx(module); - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ev = ldb_get_event_context(ldb); - if (NULL == ev) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_zero(ldb, struct lldb_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->lldb = lldb; - ac->msgid = 0; - - if (lldb_dn_is_special(req)) { - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, - lldb_auto_done_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; - } - - switch (ac->req->operation) { - case LDB_SEARCH: - ret = lldb_search(ac); - break; - case LDB_ADD: - ret = lldb_add(ac); - break; - case LDB_MODIFY: - ret = lldb_modify(ac); - break; - case LDB_DELETE: - ret = lldb_delete(ac); - break; - case LDB_RENAME: - ret = lldb_rename(ac); - break; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - lldb_request_done(ac, NULL, ret); - return ret; - } - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lldb_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - - tv.tv_sec = req->starttime + req->timeout; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static const struct ldb_module_ops lldb_ops = { - .name = "ldap", - .search = lldb_handle_request, - .add = lldb_handle_request, - .modify = lldb_handle_request, - .del = lldb_handle_request, - .rename = lldb_handle_request, - .request = lldb_handle_request, - .start_transaction = lldb_start_trans, - .end_transaction = lldb_end_trans, - .del_transaction = lldb_del_trans, -}; - - -static int lldb_destructor(struct lldb_private *lldb) -{ - ldap_unbind(lldb->ldap); - return 0; -} - - -/* - optionally perform a bind - */ -static int lldb_bind(struct ldb_module *module, - const char *options[]) -{ - const char *bind_mechanism; - struct lldb_private *lldb; - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret; - - bind_mechanism = ldb_options_find(ldb, options, "bindMech"); - if (bind_mechanism == NULL) { - /* no bind wanted */ - return LDB_SUCCESS; - } - - lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); - - if (strcmp(bind_mechanism, "simple") == 0) { - const char *bind_id, *bind_secret; - - bind_id = ldb_options_find(ldb, options, "bindID"); - bind_secret = ldb_options_find(ldb, options, "bindSecret"); - if (bind_id == NULL || bind_secret == NULL) { - ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); - if (ret != LDAP_SUCCESS) { - ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); - return ret; - } - return LDB_SUCCESS; - } - - ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); - return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; -} - -/* - connect to the database -*/ -static int lldb_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct lldb_private *lldb; - int version = 3; - int ret; - - module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - lldb = talloc_zero(module, struct lldb_private); - if (!lldb) { - ldb_oom(ldb); - goto failed; - } - ldb_module_set_private(module, lldb); - - ret = ldap_initialize(&lldb->ldap, url); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", - url, ldap_err2string(ret)); - goto failed; - } - - talloc_set_destructor(lldb, lldb_destructor); - - ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", - ldap_err2string(ret)); - goto failed; - } - - *_module = module; - - ret = lldb_bind(module, options); - if (ret != LDB_SUCCESS) { - goto failed; - } - - - return LDB_SUCCESS; - -failed: - talloc_free(module); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - initialise the module - */ -int ldb_ldap_init(const char *version) -{ - int ret, i; - const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; - LDB_MODULE_CHECK_VERSION(version); - for (i=0; names[i]; i++) { - ret = ldb_register_backend(names[i], lldb_connect, false); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c deleted file mode 100644 index d35e5c604fc..00000000000 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Simo Sorce 2008 - - ** 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 ldb_map module - * - * Description: Map portions of data into a different format on a - * remote partition. - * - * Author: Jelmer Vernooij, Martin Kuehl - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - -/* Description of the provided ldb requests: - - special attribute 'isMapped' - - - search: - - if parse tree can be split - - search remote records w/ remote attrs and parse tree - - otherwise - - enumerate all remote records - - for each remote result - - map remote result to local message - - search local result - - is present - - merge local into remote result - - run callback on merged result - - otherwise - - run callback on remote result - - - add: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - add local message - - add remote message - - - modify: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - search for local record - - if present - - modify local record - - otherwise - - add local message - - modify remote record - - - delete: - - search for local record - - if present - - delete local record - - delete remote record - - - rename: - - search for local record - - if present - - rename local record - - modify local isMapped - - rename remote record -*/ - - - -/* Private data structures - * ======================= */ - -/* Global private data */ -/* Extract mappings from private data. */ -const struct ldb_map_context *map_get_context(struct ldb_module *module) -{ - const struct map_private *data = talloc_get_type(ldb_module_get_private(module), struct map_private); - return data->context; -} - -/* Create a generic request context. */ -struct map_context *map_init_context(struct ldb_module *module, - struct ldb_request *req) -{ - struct ldb_context *ldb; - struct map_context *ac; - - ldb = ldb_module_get_ctx(module); - - ac = talloc_zero(req, struct map_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return NULL; - } - - ac->module = module; - ac->req = req; - - return ac; -} - -/* Dealing with DNs for different partitions - * ========================================= */ - -/* Check whether any data should be stored in the local partition. */ -bool map_check_local_db(struct ldb_module *module) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->remote_base_dn || !data->local_base_dn) { - return false; - } - - return true; -} - -/* Copy a DN with the base DN of the local partition. */ -static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( ! ldb_dn_validate(new_dn)) { - talloc_free(new_dn); - return NULL; - } - - /* may be we don't need to rebase at all */ - if ( ! data->remote_base_dn || ! data->local_base_dn) { - return new_dn; - } - - if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) { - talloc_free(new_dn); - return NULL; - } - - if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Copy a DN with the base DN of the remote partition. */ -static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( ! ldb_dn_validate(new_dn)) { - talloc_free(new_dn); - return NULL; - } - - /* may be we don't need to rebase at all */ - if ( ! data->remote_base_dn || ! data->local_base_dn) { - return new_dn; - } - - if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) { - talloc_free(new_dn); - return NULL; - } - - if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Run a request and make sure it targets the remote partition. */ -/* TODO: free old DNs and messages? */ -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message *msg; - - ldb = ldb_module_get_ctx(module); - - switch (request->operation) { - case LDB_SEARCH: - if (request->op.search.base) { - request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); - } else { - request->op.search.base = data->remote_base_dn; - /* TODO: adjust scope? */ - } - break; - - case LDB_ADD: - msg = ldb_msg_copy_shallow(request, request->op.add.message); - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.add.message = msg; - break; - - case LDB_MODIFY: - msg = ldb_msg_copy_shallow(request, request->op.mod.message); - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.mod.message = msg; - break; - - case LDB_DELETE: - request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); - break; - - case LDB_RENAME: - request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); - request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); - break; - - default: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Invalid remote request!"); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, request); -} - - -/* Finding mappings for attributes and objectClasses - * ================================================= */ - -/* Find an objectClass mapping by the local name. */ -static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an objectClass mapping by the remote name. */ -static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the local name. */ -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { - return &data->attribute_maps[i]; - } - } - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { - return &data->attribute_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the remote name. */ -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) -{ - const struct ldb_map_attribute *map; - const struct ldb_map_attribute *wildcard = NULL; - unsigned int i, j; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - map = &data->attribute_maps[i]; - if (ldb_attr_cmp(map->local_name, "*") == 0) { - wildcard = &data->attribute_maps[i]; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - break; - - case LDB_MAP_KEEP: - if (ldb_attr_cmp(map->local_name, name) == 0) { - return map; - } - break; - - case LDB_MAP_RENAME: - case LDB_MAP_CONVERT: - if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { - return map; - } - break; - - case LDB_MAP_GENERATE: - for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) { - if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { - return map; - } - } - break; - } - } - - /* We didn't find it, so return the wildcard record if one was configured */ - return wildcard; -} - - -/* Mapping attributes - * ================== */ - -/* Check whether an attribute will be mapped into the remote partition. */ -bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr) -{ - const struct ldb_map_attribute *map = map_attr_find_local(data, attr); - - if (map == NULL) { - return false; - } - if (map->type == LDB_MAP_IGNORE) { - return false; - } - - return true; -} - -/* Map an attribute name into the remote partition. */ -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - switch (map->type) { - case LDB_MAP_KEEP: - return talloc_strdup(mem_ctx, attr); - - case LDB_MAP_RENAME: - case LDB_MAP_CONVERT: - return talloc_strdup(mem_ctx, map->u.rename.remote_name); - - default: - return NULL; - } -} - -/* Map an attribute name back into the local partition. */ -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - if (map->type == LDB_MAP_KEEP) { - return talloc_strdup(mem_ctx, attr); - } - - return talloc_strdup(mem_ctx, map->local_name); -} - - -/* Merge two lists of attributes into a single one. */ -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, - const char ***attrs, const char * const *more_attrs) -{ - unsigned int i, j, k; - - for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; - for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; - - *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); - if (*attrs == NULL) { - map_oom(module); - return -1; - } - - for (k = 0; k < j; k++) { - (*attrs)[i + k] = more_attrs[k]; - } - - (*attrs)[i+k] = NULL; - - return 0; -} - -/* Mapping ldb values - * ================== */ - -/* Map an ldb value into the remote partition. */ -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { - return map->u.convert.convert_local(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Map an ldb value back into the local partition. */ -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { - return map->u.convert.convert_remote(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - - -/* Mapping DNs - * =========== */ - -/* Check whether a DN is below the local baseDN. */ -bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->local_base_dn) { - return true; - } - - return ldb_dn_compare_base(data->local_base_dn, dn) == 0; -} - -/* Map a DN into the remote partition. */ -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - ldb = ldb_module_get_ctx(module); - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = LDB_MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case LDB_MAP_IGNORE: - case LDB_MAP_GENERATE: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_local' not set for attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - } - /* fall through */ - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN into the local partition. */ -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - ldb = ldb_module_get_ctx(module); - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = LDB_MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case LDB_MAP_IGNORE: - case LDB_MAP_GENERATE: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_remote' not set for attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - } - /* fall through */ - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN and its base into the local partition. */ -/* TODO: This should not be required with GUIDs. */ -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_dn *dn1, *dn2; - - dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); - dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); - - talloc_free(dn1); - return dn2; -} - - -/* Converting DNs and objectClasses (as ldb values) - * ================================================ */ - -/* Map a DN contained in an ldb value into the remote partition. */ -static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_context *ldb; - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); - if (! ldb_dn_validate(dn)) { - newval.length = 0; - newval.data = NULL; - talloc_free(dn); - return newval; - } - newdn = ldb_dn_map_local(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map a DN contained in an ldb value into the local partition. */ -static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_context *ldb; - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); - if (! ldb_dn_validate(dn)) { - newval.length = 0; - newval.data = NULL; - talloc_free(dn); - return newval; - } - newdn = ldb_dn_map_remote(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map an objectClass into the remote partition. */ -static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a remote message with a mapped objectClass. */ -static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message_element *el, *oc; - struct ldb_val val; - bool found_extensibleObject = false; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - /* Find old local objectClass */ - oc = ldb_msg_find_element(old, "objectClass"); - if (oc == NULL) { - return; - } - - /* Prepare new element */ - el = talloc_zero(remote, struct ldb_message_element); - if (el == NULL) { - ldb_oom(ldb); - return; /* TODO: fail? */ - } - - /* Copy local objectClass element, reverse space for an extra value */ - el->num_values = oc->num_values + 1; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return; /* TODO: fail? */ - } - - /* Copy local element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all local objectClasses */ - for (i = 0; i < el->num_values - 1; i++) { - el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); - if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { - found_extensibleObject = true; - } - } - - if (!found_extensibleObject) { - val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); - val.length = strlen((char *)val.data); - - /* Append additional objectClass data->add_objectclass */ - el->values[i] = val; - } else { - el->num_values--; - } - - /* Add new objectClass to remote message */ - ldb_msg_add(remote, el, 0); -} - -/* Map an objectClass into the local partition. */ -static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a local message with a mapped objectClass. */ -static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message_element *el, *oc; - struct ldb_val val; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - /* Find old remote objectClass */ - oc = ldb_msg_find_element(remote, "objectClass"); - if (oc == NULL) { - return NULL; - } - - /* Prepare new element */ - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - ldb_oom(ldb); - return NULL; - } - - /* Copy remote objectClass element */ - el->num_values = oc->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return NULL; - } - - /* Copy remote element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all remote objectClasses */ - for (i = 0; i < el->num_values; i++) { - el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); - } - - val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); - val.length = strlen((char *)val.data); - - /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ - if (ldb_val_equal_exact(&val, &el->values[i-1])) { - el->num_values--; - el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return NULL; - } - } - - return el; -} - -static const struct ldb_map_attribute objectclass_convert_map = { - .local_name = "objectClass", - .type = LDB_MAP_CONVERT, - .u = { - .convert = { - .remote_name = "objectClass", - .convert_local = map_objectclass_convert_local, - .convert_remote = map_objectclass_convert_remote, - }, - }, -}; - - -/* Mappings for searches on objectClass= assuming a one-to-one - * mapping. Needed because this is a generate operator for the - * add/modify code */ -static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, - struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map); -} - -/* Auxiliary request construction - * ============================== */ - -/* Build a request to search a record by its DN. */ -struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback) -{ - const struct ldb_parse_tree *search_tree; - struct ldb_context *ldb; - struct ldb_request *req; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (tree) { - search_tree = tree; - } else { - search_tree = ldb_parse_tree(ac, NULL); - if (search_tree == NULL) { - return NULL; - } - } - - ret = ldb_build_search_req_ex(&req, ldb, ac, - dn, LDB_SCOPE_BASE, - search_tree, attrs, - NULL, - context, callback, - ac->req); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - return NULL; - } - - return req; -} - -/* Build a request to update the 'IS_MAPPED' attribute */ -struct ldb_request *map_build_fixup_req(struct map_context *ac, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - void *context, - ldb_map_callback_t callback) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_message *msg; - const char *dn; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* Prepare message */ - msg = ldb_msg_new(ac); - if (msg == NULL) { - map_oom(ac->module); - return NULL; - } - - /* Update local 'IS_MAPPED' to the new remote DN */ - msg->dn = ldb_dn_copy(msg, olddn); - dn = ldb_dn_alloc_linearized(msg, newdn); - if ( ! dn || ! ldb_dn_validate(msg->dn)) { - goto failed; - } - if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto failed; - } - if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { - goto failed; - } - - /* Prepare request */ - ret = ldb_build_mod_req(&req, ldb, - ac, msg, NULL, - context, callback, - ac->req); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - goto failed; - } - talloc_steal(req, msg); - - return req; -failed: - talloc_free(msg); - return NULL; -} - -/* Module initialization - * ===================== */ - - -/* Builtin mappings for DNs and objectClasses */ -static const struct ldb_map_attribute builtin_attribute_maps[] = { - { - .local_name = "dn", - .type = LDB_MAP_CONVERT, - .u = { - .convert = { - .remote_name = "dn", - .convert_local = ldb_dn_convert_local, - .convert_remote = ldb_dn_convert_remote, - }, - }, - }, - { - .local_name = NULL, - } -}; - -static const struct ldb_map_attribute objectclass_attribute_map = { - .local_name = "objectClass", - .type = LDB_MAP_GENERATE, - .convert_operator = map_objectclass_convert_operator, - .u = { - .generate = { - .remote_names = { "objectClass", NULL }, - .generate_local = map_objectclass_generate_local, - .generate_remote = map_objectclass_generate_remote, - }, - }, -}; - - -/* Find the special 'MAP_DN_NAME' record and store local and remote - * base DNs in private data. */ -static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) -{ - static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; - struct ldb_context *ldb; - struct ldb_dn *dn; - struct ldb_message *msg; - struct ldb_result *res; - int ret; - - if (!name) { - data->local_base_dn = NULL; - data->remote_base_dn = NULL; - return LDB_SUCCESS; - } - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); - if ( ! ldb_dn_validate(dn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Failed to construct '%s' DN!", MAP_DN_NAME); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search(ldb, data, &res, dn, LDB_SCOPE_BASE, attrs, NULL); - talloc_free(dn); - if (ret != LDB_SUCCESS) { - return ret; - } - if (res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "No results for '%s=%s'!", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Too many results for '%s=%s'!", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - msg = res->msgs[0]; - data->local_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_FROM); - data->remote_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_TO); - talloc_free(res); - - return LDB_SUCCESS; -} - -/* Store attribute maps and objectClass maps in private data. */ -static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, - const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes) -{ - unsigned int i, j, last; - last = 0; - - /* Count specified attribute maps */ - for (i = 0; attrs[i].local_name; i++) /* noop */ ; - /* Count built-in attribute maps */ - for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; - - /* Store list of attribute maps */ - data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+2); - if (data->attribute_maps == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Specified ones go first */ - for (i = 0; attrs[i].local_name; i++) { - data->attribute_maps[last] = attrs[i]; - last++; - } - - /* Built-in ones go last */ - for (i = 0; builtin_attribute_maps[i].local_name; i++) { - data->attribute_maps[last] = builtin_attribute_maps[i]; - last++; - } - - if (data->add_objectclass) { - /* ObjectClass one is very last, if required */ - data->attribute_maps[last] = objectclass_attribute_map; - last++; - } else if (ocls) { - data->attribute_maps[last] = objectclass_convert_map; - last++; - } - - /* Ensure 'local_name == NULL' for the last entry */ - memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); - - /* Store list of objectClass maps */ - data->objectclass_maps = ocls; - - data->wildcard_attributes = wildcard_attributes; - - return LDB_SUCCESS; -} - -/* Initialize global private data. */ -_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *add_objectclass, - const char *name) -{ - struct map_private *data; - int ret; - - /* Prepare private data */ - data = talloc_zero(module, struct map_private); - if (data == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_module_set_private(module, data); - - data->context = talloc_zero(data, struct ldb_map_context); - if (!data->context) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Store local and remote baseDNs */ - ret = map_init_dns(module, data->context, name); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - data->context->add_objectclass = add_objectclass; - - /* Store list of attribute and objectClass maps */ - ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h deleted file mode 100644 index 5db3e02a08a..00000000000 --- a/source4/lib/ldb/ldb_map/ldb_map.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - - ** 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 . - -*/ - -#ifndef __LDB_MAP_H__ -#define __LDB_MAP_H__ - -#include "ldb_module.h" - -/* ldb_map is a skeleton LDB module that can be used for any other modules - * that need to map attributes. - * - * The term 'remote' in this header refers to the connection where the - * original schema is used on while 'local' means the local connection - * that any upper layers will use. - * - * All local attributes will have to have a definition. Not all remote - * attributes need a definition as LDB is a lot less strict than LDAP - * (in other words, sending unknown attributes to an LDAP server hurts us, - * while returning too many attributes in ldb_search() doesn't) - */ - - -/* Name of the internal attribute pointing from the local to the - * remote part of a record */ -#define IS_MAPPED "isMapped" - - -struct ldb_map_context; - -/* convert a local ldb_val to a remote ldb_val */ -typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); - -#define LDB_MAP_MAX_REMOTE_NAMES 10 - -/* map from local to remote attribute */ -struct ldb_map_attribute { - const char *local_name; /* local name */ - - enum ldb_map_attr_type { - LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ - LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ - LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ - LDB_MAP_CONVERT, /* Rename + convert data */ - LDB_MAP_GENERATE /* Use generate function for generating new name/data. - Used for generating attributes based on - multiple remote attributes. */ - } type; - - /* if set, will be called for search expressions that contain this attribute */ - int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **ntree, const struct ldb_parse_tree *otree); - - union { - struct { - const char *remote_name; - } rename; - - struct { - const char *remote_name; - - /* Convert local to remote data */ - ldb_map_convert_func convert_local; - - /* Convert remote to local data */ - /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name - * that is non-NULL before it. */ - ldb_map_convert_func convert_remote; - } convert; - - struct { - /* Generate the local attribute from remote message */ - struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); - - /* Update remote message with information from local message */ - void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); - - /* Name(s) for this attribute on the remote server. This is an array since - * one local attribute's data can be split up into several attributes - * remotely */ - const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; - - /* Names of additional remote attributes - * required for the generation. NULL - * indicates that `local_attr' suffices. */ - /* -#define LDB_MAP_MAX_SELF_ATTRIBUTES 10 - const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; - */ - } generate; - } u; -}; - - -#define LDB_MAP_MAX_SUBCLASSES 10 -#define LDB_MAP_MAX_MUSTS 10 -#define LDB_MAP_MAX_MAYS 50 - -/* map from local to remote objectClass */ -struct ldb_map_objectclass { - const char *local_name; - const char *remote_name; - const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; - const char *musts[LDB_MAP_MAX_MUSTS]; - const char *mays[LDB_MAP_MAX_MAYS]; -}; - - -/* private context data */ -struct ldb_map_context { - struct ldb_map_attribute *attribute_maps; - /* NOTE: Always declare base classes first here */ - const struct ldb_map_objectclass *objectclass_maps; - - /* Remote (often operational) attributes that should be added - * to any wildcard search */ - const char * const *wildcard_attributes; - - /* ObjectClass (if any) to be added to remote attributes on add */ - const char *add_objectclass; - - /* struct ldb_context *mapped_ldb; */ - struct ldb_dn *local_base_dn; - struct ldb_dn *remote_base_dn; -}; - -/* Global private data */ -struct map_private { - void *caller_private; - struct ldb_map_context *context; -}; - -/* Initialize global private data. */ -int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *add_objectclass, - const char *name); - -int ldb_map_add(struct ldb_module *module, struct ldb_request *req); -int ldb_map_search(struct ldb_module *module, struct ldb_request *req); -int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); -int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); -int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); - -#define LDB_MAP_OPS \ - .add = ldb_map_add, \ - .modify = ldb_map_modify, \ - .del = ldb_map_delete, \ - .rename = ldb_map_rename, \ - .search = ldb_map_search, - -#endif /* __LDB_MAP_H__ */ diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c deleted file mode 100644 index b61037222a8..00000000000 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Simo Sorce 2008 - - ** 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 . - -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - - -/* Mapping message elements - * ======================== */ - -/* Map a message element into the remote partition. */ -static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) -{ - struct ldb_message_element *el; - unsigned int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->num_values = old->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - el->name = map_attr_map_local(el, map, old->name); - - for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); - } - - return el; -} - -/* Add a message element either to a local or to a remote message, - * depending on whether it goes into the local or remote partition. */ -static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); - struct ldb_message_element *el=NULL; - struct ldb_context *ldb = ldb_module_get_ctx(module); - - /* Unknown attribute: ignore */ - if (map == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': no mapping found", - old->name); - goto local; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - goto local; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'convert_local' not set", - map->local_name); - goto local; - } - /* fall through */ - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - el = ldb_msg_el_map_local(module, remote, map, old); - break; - - case LDB_MAP_GENERATE: - if (map->u.generate.generate_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'generate_remote' not set", - map->local_name); - goto local; - } - - /* TODO: if this attr requires context: - * make sure all context attrs are mappable (in 'names') - * make sure all context attrs have already been mapped? - * maybe postpone generation until they have been mapped? - */ - - map->u.generate.generate_remote(module, map->local_name, msg, remote, local); - return 0; - } - - if (el == NULL) { - return -1; - } - - return ldb_msg_add(remote, el, old->flags); - -local: - el = talloc(local, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return -1; - } - - *el = *old; /* copy the old element */ - - return ldb_msg_add(local, el, old->flags); -} - -/* Mapping messages - * ================ */ - -/* Check whether a message will be (partially) mapped into the remote partition. */ -static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) -{ - const struct ldb_map_context *data = map_get_context(module); - bool ret; - unsigned int i; - - for (i = 0; i < msg->num_elements; i++) { - ret = map_attr_check_remote(data, msg->elements[i].name); - if (ret) { - return ret; - } - } - - return false; -} - -/* Split message elements that stay in the local partition from those - * that are mapped into the remote partition. */ -static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) -{ - /* const char * const names[]; */ - struct ldb_context *ldb; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - for (i = 0; i < msg->num_elements; i++) { - /* Skip 'IS_MAPPED' */ - if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s'", - msg->elements[i].name); - continue; - } - - ret = ldb_msg_el_partition(module, local, remote, msg, msg->elements[i].name, &msg->elements[i]); - if (ret) { - return ret; - } - } - - return 0; -} - - -static int map_add_do_local(struct map_context *ac); -static int map_modify_do_local(struct map_context *ac); -static int map_delete_do_local(struct map_context *ac); -static int map_rename_do_local(struct map_context *ac); -static int map_rename_do_fixup(struct map_context *ac); -static int map_rename_local_callback(struct ldb_request *req, - struct ldb_reply *ares); - - -/***************************************************************************** - * COMMON INBOUND functions -*****************************************************************************/ - -/* Store the DN of a single search result in context. */ -static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* We are interested only in the single reply */ - switch(ares->type) { - case LDB_REPLY_ENTRY: - /* We have already found a remote DN */ - if (ac->local_dn) { - ldb_set_errstring(ldb, - "Too many results!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Store local DN */ - ac->local_dn = talloc_steal(ac, ares->message->dn); - break; - - case LDB_REPLY_DONE: - - switch (ac->req->operation) { - case LDB_MODIFY: - ret = map_modify_do_local(ac); - break; - case LDB_DELETE: - ret = map_delete_do_local(ac); - break; - case LDB_RENAME: - ret = map_rename_do_local(ac); - break; - default: - /* if we get here we have definitely a problem */ - ret = LDB_ERR_OPERATIONS_ERROR; - } - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - default: - /* ignore referrals */ - break; - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -/* Build a request to search the local record by its DN. */ -static int map_search_self_req(struct ldb_request **req, - struct map_context *ac, - struct ldb_dn *dn) -{ - /* attrs[] is returned from this function in - * ac->search_req->op.search.attrs, so it must be static, as - * otherwise the compiler can put it on the stack */ - static const char * const attrs[] = { IS_MAPPED, NULL }; - struct ldb_parse_tree *tree; - - /* Limit search to records with 'IS_MAPPED' present */ - tree = ldb_parse_tree(ac, "(" IS_MAPPED "=*)"); - if (tree == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - *req = map_search_base_req(ac, dn, attrs, tree, - ac, map_search_self_callback); - if (*req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int map_op_local_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_set_errstring(ldb, "Invalid reply type!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Do the remote request. */ - ret = ldb_next_remote_request(ac->module, ac->remote_req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -static int map_op_remote_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_set_errstring(ldb, "Invalid reply type!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); -} - - -/***************************************************************************** - * ADD operations -*****************************************************************************/ - - -/* Add a record. */ -int ldb_map_add(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.add.message; - struct ldb_context *ldb; - struct map_context *ac; - struct ldb_message *remote_msg; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, fail */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - - /* Prepare the local message */ - ac->local_msg = ldb_msg_new(ac); - if (ac->local_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->local_msg->dn = msg->dn; - - /* Prepare the remote message */ - remote_msg = ldb_msg_new(ac); - if (remote_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, ac->local_msg, remote_msg, msg); - - /* Prepare the remote operation */ - ret = ldb_build_add_req(&ac->remote_req, ldb, - ac, remote_msg, - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((ac->local_msg->num_elements == 0) || - ( ! map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Store remote DN in 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, - remote_msg->dn); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return map_add_do_local(ac); -} - -/* Add the local record. */ -static int map_add_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* Prepare the local operation */ - ret = ldb_build_add_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * MODIFY operations -*****************************************************************************/ - -/* Modify a record. */ -int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.mod.message; - struct ldb_request *search_req; - struct ldb_message *remote_msg; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, skip to next module */ - /* TODO: What if the remote part exists, the local doesn't, - * and this request wants to modify local data and thus - * add the local record? */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the local message */ - ac->local_msg = ldb_msg_new(ac); - if (ac->local_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->local_msg->dn = msg->dn; - - /* Prepare the remote message */ - remote_msg = ldb_msg_new(ac->remote_req); - if (remote_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, ac->local_msg, remote_msg, msg); - - /* Prepare the remote operation */ - ret = ldb_build_mod_req(&ac->remote_req, ldb, - ac, remote_msg, - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((ac->local_msg->num_elements == 0) || - ( ! map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* prepare the search operation */ - ret = map_search_self_req(&search_req, ac, msg->dn); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Modify the local record. */ -static int map_modify_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->local_dn == NULL) { - /* No local record present, add it instead */ - /* Add local 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, - LDB_FLAG_MOD_ADD, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, - ac->remote_req->op.mod.message->dn); - if (ret != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the local operation */ - ret = ldb_build_add_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - /* Prepare the local operation */ - ret = ldb_build_mod_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * DELETE operations -*****************************************************************************/ - -/* Delete a record. */ -int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *search_req; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified). - * Skip to next module */ - if (!ldb_dn_check_local(module, req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the remote operation */ - ret = ldb_build_del_req(&ac->remote_req, ldb, ac, - ldb_dn_map_local(module, ac, req->op.del.dn), - req->controls, - ac, - map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the search operation */ - ret = map_search_self_req(&search_req, ac, req->op.del.dn); - if (ret != LDB_SUCCESS) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Delete the local record. */ -static int map_delete_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the local operation */ - ret = ldb_build_del_req(&local_req, ldb, ac, - ac->req->op.del.dn, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * RENAME operations -*****************************************************************************/ - -/* Rename a record. */ -int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *search_req; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.olddn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified). - * Skip to next module */ - if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && - (!ldb_dn_check_local(module, req->op.rename.newdn))) { - return ldb_next_request(module, req); - } - - /* Rename into/out of the mapped partition requested, bail out */ - if (!ldb_dn_check_local(module, req->op.rename.olddn) || - !ldb_dn_check_local(module, req->op.rename.newdn)) { - return LDB_ERR_AFFECTS_MULTIPLE_DSAS; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the remote operation */ - ret = ldb_build_rename_req(&ac->remote_req, ldb, ac, - ldb_dn_map_local(module, ac, req->op.rename.olddn), - ldb_dn_map_local(module, ac, req->op.rename.newdn), - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the search operation */ - ret = map_search_self_req(&search_req, ac, req->op.rename.olddn); - if (ret != LDB_SUCCESS) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Rename the local record. */ -static int map_rename_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the local operation */ - ret = ldb_build_rename_req(&local_req, ldb, ac, - ac->req->op.rename.olddn, - ac->req->op.rename.newdn, - ac->req->controls, - ac, - map_rename_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, local_req); -} - -static int map_rename_local_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_set_errstring(ldb, "Invalid reply type!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* proceed with next step */ - ret = map_rename_do_fixup(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -/* Update the local 'IS_MAPPED' attribute. */ -static int map_rename_do_fixup(struct map_context *ac) -{ - struct ldb_request *local_req; - - /* Prepare the fixup operation */ - /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ - local_req = map_build_fixup_req(ac, - ac->req->op.rename.newdn, - ac->remote_req->op.rename.newdn, - ac, - map_op_local_callback); - if (local_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, local_req); -} diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c deleted file mode 100644 index 2c517a625dc..00000000000 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ /dev/null @@ -1,1407 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Andrew Bartlett 2006 - Copyright (C) Simo Sorce 2008 - - ** 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 . - -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - - -/* Mapping attributes - * ================== */ - -/* Select attributes that stay in the local partition. */ -static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - unsigned int i, last; - - if (attrs == NULL) - return NULL; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards and ignored attributes are kept locally */ - if ((ldb_attr_cmp(attrs[i], "*") == 0) || - (!map_attr_check_remote(data, attrs[i]))) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, attrs[i]); - result[last+1] = NULL; - last++; - } - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Collect attributes that are mapped into the remote partition. */ -static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, - const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - const struct ldb_map_attribute *map; - const char *name=NULL; - unsigned int i, j, last; - int ret; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - const char **new_attrs = NULL; - ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); - if (ret != LDB_SUCCESS) { - goto failed; - } - ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); - if (ret != LDB_SUCCESS) { - goto failed; - } - - attrs = new_attrs; - break; - } - } - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - /* Add all 'include in wildcard' attributes */ - name = attrs[i]; - goto named; - } - - /* Add remote names of mapped attrs */ - map = map_attr_find_local(data, attrs[i]); - if (map == NULL) { - continue; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - continue; - - case LDB_MAP_KEEP: - name = attrs[i]; - goto named; - - case LDB_MAP_RENAME: - case LDB_MAP_CONVERT: - name = map->u.rename.remote_name; - goto named; - - case LDB_MAP_GENERATE: - /* Add all remote names of "generate" attrs */ - for (j = 0; map->u.generate.remote_names[j]; j++) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); - result[last+1] = NULL; - last++; - } - continue; - } - - named: /* We found a single remote name, add that */ - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, name); - result[last+1] = NULL; - last++; - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Split attributes that stay in the local partition from those that - * are mapped into the remote partition. */ -static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) -{ - *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); - *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); - - return 0; -} - -/* Mapping message elements - * ======================== */ - -/* Add an element to a message, overwriting any old identically named elements. */ -static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) -{ - struct ldb_message_element *old; - - old = ldb_msg_find_element(msg, el->name); - - /* no local result, add as new element */ - if (old == NULL) { - if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { - return -1; - } - talloc_free(discard_const_p(char, old->name)); - } - - /* copy new element */ - *old = *el; - - /* and make sure we reference the contents */ - if (!talloc_reference(msg->elements, el->name)) { - return -1; - } - if (!talloc_reference(msg->elements, el->values)) { - return -1; - } - - return 0; -} - -/* Map a message element back into the local partition. */ -static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, - void *mem_ctx, - const struct ldb_map_attribute *map, - const char *attr_name, - const struct ldb_message_element *old) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *local_attr_name = attr_name; - struct ldb_message_element *el; - unsigned int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->values = talloc_array(el, struct ldb_val, old->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - for (i = 0; data->attribute_maps[i].local_name; i++) { - struct ldb_map_attribute *am = &data->attribute_maps[i]; - if ((am->type == LDB_MAP_RENAME && - !strcmp(am->u.rename.remote_name, attr_name)) - || (am->type == LDB_MAP_CONVERT && - !strcmp(am->u.convert.remote_name, attr_name))) { - - local_attr_name = am->local_name; - break; - } - } - - el->name = talloc_strdup(el, local_attr_name); - if (el->name == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - for (i = 0; i < old->num_values; i++) { - el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); - /* Conversions might fail, in which case bail */ - if (!el->values[i].data) { - talloc_free(el); - return NULL; - } - el->num_values++; - } - - return el; -} - -/* Merge a remote message element into a local message. */ -static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote, const char *attr_name) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - struct ldb_message_element *old, *el=NULL; - const char *remote_name = NULL; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(module); - - /* We handle wildcards in ldb_msg_el_merge_wildcard */ - if (ldb_attr_cmp(attr_name, "*") == 0) { - return LDB_SUCCESS; - } - - map = map_attr_find_local(data, attr_name); - - /* Unknown attribute in remote message: - * skip, attribute was probably auto-generated */ - if (map == NULL) { - return LDB_SUCCESS; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - break; - case LDB_MAP_CONVERT: - remote_name = map->u.convert.remote_name; - break; - case LDB_MAP_KEEP: - remote_name = attr_name; - break; - case LDB_MAP_RENAME: - remote_name = map->u.rename.remote_name; - break; - case LDB_MAP_GENERATE: - break; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - return LDB_SUCCESS; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'convert_remote' not set", - attr_name); - return LDB_SUCCESS; - } - /* fall through */ - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - old = ldb_msg_find_element(remote, remote_name); - if (old) { - el = ldb_msg_el_map_remote(module, local, map, attr_name, old); - } else { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - - case LDB_MAP_GENERATE: - if (map->u.generate.generate_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'generate_local' not set", - attr_name); - return LDB_SUCCESS; - } - - el = map->u.generate.generate_local(module, local, attr_name, remote); - if (!el) { - /* Generation failure is probably due to lack of source attributes */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - } - - if (el == NULL) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - - return ldb_msg_replace(local, el); -} - -/* Handle wildcard parts of merging a remote message element into a local message. */ -static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); - struct ldb_message_element *el=NULL; - unsigned int i; - int ret; - - /* Perhaps we have a mapping for "*" */ - if (map && map->type == LDB_MAP_KEEP) { - /* We copy everything over, and hope that anything with a - more specific rule is overwritten */ - for (i = 0; i < remote->num_elements; i++) { - el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, - &remote->elements[i]); - if (el == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_msg_replace(local, el); - if (ret) { - return ret; - } - } - } - - /* Now walk the list of possible mappings, and apply each */ - for (i = 0; data->attribute_maps[i].local_name; i++) { - ret = ldb_msg_el_merge(module, local, remote, - data->attribute_maps[i].local_name); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - continue; - } else if (ret) { - return ret; - } else { - continue; - } - } - - return LDB_SUCCESS; -} - -/* Mapping messages - * ================ */ - -/* Merge two local messages into a single one. */ -static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) -{ - unsigned int i; - int ret; - - for (i = 0; i < msg2->num_elements; i++) { - ret = ldb_msg_replace(msg1, &msg2->elements[i]); - if (ret) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* Merge a local and a remote message into a single local one. */ -static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, - struct ldb_message *remote) -{ - unsigned int i; - int ret; - const char * const *attrs = ac->all_attrs; - if (!attrs) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - } - - for (i = 0; attrs && attrs[i]; i++) { - if (ldb_attr_cmp(attrs[i], "*") == 0) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - break; - } - } - - /* Try to map each attribute back; - * Add to local message is possible, - * Overwrite old local attribute if necessary */ - for (i = 0; attrs && attrs[i]; i++) { - ret = ldb_msg_el_merge(ac->module, local, remote, - attrs[i]); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - } else if (ret) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* Mapping search results - * ====================== */ - -/* Map a search result back into the local partition. */ -static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) -{ - struct ldb_message *msg; - struct ldb_dn *dn; - int ret; - - /* There is no result message, skip */ - if (ares->type != LDB_REPLY_ENTRY) { - return 0; - } - - /* Create a new result message */ - msg = ldb_msg_new(ares); - if (msg == NULL) { - map_oom(ac->module); - return -1; - } - - /* Merge remote message into new message */ - ret = ldb_msg_merge_remote(ac, msg, ares->message); - if (ret) { - talloc_free(msg); - return ret; - } - - /* Create corresponding local DN */ - dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); - if (dn == NULL) { - talloc_free(msg); - return -1; - } - msg->dn = dn; - - /* Store new message with new DN as the result */ - talloc_free(ares->message); - ares->message = msg; - - return 0; -} - -/* Mapping parse trees - * =================== */ - -/* Check whether a parse tree can safely be split in two. */ -static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) -{ - const struct ldb_parse_tree *subtree = tree; - bool negate = false; - - while (subtree) { - switch (subtree->operation) { - case LDB_OP_NOT: - negate = !negate; - subtree = subtree->u.isnot.child; - continue; - - case LDB_OP_AND: - return !negate; /* if negate: False */ - - case LDB_OP_OR: - return negate; /* if negate: True */ - - default: - return true; /* simple parse tree */ - } - } - - return true; /* no parse tree */ -} - -/* Collect a list of attributes required to match a given parse tree. */ -static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) -{ - const char **new_attrs; - unsigned int i; - int ret; - - if (tree == NULL) { - return 0; - } - - switch (tree->operation) { - case LDB_OP_OR: - case LDB_OP_AND: /* attributes stored in list of subtrees */ - for (i = 0; i < tree->u.list.num_elements; i++) { - ret = ldb_parse_tree_collect_attrs(module, mem_ctx, - attrs, tree->u.list.elements[i]); - if (ret) { - return ret; - } - } - return 0; - - case LDB_OP_NOT: /* attributes stored in single subtree */ - return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); - - default: /* single attribute in tree */ - new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); - talloc_free(*attrs); - *attrs = new_attrs; - return 0; - } -} - -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Select a negated subtree that queries attributes in the local partition */ -static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Generate new subtree */ - ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Select a list of subtrees that query attributes in the local partition */ -static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - unsigned int i, j; - int ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return -1; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child; - ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Select a simple subtree that queries attributes in the local partition */ -static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - return 0; -} - -/* Select subtrees that query attributes in the local partition */ -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_select_local_not(module, mem_ctx, new, tree); - } - - if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { - return map_subtree_select_local_list(module, mem_ctx, new, tree); - } - - if (map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - return map_subtree_select_local_simple(module, mem_ctx, new, tree); -} - -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Collect a negated subtree that queries attributes in the remote partition */ -static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Generate new subtree */ - ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Collect a list of subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - unsigned int i, j; - int ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return -1; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child; - ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Collect a simple subtree that queries attributes in the remote partition */ -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) -{ - const char *attr; - - /* Prepare new tree */ - *new = talloc(mem_ctx, struct ldb_parse_tree); - if (*new == NULL) { - map_oom(module); - return -1; - } - **new = *tree; - - if (map->type == LDB_MAP_KEEP) { - /* Nothing to do here */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - attr = map_attr_map_local(*new, map, tree->u.present.attr); - (*new)->u.present.attr = attr; - break; - case LDB_OP_SUBSTRING: - { - attr = map_attr_map_local(*new, map, tree->u.substring.attr); - (*new)->u.substring.attr = attr; - break; - } - case LDB_OP_EQUALITY: - attr = map_attr_map_local(*new, map, tree->u.equality.attr); - (*new)->u.equality.attr = attr; - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - attr = map_attr_map_local(*new, map, tree->u.comparison.attr); - (*new)->u.comparison.attr = attr; - break; - case LDB_OP_EXTENDED: - attr = map_attr_map_local(*new, map, tree->u.extended.attr); - (*new)->u.extended.attr = attr; - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return -1; - } - - if (attr == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - if (map->type == LDB_MAP_RENAME) { - /* Nothing more to do here, the attribute has been renamed */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - break; - case LDB_OP_SUBSTRING: - { - int i; - /* Map value */ - (*new)->u.substring.chunks = NULL; - for (i=0; tree->u.substring.chunks[i]; i++) { - (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); - if (!(*new)->u.substring.chunks) { - talloc_free(*new); - *new = NULL; - return 0; - } - (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); - if (!(*new)->u.substring.chunks[i]) { - talloc_free(*new); - *new = NULL; - return 0; - } - *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); - (*new)->u.substring.chunks[i+1] = NULL; - } - break; - } - case LDB_OP_EQUALITY: - (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); - break; - case LDB_OP_EXTENDED: - (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); - (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return -1; - } - - return 0; -} - -/* Collect subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(module); - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_collect_remote_not(module, mem_ctx, new, tree); - } - - if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { - return map_subtree_collect_remote_list(module, mem_ctx, new, tree); - } - - if (!map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - map = map_attr_find_local(data, tree->u.equality.attr); - if (map->convert_operator) { - return map->convert_operator(module, mem_ctx, new, tree); - } - - if (map->type == LDB_MAP_GENERATE) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s': " - "'convert_operator' not set", - tree->u.equality.attr); - *new = NULL; - return 0; - } - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); -} - -/* Split subtrees that query attributes in the local partition from - * those that query the remote partition. */ -static int ldb_parse_tree_partition(struct ldb_module *module, - void *mem_ctx, - struct ldb_parse_tree **local_tree, - struct ldb_parse_tree **remote_tree, - const struct ldb_parse_tree *tree) -{ - int ret; - - *local_tree = NULL; - *remote_tree = NULL; - - /* No original tree */ - if (tree == NULL) { - return 0; - } - - /* Generate local tree */ - ret = map_subtree_select_local(module, mem_ctx, local_tree, tree); - if (ret) { - return ret; - } - - /* Generate remote tree */ - ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree); - if (ret) { - talloc_free(*local_tree); - return ret; - } - - return 0; -} - -/* Collect a list of attributes required either explicitly from a - * given list or implicitly from a given parse tree; split the - * collected list into local and remote parts. */ -static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, - const char * const *search_attrs, - const struct ldb_parse_tree *tree) -{ - void *tmp_ctx; - const char **tree_attrs; - const char **remote_attrs; - const char **local_attrs; - int ret; - - /* There is no tree, just partition the searched attributes */ - if (tree == NULL) { - ret = map_attrs_partition(module, ac, - &local_attrs, &remote_attrs, search_attrs); - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - ac->all_attrs = search_attrs; - } - return ret; - } - - /* Create context for temporary memory */ - tmp_ctx = talloc_new(ac); - if (tmp_ctx == NULL) { - goto oom; - } - - /* Prepare list of attributes from tree */ - tree_attrs = talloc_array(tmp_ctx, const char *, 1); - if (tree_attrs == NULL) { - talloc_free(tmp_ctx); - goto oom; - } - tree_attrs[0] = NULL; - - /* Collect attributes from tree */ - ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); - if (ret) { - goto done; - } - - /* Merge attributes from search operation */ - ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); - if (ret) { - goto done; - } - - /* Split local from remote attributes */ - ret = map_attrs_partition(module, ac, &local_attrs, - &remote_attrs, tree_attrs); - - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - talloc_steal(ac, tree_attrs); - ac->all_attrs = tree_attrs; - } -done: - /* Free temporary memory */ - talloc_free(tmp_ctx); - return ret; - -oom: - map_oom(module); - return -1; -} - - -/* Outbound requests: search - * ========================= */ - -static int map_remote_search_callback(struct ldb_request *req, - struct ldb_reply *ares); -static int map_local_merge_callback(struct ldb_request *req, - struct ldb_reply *ares); -static int map_search_local(struct map_context *ac); - -static int map_save_entry(struct map_context *ac, struct ldb_reply *ares) -{ - struct map_reply *mr; - - mr = talloc_zero(ac, struct map_reply); - if (mr == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - mr->remote = talloc_steal(mr, ares); - if (ac->r_current) { - ac->r_current->next = mr; - } else { - /* first entry */ - ac->r_list = mr; - } - ac->r_current = mr; - - return LDB_SUCCESS; -} - -/* Pass a merged search result up the callback chain. */ -int map_return_entry(struct map_context *ac, struct ldb_reply *ares) -{ - struct ldb_message_element *el; - const char * const *attrs; - struct ldb_context *ldb; - unsigned int i; - int ret; - bool matched; - - ldb = ldb_module_get_ctx(ac->module); - - /* Merged result doesn't match original query, skip */ - ret = ldb_match_msg_error(ldb, ares->message, - ac->req->op.search.tree, - ac->req->op.search.base, - ac->req->op.search.scope, - &matched); - if (ret != LDB_SUCCESS) return ret; - if (!matched) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " - "Skipping record '%s': " - "doesn't match original search", - ldb_dn_get_linearized(ares->message->dn)); - return LDB_SUCCESS; - } - - /* Limit result to requested attrs */ - if (ac->req->op.search.attrs && - (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) { - - attrs = ac->req->op.search.attrs; - i = 0; - - while (i < ares->message->num_elements) { - - el = &ares->message->elements[i]; - if ( ! ldb_attr_in_list(attrs, el->name)) { - ldb_msg_remove_element(ares->message, el); - } else { - i++; - } - } - } - - return ldb_module_send_entry(ac->req, ares->message, ares->controls); -} - -/* Search a record. */ -int ldb_map_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_parse_tree *remote_tree; - struct ldb_parse_tree *local_tree; - struct ldb_request *remote_req; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - const char *wildcard[] = { "*", NULL }; - const char * const *attrs; - - ldb = ldb_module_get_ctx(module); - - /* if we're not yet initialized, go to the next module */ - if (!ldb_module_get_private(module)) - return ldb_next_request(module, req); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) { - return ldb_next_request(module, req); - } - - /* No mapping requested, skip to next module */ - if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { - return ldb_next_request(module, req); - } - - /* TODO: How can we be sure about which partition we are - * targetting when there is no search base? */ - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* It is easier to deal with the two different ways of - * expressing the wildcard in the same codepath */ - attrs = req->op.search.attrs; - if (attrs == NULL) { - attrs = wildcard; - } - - /* Split local from remote attrs */ - ret = map_attrs_collect_and_partition(module, ac, - attrs, req->op.search.tree); - if (ret) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Split local from remote tree */ - ret = ldb_parse_tree_partition(module, ac, - &local_tree, &remote_tree, - req->op.search.tree); - if (ret) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (((local_tree != NULL) && (remote_tree != NULL)) && - (!ldb_parse_tree_check_splittable(req->op.search.tree))) { - /* The query can't safely be split, enumerate the remote partition */ - local_tree = NULL; - remote_tree = NULL; - } - - if (local_tree == NULL) { - /* Construct default local parse tree */ - local_tree = talloc_zero(ac, struct ldb_parse_tree); - if (local_tree == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - local_tree->operation = LDB_OP_PRESENT; - local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); - } - if (remote_tree == NULL) { - /* Construct default remote parse tree */ - remote_tree = ldb_parse_tree(ac, NULL); - if (remote_tree == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ac->local_tree = local_tree; - - /* Prepare the remote operation */ - ret = ldb_build_search_req_ex(&remote_req, ldb, ac, - req->op.search.base, - req->op.search.scope, - remote_tree, - ac->remote_attrs, - req->controls, - ac, map_remote_search_callback, - req); - LDB_REQ_SET_LOCATION(remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_remote_request(module, remote_req); -} - -/* Now, search the local part of a remote search result. */ -static int map_remote_search_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_REFERRAL: - - /* ignore referrals */ - talloc_free(ares); - return LDB_SUCCESS; - - case LDB_REPLY_ENTRY: - - /* Map result record into a local message */ - ret = map_reply_remote(ac, ares); - if (ret) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* if we have no local db, then we can just return the reply to - * the upper layer, otherwise we must save it and process it - * when all replies ahve been gathered */ - if ( ! map_check_local_db(ac->module)) { - ret = map_return_entry(ac, ares); - } else { - ret = map_save_entry(ac,ares); - } - - if (ret != LDB_SUCCESS) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - break; - - case LDB_REPLY_DONE: - - if ( ! map_check_local_db(ac->module)) { - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - - /* reset the pointer to the start of the list */ - ac->r_current = ac->r_list; - - /* no entry just return */ - if (ac->r_current == NULL) { - ret = ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - talloc_free(ares); - return ret; - } - - ac->remote_done_ares = talloc_steal(ac, ares); - - ret = map_search_local(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - } - - return LDB_SUCCESS; -} - -static int map_search_local(struct map_context *ac) -{ - struct ldb_request *search_req; - - if (ac->r_current == NULL || ac->r_current->remote == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare local search request */ - /* TODO: use GUIDs here instead? */ - search_req = map_search_base_req(ac, - ac->r_current->remote->message->dn, - NULL, NULL, - ac, map_local_merge_callback); - if (search_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, search_req); -} - -/* Merge the remote and local parts of a search result. */ -int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* We have already found a local record */ - if (ac->r_current->local) { - talloc_free(ares); - ldb_set_errstring(ldb, "ldb_map: Too many results!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Store local result */ - ac->r_current->local = talloc_steal(ac->r_current, ares); - - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - /* We don't need the local 'ares', but we will use the remote one from below */ - talloc_free(ares); - - /* No local record found, map and send remote record */ - if (ac->r_current->local != NULL) { - /* Merge remote into local message */ - ret = ldb_msg_merge_local(ac->module, - ac->r_current->local->message, - ac->r_current->remote->message); - if (ret == LDB_SUCCESS) { - ret = map_return_entry(ac, ac->r_current->local); - } - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - } else { - ret = map_return_entry(ac, ac->r_current->remote); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - } - - if (ac->r_current->next != NULL) { - ac->r_current = ac->r_current->next; - if (ac->r_current->remote->type == LDB_REPLY_ENTRY) { - ret = map_search_local(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - break; - } - } - - /* ok we are done with all search, finally it is time to - * finish operations for this module */ - return ldb_module_done(ac->req, - ac->remote_done_ares->controls, - ac->remote_done_ares->response, - ac->remote_done_ares->error); - } - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb/ldb_map/ldb_map_private.h b/source4/lib/ldb/ldb_map/ldb_map_private.h deleted file mode 100644 index 7faaa997088..00000000000 --- a/source4/lib/ldb/ldb_map/ldb_map_private.h +++ /dev/null @@ -1,96 +0,0 @@ -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" - -/* A handy macro to report Out of Memory conditions */ -#define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); - -/* The type of search callback functions */ -typedef int (*ldb_map_callback_t)(struct ldb_request *, struct ldb_reply *); - -/* The special DN from which the local and remote base DNs are fetched */ -#define MAP_DN_NAME "@MAP" -#define MAP_DN_FROM "@FROM" -#define MAP_DN_TO "@TO" - -/* Private data structures - * ======================= */ - -struct map_reply { - struct map_reply *next; - struct ldb_reply *remote; - struct ldb_reply *local; -}; - -/* Context data for mapped requests */ -struct map_context { - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_dn *local_dn; - const struct ldb_parse_tree *local_tree; - const char * const *local_attrs; - const char * const *remote_attrs; - const char * const *all_attrs; - - struct ldb_message *local_msg; - struct ldb_request *remote_req; - - struct map_reply *r_list; - struct map_reply *r_current; - - /* The response continaing any controls the remote server gave */ - struct ldb_reply *remote_done_ares; -}; - -/* Common operations - * ================= */ - -/* The following definitions come from lib/ldb/modules/ldb_map.c */ -const struct ldb_map_context *map_get_context(struct ldb_module *module); -struct map_context *map_init_context(struct ldb_module *module, - struct ldb_request *req); - -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); - -bool map_check_local_db(struct ldb_module *module); -bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr); -bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn); - -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); - -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); - -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); - -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); - -struct ldb_request *map_search_base_req(struct map_context *ac, - struct ldb_dn *dn, - const char * const *attrs, - const struct ldb_parse_tree *tree, - void *context, - ldb_map_callback_t callback); -struct ldb_request *map_build_fixup_req(struct map_context *ac, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - void *context, - ldb_map_callback_t callback); -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, - struct ldb_parse_tree **new, - const struct ldb_parse_tree *tree, - const struct ldb_map_attribute *map); -int map_return_fatal_error(struct ldb_request *req, - struct ldb_reply *ares); -int map_return_normal_error(struct ldb_request *req, - struct ldb_reply *ares, - int error); - -int map_return_entry(struct map_context *ac, struct ldb_reply *ares); diff --git a/source4/lib/ldb/ldb_sqlite3/README b/source4/lib/ldb/ldb_sqlite3/README deleted file mode 100644 index 6cda0a77595..00000000000 --- a/source4/lib/ldb/ldb_sqlite3/README +++ /dev/null @@ -1,7 +0,0 @@ -trees.ps contains an explanation of the Genealogical Representation of Trees -in Databases which is being used in ldb_sqlite3. Note that we use fgID -representation with 4 bytes per level, so we can represent 6.5E+08 subclasses -of any object class. This should be adequate for our purposes. :-) - -The following document is the primary basis for the schema currently being -used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/source4/lib/ldb/ldb_sqlite3/base160.c b/source4/lib/ldb/ldb_sqlite3/base160.c deleted file mode 100644 index 7ad39f7c2f5..00000000000 --- a/source4/lib/ldb/ldb_sqlite3/base160.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - base160 code used by ldb_sqlite3 - - Copyright (C) 2004 Derrell Lipman - - 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 . -*/ - - -/* - * ldb_sqlite3_base160() - * - * Convert an integer value to a string containing the base 160 representation - * of the integer. We always convert to a string representation that is 4 - * bytes in length, and we always null terminate. - * - * Parameters: - * val -- - * The value to be converted - * - * result -- - * Buffer in which the result is to be placed - * - * Returns: - * nothing - */ -static unsigned char base160tab[161] = -{ - 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ - 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ - 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ - 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ - 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ - 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ - '\0' -}; - - -/* - * lsqlite3_base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -void -lsqlite3_base160(unsigned long val, - unsigned char result[5]) -{ - int i; - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; -} - - -/* - * lsqlite3_base160Next() - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) are - * operated on. - * - * Parameters: - * base160 -- a character array containing either an empty string (in which - * case no operation is performed), or a string of base160 digits - * with a length of a multiple of four digits. - * - * Upon return, the trailing four digits (one tree level) will - * have been incremented by 1. - * - * Returns: - * base160 -- the modified array - */ -char * -lsqlite3_base160Next(char base160[]) -{ - int i; - int len; - unsigned char * pTab; - char * pBase160 = base160; - - /* - * We need a minimum of four digits, and we will always get a multiple of - * four digits. - */ - if ((len = strlen(pBase160)) >= 4) - { - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* Nope. Just increment this value and we're done. */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets base160tab[0], we - * decrement the buffer pointer to get the next higher-order - * digit, and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - } - - return base160; -} diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c deleted file mode 100644 index 223868a6c0a..00000000000 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ /dev/null @@ -1,1940 +0,0 @@ -/* - ldb database library - - Copyright (C) Derrell Lipman 2005 - Copyright (C) Simo Sorce 2005-2009 - - ** 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 sqlite3 backend - * - * Description: core files for SQLITE3 backend - * - * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) - */ - -#include "ldb_module.h" - -#include - -struct lsqlite3_private { - int trans_count; - char **options; - sqlite3 *sqlite; -}; - -struct lsql_context { - struct ldb_module *module; - struct ldb_request *req; - - /* search stuff */ - long long current_eid; - const char * const * attrs; - struct ldb_reply *ares; - - bool callback_failed; - struct tevent_timer *timeout_event; -}; - -/* - * Macros used throughout - */ - -#ifndef FALSE -# define FALSE (0) -# define TRUE (! FALSE) -#endif - -#define RESULT_ATTR_TABLE "temp_result_attrs" - - -/* for testing, define to nothing, (create non-temporary table) */ -#define TEMPTAB "TEMPORARY" - -/* - * Static variables - */ -sqlite3_stmt * stmtGetEID = NULL; - -static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) -{ - char *str, *ret; - va_list ap; - - va_start(ap, fmt); - str = sqlite3_vmprintf(fmt, ap); - va_end(ap); - - if (str == NULL) return NULL; - - ret = talloc_strdup(mem_ctx, str); - if (ret == NULL) { - sqlite3_free(str); - return NULL; - } - - sqlite3_free(str); - return ret; -} - -static char base160tab[161] = { - 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ - 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ - 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ - 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ - 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ - 109,110,111,112,113,114,115,116,117,118, /* m-v */ - 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ - 166,167,168,169,170,171,172,173,174,175, /* latin1 */ - 176,177,178,179,180,181,182,183,184,185, /* latin1 */ - 186,187,188,189,190,191,192,193,194,195, /* latin1 */ - 196,197,198,199,200,201,202,203,204,205, /* latin1 */ - 206,207,208,209,210,211,212,213,214,215, /* latin1 */ - 216,217,218,219,220,221,222,223,224,225, /* latin1 */ - 226,227,228,229,230,231,232,233,234,235, /* latin1 */ - 236,237,238,239,240,241,242,243,244,245, /* latin1 */ - 246,247,248,249,250,251,252,253,254,255, /* latin1 */ - '\0' -}; - - -/* - * base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -static void -base160_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - long long val; - char result[5]; - - val = sqlite3_value_int64(argv[0]); - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; - - sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); -} - - -/* - * base160next_sql() - * - * This function enhances sqlite by adding a "base160_next()" function which is - * accessible via queries. - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) is - * operated on. - * - * Input: - * A character string: either an empty string (in which case no operation is - * performed), or a string of base160 digits with a length of a multiple of - * four digits. - * - * Output: - * Upon return, the trailing four digits (one tree level) will have been - * incremented by 1. - */ -static void -base160next_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - int len; - char * pTab; - char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); - char * pStart = pBase160; - - /* - * We need a minimum of four digits, and we will always get a multiple - * of four digits. - */ - if (pBase160 != NULL && - (len = strlen(pBase160)) >= 4 && - len % 4 == 0) { - - if (pBase160 == NULL) { - - sqlite3_result_null(hContext); - return; - } - - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* - * Nope. Just increment this value and we're - * done. - */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets - * base160tab[0], we decrement the buffer - * pointer to get the next higher-order digit, - * and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - - sqlite3_result_text(hContext, - pStart, - strlen(pStart), - free); - } else { - sqlite3_result_value(hContext, argv[0]); - if (pBase160 != NULL) { - free(pBase160); - } - } -} - -static char *parsetree_to_sql(struct ldb_module *module, - void *mem_ctx, - const struct ldb_parse_tree *t) -{ - struct ldb_context *ldb; - const struct ldb_schema_attribute *a; - struct ldb_val value, subval; - char *wild_card_string; - char *child, *tmp; - char *ret = NULL; - char *attr; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - switch(t->operation) { - case LDB_OP_AND: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); - if (tmp == NULL) return NULL; - } - - ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); - - return ret; - - case LDB_OP_OR: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " UNION %s ", child); - if (tmp == NULL) return NULL; - } - - return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); - - case LDB_OP_NOT: - - child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); - if (child == NULL) return NULL; - - return talloc_asprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE eid NOT IN ( %s ) ", child); - - case LDB_OP_EQUALITY: - /* - * For simple searches, we want to retrieve the list of EIDs that - * match the criteria. - */ - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - if (strcasecmp(t->u.equality.attr, "dn") == 0) { - /* DN query is a special ldb case */ - const char *cdn = ldb_dn_get_casefold( - ldb_dn_new(mem_ctx, ldb, - (const char *)value.data)); - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE norm_dn = '%q'", cdn); - - } else { - /* A normal query. */ - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value = '%q'", - attr, - value.data); - - } - - case LDB_OP_SUBSTRING: - - wild_card_string = talloc_strdup(mem_ctx, - (t->u.substring.start_with_wildcard)?"*":""); - if (wild_card_string == NULL) return NULL; - - for (i = 0; t->u.substring.chunks[i]; i++) { - wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", - t->u.substring.chunks[i]->data); - if (wild_card_string == NULL) return NULL; - } - - if ( ! t->u.substring.end_with_wildcard ) { - /* remove last wildcard */ - wild_card_string[strlen(wild_card_string) - 1] = '\0'; - } - - attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - subval.data = (void *)wild_card_string; - subval.length = strlen(wild_card_string) + 1; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value GLOB '%q'", - attr, - value.data); - - case LDB_OP_GREATER: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_LESS: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_PRESENT: - if (strcasecmp(t->u.present.attr, "dn") == 0) { - return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); - } - - attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); - if (attr == NULL) return NULL; - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' ", - attr); - - case LDB_OP_APPROX: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_EXTENDED: -#warning "work out how to handle bitops" - return NULL; - - default: - break; - }; - - /* should never occur */ - abort(); - return NULL; -} - -/* - * query_int() - * - * This function is used for the common case of queries that return a single - * integer value. - * - * NOTE: If more than one value is returned by the query, all but the first - * one will be ignored. - */ -static int -query_int(const struct lsqlite3_private * lsqlite3, - long long * pRet, - const char * pSql, - ...) -{ - int ret; - int bLoop; - char * p; - sqlite3_stmt * pStmt; - va_list args; - - /* Begin access to variable argument list */ - va_start(args, pSql); - - /* Format the query */ - if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { - va_end(args); - return SQLITE_NOMEM; - } - - /* - * Prepare and execute the SQL statement. Loop allows retrying on - * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, - * requiring retrying the operation. - */ - for (bLoop = TRUE; bLoop; ) { - - /* Compile the SQL statement into sqlite virtual machine */ - if ((ret = sqlite3_prepare(lsqlite3->sqlite, - p, - -1, - &pStmt, - NULL)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - break; - } - - /* One row expected */ - if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - (void) sqlite3_finalize(pStmt); - continue; - } else if (ret != SQLITE_ROW) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* Get the value to be returned */ - *pRet = sqlite3_column_int64(pStmt, 0); - - /* Free the virtual machine */ - if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* - * Normal condition is only one time through loop. Loop is - * rerun in error conditions, via "continue", above. - */ - bLoop = FALSE; - } - - /* All done with variable argument list */ - va_end(args); - - - /* Free the memory we allocated for our query string */ - sqlite3_free(p); - - return ret; -} - -/* - * This is a bad hack to support ldap style comparisons within sqlite. - * val is the attribute in the row currently under test - * func is the desired test "<=" ">=" "~" ":" - * cmp is the value to compare against (eg: "test") - * attr is the attribute name the value of which we want to test - */ - -static void lsqlite3_compare(sqlite3_context *ctx, int argc, - sqlite3_value **argv) -{ - struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); - const char *val = (const char *)sqlite3_value_text(argv[0]); - const char *func = (const char *)sqlite3_value_text(argv[1]); - const char *cmp = (const char *)sqlite3_value_text(argv[2]); - const char *attr = (const char *)sqlite3_value_text(argv[3]); - const struct ldb_schema_attribute *a; - struct ldb_val valX; - struct ldb_val valY; - int ret; - - switch (func[0]) { - /* greater */ - case '>': /* >= */ - a = ldb_schema_attribute_by_name(ldb, attr); - valX.data = (uint8_t *)cmp; - valX.length = strlen(cmp); - valY.data = (uint8_t *)val; - valY.length = strlen(val); - ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); - if (ret >= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* lesser */ - case '<': /* <= */ - a = ldb_schema_attribute_by_name(ldb, attr); - valX.data = (uint8_t *)cmp; - valX.length = strlen(cmp); - valY.data = (uint8_t *)val; - valY.length = strlen(val); - ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); - if (ret <= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* approx */ - case '~': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - /* bitops */ - case ':': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - default: - break; - } - - sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); - return; -} - - -/* rename a record */ -static int lsqlite3_safe_rollback(sqlite3 *sqlite) -{ - char *errmsg; - int ret; - - /* execute */ - ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return 0; -} - -/* return an eid as result */ -static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) -{ - long long *eid = (long long *)result; - - if (col_num != 1) return SQLITE_ABORT; - if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; - - *eid = atoll(cols[0]); - return SQLITE_OK; -} - -/* - * add a single set of ldap message values to a ldb_message - */ -static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) -{ - struct ldb_context *ldb; - struct lsql_context *ac; - struct ldb_message *msg; - long long eid; - unsigned int i; - int ret; - - ac = talloc_get_type(result, struct lsql_context); - ldb = ldb_module_get_ctx(ac->module); - - /* eid, dn, attr_name, attr_value */ - if (col_num != 4) return SQLITE_ABORT; - - eid = atoll(cols[0]); - - if (ac->ares) { - msg = ac->ares->message; - } - - if (eid != ac->current_eid) { /* here begin a new entry */ - - /* call the async callback for the last entry - * except the first time */ - if (ac->current_eid != 0) { - ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); - if (ret != LDB_SUCCESS) { - return SQLITE_ABORT; - } - - ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - ac->callback_failed = true; - /* free msg object */ - TALLOC_FREE(msg); - return SQLITE_ABORT; - } - - /* free msg object */ - TALLOC_FREE(msg); - } - - /* start over */ - ac->ares = talloc_zero(ac, struct ldb_reply); - if (!ac->ares) return SQLITE_ABORT; - - msg = ldb_msg_new(ac->ares); - if (!msg) return SQLITE_ABORT; - - ac->ares->type = LDB_REPLY_ENTRY; - ac->current_eid = eid; - } - - if (msg->dn == NULL) { - msg->dn = ldb_dn_new(msg, ldb, cols[1]); - if (msg->dn == NULL) - return SQLITE_ABORT; - } - - if (ac->attrs) { - int found = 0; - for (i = 0; ac->attrs[i]; i++) { - if (strcasecmp(cols[2], ac->attrs[i]) == 0) { - found = 1; - break; - } - } - if (!found) goto done; - } - - if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { - return SQLITE_ABORT; - } - -done: - ac->ares->message = msg; - return SQLITE_OK; -} - - -/* - * lsqlite3_get_eid() - * lsqlite3_get_eid_ndn() - * - * These functions are used for the very common case of retrieving an EID value - * given a (normalized) DN. - */ - -static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) -{ - char *errmsg; - char *query; - long long eid = -1; - long long ret; - - /* get object eid */ - query = lsqlite3_tprintf(mem_ctx, "SELECT eid " - "FROM ldb_entry " - "WHERE norm_dn = '%q';", norm_dn); - if (query == NULL) return -1; - - ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return eid; -} - -static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, - struct ldb_dn *dn) -{ - TALLOC_CTX *local_ctx; - long long eid = -1; - char *cdn; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(dn)) { - return -1; - } - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); - if (local_ctx == NULL) { - return -1; - } - - cdn = ldb_dn_alloc_casefold(local_ctx, dn); - if (!cdn) goto done; - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); - -done: - talloc_free(local_ctx); - return eid; -} - -/* - * Interface functions referenced by lsqlite3_ops - */ - -/* search for matching records, by tree */ -int lsql_search(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - char *norm_basedn; - char *sqlfilter; - char *errmsg; - char *query = NULL; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if ((( ! ldb_dn_is_valid(req->op.search.base)) || - ldb_dn_is_null(req->op.search.base)) && - (req->op.search.scope == LDB_SCOPE_BASE || - req->op.search.scope == LDB_SCOPE_ONELEVEL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.base) { - norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); - if (norm_basedn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } else norm_basedn = talloc_strdup(ctx, ""); - - /* Convert filter into a series of SQL conditions (constraints) */ - sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); - - switch(req->op.search.scope) { - case LDB_SCOPE_DEFAULT: - case LDB_SCOPE_SUBTREE: - if (*norm_basedn != '\0') { - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" - " OR ldb_entry.norm_dn = '%q')\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - } else { - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - sqlfilter); - } - - break; - - case LDB_SCOPE_BASE: - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.norm_dn = '%q'\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - sqlfilter); - break; - - case LDB_SCOPE_ONELEVEL: - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE norm_dn GLOB('*,%q')\n" - " AND NOT norm_dn GLOB('*,*,%q')\n" - " AND ldb_entry.eid IN\n(%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - break; - } - - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* * / - printf ("%s\n", query); - / * */ - - ctx->current_eid = 0; - ctx->attrs = req->op.search.attrs; - ctx->ares = NULL; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - /* complete the last message if any */ - if (ctx->ares) { - ret = ldb_msg_normalize(ldb, ctx->ares, - ctx->ares->message, - &ctx->ares->message); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_module_send_entry(req, ctx->ares->message, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - - return LDB_SUCCESS; -} - -/* add a record */ -static int lsql_add(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - struct ldb_message *msg = req->op.add.message; - long long eid; - char *dn, *ndn; - char *errmsg; - char *query; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { -/* - struct ldb_dn *c; - c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); - if (ldb_dn_compare(ldb, msg->dn, c) == 0) { -#warning "should we handle indexes somehow ?" - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } -*/ - /* Others return an error */ - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - /* create linearized and normalized dns */ - dn = ldb_dn_alloc_linearized(ctx, msg->dn); - ndn = ldb_dn_alloc_casefold(ctx, msg->dn); - if (dn == NULL || ndn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - query = lsqlite3_tprintf(ctx, - /* Add new entry */ - "INSERT OR ABORT INTO ldb_entry " - "('dn', 'norm_dn') " - "VALUES ('%q', '%q');", - dn, ndn); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a; - char *attr; - unsigned int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(ctx, el->name); - if (attr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - - if (el->num_value == 0) { - ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - char *insert; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - insert = lsqlite3_tprintf(ctx, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - if (insert == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - } - - return LDB_SUCCESS; -} - -/* modify a record */ -static int lsql_modify(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - struct ldb_message *msg = req->op.mod.message; - long long eid; - char *errmsg; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { - /* Others return an error */ - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - eid = lsqlite3_get_eid(lsqlite3, msg->dn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a; - unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; - char *attr; - char *mod; - unsigned int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(ctx, el->name); - if (attr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - - switch (flags) { - - case LDB_FLAG_MOD_REPLACE: - - for (j=0; jnum_values; j++) { - if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { - ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j); - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - } - - /* remove all attributes before adding the replacements */ - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - /* MISSING break is INTENTIONAL */ - - case LDB_FLAG_MOD_ADD: - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = lsqlite3_tprintf(ctx, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - break; - - case LDB_FLAG_MOD_DELETE: -#warning "We should throw an error if the attribute we are trying to delete does not exist!" - if (el->num_values == 0) { - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q' " - "AND norm_attr_value = '%q';", - eid, attr, value.data); - - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - break; - } - } - - return LDB_SUCCESS; -} - -/* delete a record */ -static int lsql_delete(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - long long eid; - char *errmsg; - char *query; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - query = lsqlite3_tprintf(ctx, - /* Delete entry */ - "DELETE FROM ldb_entry WHERE eid = %lld; " - /* Delete attributes */ - "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", - eid, eid); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* rename a record */ -static int lsql_rename(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - char *new_dn, *new_cdn, *old_cdn; - char *errmsg; - char *query; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* create linearized and normalized dns */ - old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); - new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); - new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); - if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* build the SQL query */ - query = lsqlite3_tprintf(ctx, - "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " - "WHERE norm_dn = '%q';", - new_dn, new_cdn, old_cdn); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* execute */ - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int lsql_start_trans(struct ldb_module * module) -{ - int ret; - char *errmsg; - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_start_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - }; - - lsqlite3->trans_count++; - - return 0; -} - -static int lsql_end_trans(struct ldb_module *module) -{ - int ret; - char *errmsg; - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_end_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - } - - return 0; -} - -static int lsql_del_trans(struct ldb_module *module) -{ - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - return lsqlite3_safe_rollback(lsqlite3->sqlite); - } - - return -1; -} - -static int destructor(struct lsqlite3_private *lsqlite3) -{ - if (lsqlite3->sqlite) { - sqlite3_close(lsqlite3->sqlite); - } - return 0; -} - -static void lsql_request_done(struct lsql_context *ctx, int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->error = error; - - req->callback(req, ares); -} - -static void lsql_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lsql_context *ctx; - ctx = talloc_get_type(private_data, struct lsql_context); - - lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void lsql_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lsql_context *ctx; - int ret; - - ctx = talloc_get_type(private_data, struct lsql_context); - - switch (ctx->req->operation) { - case LDB_SEARCH: - ret = lsql_search(ctx); - break; - case LDB_ADD: - ret = lsql_add(ctx); - break; - case LDB_MODIFY: - ret = lsql_modify(ctx); - break; - case LDB_DELETE: - ret = lsql_delete(ctx); - break; - case LDB_RENAME: - ret = lsql_rename(ctx); - break; -/* TODO: - case LDB_EXTENDED: - ret = lsql_extended(ctx); - break; - */ - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - } - - if (!ctx->callback_failed) { - /* Once we are done, we do not need timeout events */ - talloc_free(ctx->timeout_event); - lsql_request_done(ctx, ret); - } -} - -static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct tevent_context *ev; - struct lsql_context *ac; - struct tevent_timer *te; - struct timeval tv; - - if (ldb_check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ldb = ldb_module_get_ctx(module); - ev = ldb_get_event_context(ldb); - - ac = talloc_zero(req, struct lsql_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - tv.tv_sec = req->starttime + req->timeout; - ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); - if (NULL == ac->timeout_event) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* - * Table of operations for the sqlite3 backend - */ -static const struct ldb_module_ops lsqlite3_ops = { - .name = "sqlite", - .search = lsql_handle_request, - .add = lsql_handle_request, - .modify = lsql_handle_request, - .del = lsql_handle_request, - .rename = lsql_handle_request, - .extended = lsql_handle_request, - .start_transaction = lsql_start_trans, - .end_transaction = lsql_end_trans, - .del_transaction = lsql_del_trans, -}; - -/* - * Static functions - */ - -static int initialize(struct lsqlite3_private *lsqlite3, - struct ldb_context *ldb, const char *url, - unsigned int flags) -{ - TALLOC_CTX *local_ctx; - long long queryInt; - int rollback = 0; - char *errmsg; - char *schema; - int ret; - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); - if (local_ctx == NULL) { - return -1; - } - - schema = lsqlite3_tprintf(local_ctx, - - - "CREATE TABLE ldb_info AS " - " SELECT 'LDB' AS database_type," - " '1.0' AS version;" - - /* - * The entry table holds the information about an entry. - * This table is used to obtain the EID of the entry and to - * support scope=one and scope=base. The parent and child - * table is included in the entry table since all the other - * attributes are dependent on EID. - */ - "CREATE TABLE ldb_entry " - "(" - " eid INTEGER PRIMARY KEY AUTOINCREMENT," - " dn TEXT UNIQUE NOT NULL," - " norm_dn TEXT UNIQUE NOT NULL" - ");" - - - "CREATE TABLE ldb_object_classes" - "(" - " class_name TEXT PRIMARY KEY," - " parent_class_name TEXT," - " tree_key TEXT UNIQUE," - " max_child_num INTEGER DEFAULT 0" - ");" - - /* - * We keep a full listing of attribute/value pairs here - */ - "CREATE TABLE ldb_attribute_values" - "(" - " eid INTEGER REFERENCES ldb_entry," - " attr_name TEXT," - " norm_attr_name TEXT," - " attr_value TEXT," - " norm_attr_value TEXT " - ");" - - - /* - * Indexes - */ - "CREATE INDEX ldb_attribute_values_eid_idx " - " ON ldb_attribute_values (eid);" - - "CREATE INDEX ldb_attribute_values_name_value_idx " - " ON ldb_attribute_values (attr_name, norm_attr_value);" - - - - /* - * Triggers - */ - - "CREATE TRIGGER ldb_object_classes_insert_tr" - " AFTER INSERT" - " ON ldb_object_classes" - " FOR EACH ROW" - " BEGIN" - " UPDATE ldb_object_classes" - " SET tree_key = COALESCE(tree_key, " - " (" - " SELECT tree_key || " - " (SELECT base160(max_child_num + 1)" - " FROM ldb_object_classes" - " WHERE class_name = " - " new.parent_class_name)" - " FROM ldb_object_classes " - " WHERE class_name = new.parent_class_name " - " ));" - " UPDATE ldb_object_classes " - " SET max_child_num = max_child_num + 1" - " WHERE class_name = new.parent_class_name;" - " END;" - - /* - * Table initialization - */ - - "INSERT INTO ldb_object_classes " - " (class_name, tree_key) " - " VALUES " - " ('TOP', '0001');"); - - /* Skip protocol indicator of url */ - if (strncmp(url, "sqlite3://", 10) != 0) { - return SQLITE_MISUSE; - } - - /* Update pointer to just after the protocol indicator */ - url += 10; - - /* Try to open the (possibly empty/non-existent) database */ - if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { - return ret; - } - - /* In case this is a new database, enable auto_vacuum */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - if (flags & LDB_FLG_NOSYNC) { - /* DANGEROUS */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } - - /* */ - - /* Establish a busy timeout of 30 seconds */ - if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, - 30000)) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to increment a tree_key */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160_next", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160next_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to convert int to base160 */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to perform various comparisons */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite, /* handle */ - "ldap_compare", /* function name */ - 4, /* number of args */ - SQLITE_ANY, /* preferred text type */ - ldb , /* user data */ - lsqlite3_compare, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Begin a transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: initialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - rollback = 1; - - /* Determine if this is a new database. No tables means it is. */ - if (query_int(lsqlite3, - &queryInt, - "SELECT COUNT(*)\n" - " FROM sqlite_master\n" - " WHERE type = 'table';") != 0) { - goto failed; - } - - if (queryInt == 0) { - /* - * Create the database schema - */ - ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } else { - /* - * Ensure that the database we opened is one of ours - */ - if (query_int(lsqlite3, - &queryInt, - "SELECT " - " (SELECT COUNT(*) = 2" - " FROM sqlite_master " - " WHERE type = 'table' " - " AND name IN " - " (" - " 'ldb_entry', " - " 'ldb_object_classes' " - " ) " - " ) " - " AND " - " (SELECT 1 " - " FROM ldb_info " - " WHERE database_type = 'LDB' " - " AND version = '1.0'" - " );") != 0 || - queryInt != 1) { - - /* It's not one that we created. See ya! */ - goto failed; - } - } - - /* Commit the transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: iniialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - return SQLITE_OK; - -failed: - if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); - sqlite3_close(lsqlite3->sqlite); - return -1; -} - -/* - * connect to the database - */ -static int lsqlite3_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct lsqlite3_private *lsqlite3; - unsigned int i; - int ret; - - module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - lsqlite3 = talloc(module, struct lsqlite3_private); - if (!lsqlite3) { - goto failed; - } - - lsqlite3->sqlite = NULL; - lsqlite3->options = NULL; - lsqlite3->trans_count = 0; - - ret = initialize(lsqlite3, ldb, url, flags); - if (ret != SQLITE_OK) { - goto failed; - } - - talloc_set_destructor(lsqlite3, destructor); - - ldb_module_set_private(module, lsqlite3); - - if (options) { - /* - * take a copy of the options array, so we don't have to rely - * on the caller keeping it around (it might be dynamic) - */ - for (i=0;options[i];i++) ; - - lsqlite3->options = talloc_array(lsqlite3, char *, i+1); - if (!lsqlite3->options) { - goto failed; - } - - for (i=0;options[i];i++) { - - lsqlite3->options[i+1] = NULL; - lsqlite3->options[i] = - talloc_strdup(lsqlite3->options, options[i]); - if (!lsqlite3->options[i]) { - goto failed; - } - } - } - - *_module = module; - return LDB_SUCCESS; - -failed: - if (lsqlite3 && lsqlite3->sqlite != NULL) { - (void) sqlite3_close(lsqlite3->sqlite); - } - talloc_free(lsqlite3); - return LDB_ERR_OPERATIONS_ERROR; -} - -int ldb_sqlite3_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("sqlite3", lsqlite3_connect, false); -} diff --git a/source4/lib/ldb/ldb_sqlite3/schema b/source4/lib/ldb/ldb_sqlite3/schema deleted file mode 100644 index ab7c5cc406f..00000000000 --- a/source4/lib/ldb/ldb_sqlite3/schema +++ /dev/null @@ -1,328 +0,0 @@ - -- ------------------------------------------------------ - - PRAGMA auto_vacuum=1; - - -- ------------------------------------------------------ - - BEGIN EXCLUSIVE; - - -- ------------------------------------------------------ - - CREATE TABLE ldb_info AS - SELECT 'LDB' AS database_type, - '1.0' AS version; - - /* - * Get the next USN value with: - * BEGIN EXCLUSIVE; - * UPDATE usn SET value = value + 1; - * SELECT value FROM usn; - * COMMIT; - */ - CREATE TABLE usn - ( - value INTEGER - ); - - CREATE TABLE ldb_object - ( - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT PRIMARY KEY, - - parent_tree_key TEXT, - dn TEXT, - - attr_name TEXT REFERENCES ldb_attributes, - attr_value TEXT, - - /* - * object_type can take on these values (to date): - * 1: object is a node of a DN - * 2: object is an attribute/value pair of its parent DN - */ - object_type INTEGER, - - /* - * if object_type is 1, the node can have children. - * this tracks the maximum previously assigned child - * number so we can generate a new unique tree key for - * a new child object. note that this is always incremented, - * so if children are deleted, this will not represent - * the _number_ of children. - */ - max_child_num INTEGER, - - /* - * Automatically maintained meta-data (a gift for metze) - */ - object_guid TEXT UNIQUE, - timestamp INTEGER, -- originating_time - invoke_id TEXT, -- GUID: originating_invocation_id - usn INTEGER, -- hyper: originating_usn - - /* do not allow duplicate name/value pairs */ - UNIQUE (parent_tree_key, attr_name, attr_value, object_type) - ); - - CREATE TABLE ldb_attributes - ( - attr_name TEXT PRIMARY KEY, - parent_tree_key TEXT, - - objectclass_p BOOLEAN DEFAULT 0, - - case_insensitive_p BOOLEAN DEFAULT 0, - wildcard_p BOOLEAN DEFAULT 0, - hidden_p BOOLEAN DEFAULT 0, - integer_p BOOLEAN DEFAULT 0, - - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT, -- null if not a object/sub class - -- level 1 if an objectclass - -- level 1-n if a subclass - max_child_num INTEGER - ); - - -- ------------------------------------------------------ - - CREATE INDEX ldb_object_dn_idx - ON ldb_object (dn); - - CREATE INDEX ldb_attributes_tree_key_ids - ON ldb_attributes (tree_key); - - -- ------------------------------------------------------ - - /* Gifts for metze. Automatically updated meta-data */ - CREATE TRIGGER ldb_object_insert_tr - AFTER INSERT - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE ldb_object - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_object - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0, - object_guid = random_guid(), - timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_object_update_tr - AFTER UPDATE - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_attributes_insert_tr - AFTER INSERT - ON ldb_attributes - FOR EACH ROW - BEGIN - UPDATE ldb_attributes - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE ldb_attributes - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_attributes - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0 - WHERE tree_key = new.tree_key; - END; - - - -- ------------------------------------------------------ - - /* Initialize usn */ - INSERT INTO usn (value) VALUES (0); - - /* Create root object */ - INSERT INTO ldb_object - (tree_key, parent_tree_key, - dn, - object_type, max_child_num) - VALUES ('', NULL, - '', - 1, 0); - - /* We need an implicit "top" level object class */ - INSERT INTO ldb_attributes (attr_name, - parent_tree_key) - SELECT 'top', ''; - - -- ------------------------------------------------------ - - COMMIT; - - -- ------------------------------------------------------ - -/* - * dn: o=University of Michigan,c=US - * objectclass: organization - * objectclass: domainRelatedObject - */ --- newDN -BEGIN; - -INSERT OR IGNORE INTO ldb_object - (parent_tree_key - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('', - 'c=US', - 'c', 'US', 1, 0); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('0001', - 'o=University of Michigan,c=US', - 'o', 'University of Michigan', 1, 0); - --- newObjectClass -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'organization', 2, 0); - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'domainRelatedObject', 2, 0); - -COMMIT; - - -/* - * dn: o=University of Michigan,c=US - * l: Ann Arbor, Michigan - * st: Michigan - * o: University of Michigan - * o: UMICH - * seeAlso: - * telephonenumber: +1 313 764-1817 - */ --- addAttrValuePair -BEGIN; - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'l', 'Ann Arbor, Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'st', 'Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'University of Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'UMICH', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'seeAlso', '', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'telephonenumber', '+1 313 764-1817', 2, 0); - -COMMIT; - --- ---------------------------------------------------------------------- - -/* - * dn: @ATTRIBUTES - * uid: CASE_INSENSITIVE WILDCARD - * cn: CASE_INSENSITIVE - * ou: CASE_INSENSITIVE - * dn: CASE_INSENSITIVE - */ --- newAttribute - -BEGIN; - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('uid', '', 0); - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 1, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'uid' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'cn' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'ou' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'dn' - diff --git a/source4/lib/ldb/ldb_sqlite3/trees.ps b/source4/lib/ldb/ldb_sqlite3/trees.ps deleted file mode 100644 index 433a064816c..00000000000 --- a/source4/lib/ldb/ldb_sqlite3/trees.ps +++ /dev/null @@ -1,1760 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software -%%Title: trees.dvi -%%Pages: 7 -%%PageOrder: Ascend -%%BoundingBox: 0 0 596 842 -%%EndComments -%DVIPSWebPage: (www.radicaleye.com) -%DVIPSCommandLine: dvips -f trees.dvi -%DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2000.05.06:2055 -%%BeginProcSet: texc.pro -%! -/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S -N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 -mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 -0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ -landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize -mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ -matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round -exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ -statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] -N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin -/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array -/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 -array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N -df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A -definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get -}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} -B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr -1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 -1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx -0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx -sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ -rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp -gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B -/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ -/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ -A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy -get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} -ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp -fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 -{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add -chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ -1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} -forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn -/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put -}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ -bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A -mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ -SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ -userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X -1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 -index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N -/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ -/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) -(LaserWriter 16/600)]{A length product length le{A length product exch 0 -exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse -end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask -grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} -imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round -exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto -fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p -delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} -B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ -p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S -rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end - -%%EndProcSet -TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) -@start -%DVIPSBitmapFont: Fa cmr10 10 6 -/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B -120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 -6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 -D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F -A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 -5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 -F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DI54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fb cmr7 7 3 -/Fb 3 55 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 -15267BA521>I54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fc cmmi10 10 1 -/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 -0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 -0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 -7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 -49EC7FC0B8C8FC16FC16C03E397DB845>68 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fd ectt1000 10 73 -/Fd 73 126 df37 -D39 -D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F -5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F -12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> -I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 -A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F -1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< -EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 -E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB -07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 -12E0B712F8A4C700F8C7FCB0147025267DAB2C>II<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 -D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F -92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 -7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 -7021417BB92C>II<1307497EA2131F -A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 -E01C3477B32C>II<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 -9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E -B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C -000114C06C6C90C7FCEB0FF823347CB22C>53 DI<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A -5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A -A5133F91C8FCAA131E23357CB32C>I59 D<1502ED0F80151F157F15 -FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 -C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 -6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED -0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 -25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 -FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC -0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F -F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 -A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 -4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC -497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 -03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F -E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 -E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 -13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 -7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C -130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 -25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED -0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 -153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 -B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC -A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 -F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C -7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC -01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE -5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D -137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 -7DB32C>II<007FB512F8B612FCA36C14 -F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 -ED01F8A8007FB6FCB7FCA36C15F025337DB22C>IIII<007FB512C0B612 -F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 -ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E -B22C>II<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 -6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F -81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 -381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE -143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C -14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC -A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 -D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 -B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C -13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC -E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>III<3A3FFF03FFE0484913F0148714076C6D13E03A01 -F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D -90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB -7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE -6C15FC497E27337EB22C>II<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC -17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 -7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E -A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED -070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 -7DB92C>II<007FB6FCB71280A46C150021067B7D -2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC -5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 -000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF -FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 -383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>II<90 -3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC -5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A -6C5C6C6C5B011F13E0010390C7FC21247AA32C>III103 -DI< -1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F -B512FCB612FEA36C14FC1F3479B32C>I107 D<387FFFE0B57EA37EEA0003B3B3A5007F -B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 -7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 -3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F -F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B -5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>II<397FF01FE0 -39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 -5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 -9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 -7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 -48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F -6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A -1480A36E140029367DA32C>II<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB -00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 -FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 -148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 -ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 -2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 -00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 -8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 -3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 -E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC -140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F -806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D -A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 -14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 -27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F -E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E -1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>II E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fe ecti1000 10 33 -/Fe 33 122 df28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 -495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC -A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 -001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C -AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 -A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC -120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 -18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 -140E140CA3141C1418A2333275AD40>43 DI<120E -EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 -F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 -5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F -4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 -7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 -D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC -A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 -7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 -1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 -0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 -1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 -D79 -D81 D<92383FC00E913901FFF01C020713FC91 -391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F -15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 -80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A -A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 -8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A -D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F -C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C -A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F -871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F -5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF -076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 -D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F -80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 -0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 -C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 -70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F -90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 -380F81F83803FFE0C690C7FC1D2677A426>II<147F903803FFC090380FC1E09038 -3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 -FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C -EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>IIIII108 -DII<147F903803FFC090380FC1F090381F00F8 -017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A -4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E -6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 -3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C -A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A -6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 -03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A -3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 -015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 -D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 -15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 -0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC -1C267AA422>II<01F013 -0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 -0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 -0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 -D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 -13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C -A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E -EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 -D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 -1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D -A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 -133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 -3679A428>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Ff cmsy10 10 1 -/Ff 1 16 df15 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fg ecbx1000 10 36 -/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF -8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 -C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D45 -DI<141E143E -14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 -DI54 D58 D66 DII73 -D76 DII< -EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 -6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 -3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C -4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 -C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>III83 D85 DII<13 -FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB -3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 -C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 -35>98 D100 -D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC -1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F -6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 -257DA42C>II<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 -8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 -FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 -6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C -6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< -EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 -A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED -1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 -6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 -D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 -FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA -CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 -A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 -13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 -FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 -491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C -6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB -0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC -91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F -383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C -14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 -F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B -5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 -3FFFC06D1380903803FE001D357EB425>I118 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fh ecrm1000 10 89 -/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 -0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 -A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 -3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 -12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I21 D27 -DI30 D36 D<141FEC7FC0903801F0 -E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 -5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED -0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F -1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 -3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 -6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 -26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 -1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 -C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E -A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E -7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E -6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F -80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A -5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 -D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A -12600A19798817>II<121C127FEAFF80A5EA7F00121C09097988 -17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 -0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 -91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 -90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A ->II -III<1538A2157815F8A214011403 -1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 -1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA -4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 -92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C -7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A -5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A ->II<12301238123E003FB612E0A316C05A168016 -000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C -1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A -7BB72A>III<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A -1206120E5A5A5A12600A3479A317>II<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 -EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 -1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 -ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 -1ECBFC127812E0322E79AB41>II<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 -0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 -7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E -A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 -DI<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 -FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 -48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 -3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 -5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D -7BBA3C>IIIIIII<013FB512 -E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C -5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>IIIIIIIII< -D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F -003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 -F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 -151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D -EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< -003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 -A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>IIII89 D<003FB7FCA39039FC0001FE -01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 -FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB -0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 -48495A49130FB8FCA329397BB833>II93 D<007FB81280B912C0A26C17 -803204797041>95 D97 DIIII<147E903803FF8090 -380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC -B3AB487E387FFFF8A31C3B7FBA19>IIIIIII<2703F00FF0EB1FE000FFD93FFCEB -7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC -49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 ->I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E -A25BA35BB3A3486C497EB500C1B51280A329257EA42E>II<3903F01F -E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 -49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 -C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> -II<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 -9038FC0080491300A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F812011203 -1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE -EB01F81A347FB220>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038 -EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A -A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 -EB03FC90B5FCA21F247EA325>II<126012F0B3B3B3 -B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 -07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C -133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fi ecbx1440 14.4 34 -/Fi 34 118 df28 D45 D<151E153E15FE1403140F147FEB07FF00 -03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 -DI<913807FFC0027F13FC0103B67E010F15E090 -261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 -17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 -030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 -138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 -FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F -FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 ->I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 -FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C -49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 -FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A -5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 -B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 -16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 -E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF -E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I58 -D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF -5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F -498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 -98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F -7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F -01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 -801303040301F8CAFC595479D267>71 D73 D76 -D78 D80 D<93381FFF800303B512FC033FECFFC0 -92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E -7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 -86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 -A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 -EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 -7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 -C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB -83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 -1C00735B735B735B735B9638003FC0556A79D263>III<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 -49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 -B912C0A550517BD05B>I97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB -07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 -C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E -6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 -138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 -49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 -4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D -5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F -010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 -076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 -90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 -3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A -D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C ->IIII<133FEBFFC0 -487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 -12F0A51C547CD324>I108 -DII<913801FFC0023F13FE91B67E010315E001 -0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 -488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F -A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE -6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>II<90393FF001FCB590 -380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 -80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 -D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 -1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C -14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 -150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 -39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 -14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F -FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F -1380DA03FEC7FC294D7ECB33>II E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fj ecrm0900 9 5 -/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D97 DI104 -D108 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fk ecbx0900 9 7 -/Fk 7 117 df65 D97 DI<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 -A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 -07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF -EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 -1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 -5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB -007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 -E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 -FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I -E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fl ecrm1200 12 25 -/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 -80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 -3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 -F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 -6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 -F8903807FFE0010090C7FC28447CC131>48 D50 D54 D<16C04B7EA34B7EA34B7EA34B7EA3ED -19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 -06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 -C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 -D80FFF03037FB500E0027FEBFFC0A342477DC649>65 DI68 D77 -D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 -181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 -D -I97 -D99 D<167FED3FFFA315018182B3EC7F80903803 -FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 -127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C -010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>II103 D105 D108 D<3901FC01FE00FF903807FFC091381E -07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 -486CECFF80B5D8F83F13FEA32F2C7DAB36>110 DI<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 -7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 -D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 -1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 -011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 -F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E -A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C -017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 ->III< -B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 -6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 -FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 -06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 -F02E3F7EAA33>121 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fm ecbx1200 12 47 -/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A -001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 -F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 -006C486D5AD801F0EB00F82A2283C427>16 DI28 D46 D48 DIII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 -C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B -485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 -7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 -FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E -01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 -F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB -FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 -027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 -5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F -FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 -5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D -4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 -3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 -7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A -5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A -6D5A2F447AC238>I58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 -FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA -07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 -EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 -007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 -FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 -19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB -3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF -9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 -0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF -80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED -1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE -CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 -0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 -D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D -7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 -E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 -007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E -6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C -6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C -7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC -49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 -DIIII73 D77 D<923807FFC092B512FE0207ECFFC0021F15F0 -91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 -6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 -82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 -F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D -6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 -004AC8FC030713C047467AC454>79 D83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D -7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 -90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B -127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 -6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 DIIIIIII<137C48B4FC4813804813C0A24813E0A56C13 -C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> -I108 D<90277F8007FEEC0FFC -B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D -8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E -A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 -3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 -F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>II<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F -FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF -3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F -FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>II<90387F807FB53881FFE002 -8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED -01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F -381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F -FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 -F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A -00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>II< -D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 -13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I -I120 -D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 -3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 -48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 -292C7DAB32>122 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fn ecrm1728 17.28 8 -/Fn 8 117 df68 D70 D97 D102 D<1378EA01FE487E487FA66C -90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F -B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 -3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB -0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 -D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 -1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE -381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F -13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 -077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 -12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 -0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 -80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 -FC2A597ED734>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fo ecbx1728 17.28 18 -/Fo 18 117 df68 D<942603FFF8151C94B66C -143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 -B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF -91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 -075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F -B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F -6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 -C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B -C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 -D82 D<001FBD12F0A59126F8000191C7123F4801C0 -060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC -A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 -D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 -6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC -90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 -FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF -6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 -C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B -C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 -12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B -6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F -1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F -C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 -4C657CE356>II101 DII105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 -12E0A523647CE32A>108 D110 D<92381FFF804AB512F8020F -14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 -486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 -C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F -6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D -9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF -8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF -806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 -851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B -6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 -3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I114 DII E -%EndDVIPSBitmapFont -end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%PaperSize: A4 - -%%EndSetup -%%Page: 1 1 -1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 -b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 -1063 y Fm(Miguel)36 b(Sofer)i()1359 1179 -y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 -b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 -1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 -2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 -b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f -(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g -(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 -2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h -(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 -b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i -(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 -2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n -(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 -b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 -2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g -(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e -(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h -(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h -(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) -220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 -b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h -(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 -3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g -(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g -(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 -b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 -b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r -(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f -(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h -(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h -(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g -(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g -(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 -4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n -(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i -(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 -b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r -(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h -(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n -(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 -b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r -(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f -(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e -(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r -(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 -b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f -(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 -b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h -(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n -(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f -(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 -b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n -(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) -49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 -5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f -(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop -%%Page: 2 2 -2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f -(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y -Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j -Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 -b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f -(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 -908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h -(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 -1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f -(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 -b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 -b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g -(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n -(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) -h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 -1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 -b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g -(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 -y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 -b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g -(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 -b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 -1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 -y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h -(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) -h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 -2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) -n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) -n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 -2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g -(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 -b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 -2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 -2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) -g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g -(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 -y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i -(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g -(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f -(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f -(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 -y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g -(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 -b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i -(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h -(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 -2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) -243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g -(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 -b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 -b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 -3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r -(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f -(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) -h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h -(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 -4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 -4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n -(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h -(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f -(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) -k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 -4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) -h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) -40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r -(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 -y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) -243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f -(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f -(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h -(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) -n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h -(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 -5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) -g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 -5653 y(2)p eop -%%Page: 3 3 -3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 -b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 -b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 -b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g -(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g -(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 -b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f -(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 -b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 -b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 -b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g -(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h -(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h -(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 -942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h -(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) -h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 -y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g -(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h -Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g -(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d -(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 -1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 -b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n -(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 -y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f -(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f -(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 -y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y -Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i -(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g -(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 -y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h -(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f -(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 -b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n -(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) -f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i -(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 -b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r -(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 -2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h -(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e -(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 -2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f -(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g -(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 -3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f -(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h -(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h -(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 -b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 -3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f -(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n -(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f -(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g -(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g -(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j -(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e -(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h -(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e -(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 -b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g -(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h -Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h -(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) -h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e -Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 -b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r -(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g -Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 -4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f -(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g -(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g -(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i -(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) -67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 -b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f -(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 -4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 -b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g -(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h -(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 -b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f -(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f -(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h -(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n -(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f -(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f -(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 -b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h -(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g -(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h -(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 -b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f -(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g -(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h -(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f -(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h -(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 -y(forest.)1987 5653 y(3)p eop -%%Page: 4 4 -4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h -(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g -(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 -b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h -(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n -(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f -(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 -771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g -(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 -1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 -b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f -(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 -1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 -b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n -(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b -Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r -(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 -1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h -(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 -2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) -118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g -(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r -(eration,)f(no)i(table)f(access)g(is)g(required.)243 -2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f -(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y -Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f -(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f -(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 -b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 -y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 -3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i -(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y -Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 -3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 -b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 -4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g -('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 -b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n -(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 -b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 -5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 -b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 -5653 y Fh(4)p eop -%%Page: 5 5 -5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h -(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l -(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 -543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 -b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g -(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r -(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 -b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 -743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f -(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d -(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 -b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 -b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f -(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k -(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 -1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) -g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h -(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 -b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f -(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i -(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 -b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h -(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 -b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j -(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r -(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 -b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r -(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f -(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 -2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) -118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f -(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h -(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g -(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y -Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e -(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 -b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 -2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e -(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j -(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 -3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 -3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 -b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 -y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 -b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 -b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g -(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 -b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 -4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l -(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f -(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 -b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 -b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y -Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o -(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 -b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 -b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g -(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f()243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) -r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n -(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 -b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h -(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f -(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop -%%Page: 6 6 -6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 -444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f -(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 -b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d -(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 -b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 -b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) -413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 -y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o -(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f -('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g -(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h -(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 -1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f -(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e -(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 -b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 -1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 -2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o -(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 -2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y -Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g -(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n -(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n -(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o -(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 -2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 -b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h -(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 -3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e -(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h -(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 -y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 -b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 -b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 -4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 -y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 -b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r -(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h -(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h -(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n -(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 -b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g -(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 -4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h -(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h -(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n -(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n -(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g -(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 -5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p -eop -%%Page: 7 7 -7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n -(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n -(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 -556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e -(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n -(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g -(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 -822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i -(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h -(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 -1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 -y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) -r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f -(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 -b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 -1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 -b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p -Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 -y Fh()160 2200 -y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p -Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) -289 2299 y()289 -2399 y()289 -2498 y()289 -2598 y()160 -2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 -b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 -y()1987 5653 -y(7)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c deleted file mode 100644 index e54ceaaa98a..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ /dev/null @@ -1,490 +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 tdb cache functions - * - * Description: cache special records in a ldb/tdb - * - * Author: Andrew Tridgell - */ - -#include "ldb_tdb.h" -#include "ldb_private.h" - -#define LTDB_FLAG_CASE_INSENSITIVE (1<<0) -#define LTDB_FLAG_INTEGER (1<<1) -#define LTDB_FLAG_HIDDEN (1<<2) - -/* valid attribute flags */ -static const struct { - const char *name; - int value; -} ltdb_valid_attr_flags[] = { - { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE }, - { "INTEGER", LTDB_FLAG_INTEGER }, - { "HIDDEN", LTDB_FLAG_HIDDEN }, - { "NONE", 0 }, - { NULL, 0 } -}; - - -/* - de-register any special handlers for @ATTRIBUTES -*/ -static void ltdb_attributes_unload(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - struct ldb_message *msg; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - if (ltdb->cache->attributes == NULL) { - /* no previously loaded attributes */ - return; - } - - msg = ltdb->cache->attributes; - for (i=0;inum_elements;i++) { - ldb_schema_attribute_remove(ldb, msg->elements[i].name); - } - - talloc_free(ltdb->cache->attributes); - ltdb->cache->attributes = NULL; -} - -/* - add up the attrib flags for a @ATTRIBUTES element -*/ -static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) -{ - unsigned int i; - unsigned value = 0; - for (i=0;inum_values;i++) { - unsigned int j; - for (j=0;ltdb_valid_attr_flags[j].name;j++) { - if (strcmp(ltdb_valid_attr_flags[j].name, - (char *)el->values[i].data) == 0) { - value |= ltdb_valid_attr_flags[j].value; - break; - } - } - if (ltdb_valid_attr_flags[j].name == NULL) { - return -1; - } - } - *v = value; - return 0; -} - -/* - register any special handlers from @ATTRIBUTES -*/ -static int ltdb_attributes_load(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - struct ldb_message *msg = ltdb->cache->attributes; - struct ldb_dn *dn; - unsigned int i; - int r; - - ldb = ldb_module_get_ctx(module); - - if (ldb->schema.attribute_handler_override) { - /* we skip loading the @ATTRIBUTES record when a module is supplying - its own attribute handling */ - return 0; - } - - dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES); - if (dn == NULL) goto failed; - - r = ltdb_search_dn1(module, dn, msg); - talloc_free(dn); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } - if (r == LDB_ERR_NO_SUCH_OBJECT) { - return 0; - } - /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, - but its close enough for now */ - for (i=0;inum_elements;i++) { - unsigned flags; - const char *syntax; - const struct ldb_schema_syntax *s; - - if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name); - goto failed; - } - switch (flags & ~LTDB_FLAG_HIDDEN) { - case 0: - syntax = LDB_SYNTAX_OCTET_STRING; - break; - case LTDB_FLAG_CASE_INSENSITIVE: - syntax = LDB_SYNTAX_DIRECTORY_STRING; - break; - case LTDB_FLAG_INTEGER: - syntax = LDB_SYNTAX_INTEGER; - break; - default: - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES", - flags, msg->elements[i].name); - goto failed; - } - - s = ldb_standard_syntax_by_name(ldb, syntax); - if (s == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES", - syntax, msg->elements[i].name); - goto failed; - } - - flags |= LDB_ATTR_FLAG_ALLOCATED; - if (ldb_schema_attribute_add_with_syntax(ldb, msg->elements[i].name, flags, s) != 0) { - goto failed; - } - } - - return 0; -failed: - return -1; -} - - -/* - initialise the baseinfo record -*/ -static int ltdb_baseinfo_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - struct ldb_message *msg; - struct ldb_message_element el; - struct ldb_val val; - int ret; - /* the initial sequence number must be different from the one - set in ltdb_cache_free(). Thanks to Jon for pointing this - out. */ - const char *initial_sequence_number = "1"; - - ldb = ldb_module_get_ctx(module); - - ltdb->sequence_number = atof(initial_sequence_number); - - msg = ldb_msg_new(ltdb); - if (msg == NULL) { - goto failed; - } - - msg->num_elements = 1; - msg->elements = ⪙ - msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO); - if (!msg->dn) { - goto failed; - } - el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); - if (!el.name) { - goto failed; - } - el.values = &val; - el.num_values = 1; - el.flags = 0; - val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); - if (!val.data) { - goto failed; - } - val.length = 1; - - ret = ltdb_store(module, msg, TDB_INSERT); - - talloc_free(msg); - - return ret; - -failed: - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - free any cache records - */ -static void ltdb_cache_free(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - - ltdb->sequence_number = 0; - talloc_free(ltdb->cache); - ltdb->cache = NULL; -} - -/* - force a cache reload -*/ -int ltdb_cache_reload(struct ldb_module *module) -{ - ltdb_attributes_unload(module); - ltdb_cache_free(module); - return ltdb_cache_load(module); -} - -/* - load the cache records -*/ -int ltdb_cache_load(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL; - struct ldb_dn *indexlist_dn = NULL; - uint64_t seq; - struct ldb_message *baseinfo = NULL, *options = NULL; - int r; - - ldb = ldb_module_get_ctx(module); - - /* a very fast check to avoid extra database reads */ - if (ltdb->cache != NULL && - tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) { - return 0; - } - - if (ltdb->cache == NULL) { - ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); - if (ltdb->cache == NULL) goto failed; - ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); - ltdb->cache->attributes = ldb_msg_new(ltdb->cache); - if (ltdb->cache->indexlist == NULL || - ltdb->cache->attributes == NULL) { - goto failed; - } - } - - baseinfo = ldb_msg_new(ltdb->cache); - if (baseinfo == NULL) goto failed; - - baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO); - if (baseinfo_dn == NULL) goto failed; - - r= ltdb_search_dn1(module, baseinfo_dn, baseinfo); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } - - /* possibly initialise the baseinfo */ - if (r == LDB_ERR_NO_SUCH_OBJECT) { - if (ltdb_baseinfo_init(module) != LDB_SUCCESS) { - goto failed; - } - if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) != LDB_SUCCESS) { - goto failed; - } - } - - ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); - - /* if the current internal sequence number is the same as the one - in the database then assume the rest of the cache is OK */ - seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0); - if (seq == ltdb->sequence_number) { - goto done; - } - ltdb->sequence_number = seq; - - /* Read an interpret database options */ - options = ldb_msg_new(ltdb->cache); - if (options == NULL) goto failed; - - options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS); - if (options_dn == NULL) goto failed; - - r= ltdb_search_dn1(module, options_dn, options); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } - - /* set flag for checking base DN on searches */ - if (r == LDB_SUCCESS) { - ltdb->check_base = ldb_msg_find_attr_as_bool(options, LTDB_CHECK_BASE, false); - } else { - ltdb->check_base = false; - } - - talloc_free(ltdb->cache->indexlist); - ltdb_attributes_unload(module); /* calls internally "talloc_free" */ - - ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); - ltdb->cache->attributes = ldb_msg_new(ltdb->cache); - if (ltdb->cache->indexlist == NULL || - ltdb->cache->attributes == NULL) { - goto failed; - } - ltdb->cache->one_level_indexes = false; - ltdb->cache->attribute_indexes = false; - - indexlist_dn = ldb_dn_new(module, ldb, LTDB_INDEXLIST); - if (indexlist_dn == NULL) goto failed; - - r = ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } - - if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) { - ltdb->cache->one_level_indexes = true; - } - if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) { - ltdb->cache->attribute_indexes = true; - } - - if (ltdb_attributes_load(module) == -1) { - goto failed; - } - -done: - talloc_free(options); - talloc_free(baseinfo); - talloc_free(indexlist_dn); - return 0; - -failed: - talloc_free(options); - talloc_free(baseinfo); - talloc_free(indexlist_dn); - return -1; -} - - -/* - increase the sequence number to indicate a database change -*/ -int ltdb_increase_sequence_number(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - struct ldb_message *msg; - struct ldb_message_element el[2]; - struct ldb_val val; - struct ldb_val val_time; - time_t t = time(NULL); - char *s = NULL; - int ret; - - ldb = ldb_module_get_ctx(module); - - msg = ldb_msg_new(ltdb); - if (msg == NULL) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1); - if (!s) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->num_elements = ARRAY_SIZE(el); - msg->elements = el; - msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO); - if (msg->dn == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); - if (el[0].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[0].values = &val; - el[0].num_values = 1; - el[0].flags = LDB_FLAG_MOD_REPLACE; - val.data = (uint8_t *)s; - val.length = strlen(s); - - el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP); - if (el[1].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[1].values = &val_time; - el[1].num_values = 1; - el[1].flags = LDB_FLAG_MOD_REPLACE; - - s = ldb_timestring(msg, t); - if (s == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - val_time.data = (uint8_t *)s; - val_time.length = strlen(s); - - ret = ltdb_modify_internal(module, msg, NULL); - - talloc_free(msg); - - if (ret == LDB_SUCCESS) { - ltdb->sequence_number += 1; - } - - /* updating the tdb_seqnum here avoids us reloading the cache - records due to our own modification */ - ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); - - return ret; -} - -int ltdb_check_at_attributes_values(const struct ldb_val *value) -{ - unsigned int i; - - for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) { - if ((strcmp(ltdb_valid_attr_flags[i].name, (char *)value->data) == 0)) { - return 0; - } - } - - return -1; -} - diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c deleted file mode 100644 index 24cc93feb94..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ /dev/null @@ -1,1599 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004-2009 - - ** 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 tdb backend - indexing - * - * Description: indexing routines for ldb tdb backend - * - * Author: Andrew Tridgell - */ - -#include "ldb_tdb.h" - -struct dn_list { - unsigned int count; - struct ldb_val *dn; -}; - -struct ltdb_idxptr { - struct tdb_context *itdb; - int error; -}; - -/* we put a @IDXVERSION attribute on index entries. This - allows us to tell if it was written by an older version -*/ -#define LTDB_INDEXING_VERSION 2 - -/* enable the idxptr mode when transactions start */ -int ltdb_index_transaction_start(struct ldb_module *module) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr); - return LDB_SUCCESS; -} - -/* compare two DN entries in a dn_list. Take account of possible - * differences in string termination */ -static int dn_list_cmp(const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length > v2->length && v1->data[v2->length] != 0) { - return -1; - } - if (v1->length < v2->length && v2->data[v1->length] != 0) { - return 1; - } - return strncmp((char *)v1->data, (char *)v2->data, v1->length); -} - - -/* - find a entry in a dn_list, using a ldb_val. Uses a case sensitive - comparison with the dn returns -1 if not found - */ -static int ltdb_dn_list_find_val(const struct dn_list *list, const struct ldb_val *v) -{ - unsigned int i; - for (i=0; icount; i++) { - if (dn_list_cmp(&list->dn[i], v) == 0) return i; - } - return -1; -} - -/* - find a entry in a dn_list. Uses a case sensitive comparison with the dn - returns -1 if not found - */ -static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn) -{ - struct ldb_val v; - v.data = discard_const_p(unsigned char, dn); - v.length = strlen(dn); - return ltdb_dn_list_find_val(list, &v); -} - -/* - this is effectively a cast function, but with lots of paranoia - checks and also copes with CPUs that are fussy about pointer - alignment - */ -static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent) -{ - struct dn_list *list; - if (rec.dsize != sizeof(void *)) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Bad data size for idxptr %u", (unsigned)rec.dsize); - return NULL; - } - /* note that we can't just use a cast here, as rec.dptr may - not be aligned sufficiently for a pointer. A cast would cause - platforms like some ARM CPUs to crash */ - memcpy(&list, rec.dptr, sizeof(void *)); - list = talloc_get_type(list, struct dn_list); - if (list == NULL) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Bad type '%s' for idxptr", - talloc_get_name(list)); - return NULL; - } - if (check_parent && list->dn && talloc_parent(list->dn) != list) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Bad parent '%s' for idxptr", - talloc_get_name(talloc_parent(list->dn))); - return NULL; - } - return list; -} - -/* - return the @IDX list in an index entry for a dn as a - struct dn_list - */ -static int ltdb_dn_list_load(struct ldb_module *module, - struct ldb_dn *dn, struct dn_list *list) -{ - struct ldb_message *msg; - int ret; - struct ldb_message_element *el; - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - TDB_DATA rec; - struct dn_list *list2; - TDB_DATA key; - - list->dn = NULL; - list->count = 0; - - /* see if we have any in-memory index entries */ - if (ltdb->idxptr == NULL || - ltdb->idxptr->itdb == NULL) { - goto normal_index; - } - - key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); - key.dsize = strlen((char *)key.dptr); - - rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); - if (rec.dptr == NULL) { - goto normal_index; - } - - /* we've found an in-memory index entry */ - list2 = ltdb_index_idxptr(module, rec, true); - if (list2 == NULL) { - free(rec.dptr); - return LDB_ERR_OPERATIONS_ERROR; - } - free(rec.dptr); - - *list = *list2; - return LDB_SUCCESS; - -normal_index: - msg = ldb_msg_new(list); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_search_dn1(module, dn, msg); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - - /* TODO: check indexing version number */ - - el = ldb_msg_find_element(msg, LTDB_IDX); - if (!el) { - talloc_free(msg); - return LDB_SUCCESS; - } - - /* we avoid copying the strings by stealing the list */ - list->dn = talloc_steal(list, el->values); - list->count = el->num_values; - - return LDB_SUCCESS; -} - - -/* - save a dn_list into a full @IDX style record - */ -static int ltdb_dn_list_store_full(struct ldb_module *module, struct ldb_dn *dn, - struct dn_list *list) -{ - struct ldb_message *msg; - int ret; - - if (list->count == 0) { - ret = ltdb_delete_noindex(module, dn); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return LDB_SUCCESS; - } - return ret; - } - - msg = ldb_msg_new(module); - if (!msg) { - return ldb_module_oom(module); - } - - ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ldb_module_oom(module); - } - - msg->dn = dn; - if (list->count > 0) { - struct ldb_message_element *el; - - ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ldb_module_oom(module); - } - el->values = list->dn; - el->num_values = list->count; - } - - ret = ltdb_store(module, msg, TDB_REPLACE); - talloc_free(msg); - return ret; -} - -/* - save a dn_list into the database, in either @IDX or internal format - */ -static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, - struct dn_list *list) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - TDB_DATA rec, key; - int ret; - struct dn_list *list2; - - if (ltdb->idxptr == NULL) { - return ltdb_dn_list_store_full(module, dn, list); - } - - if (ltdb->idxptr->itdb == NULL) { - ltdb->idxptr->itdb = tdb_open_compat(NULL, 1000, TDB_INTERNAL, O_RDWR, 0, NULL, NULL); - if (ltdb->idxptr->itdb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); - key.dsize = strlen((char *)key.dptr); - - rec = tdb_fetch_compat(ltdb->idxptr->itdb, key); - if (rec.dptr != NULL) { - list2 = ltdb_index_idxptr(module, rec, false); - if (list2 == NULL) { - free(rec.dptr); - return LDB_ERR_OPERATIONS_ERROR; - } - free(rec.dptr); - list2->dn = talloc_steal(list2, list->dn); - list2->count = list->count; - return LDB_SUCCESS; - } - - list2 = talloc(ltdb->idxptr, struct dn_list); - if (list2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - list2->dn = talloc_steal(list2, list->dn); - list2->count = list->count; - - rec.dptr = (uint8_t *)&list2; - rec.dsize = sizeof(void *); - - ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT); - if (ret != 0) { - return ltdb_err_map(tdb_error(ltdb->idxptr->itdb)); - } - return LDB_SUCCESS; -} - -/* - traverse function for storing the in-memory index entries on disk - */ -static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_module *module = state; - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - struct ldb_dn *dn; - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_val v; - struct dn_list *list; - - list = ltdb_index_idxptr(module, data, true); - if (list == NULL) { - ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - v.data = key.dptr; - v.length = strnlen((char *)key.dptr, key.dsize); - - dn = ldb_dn_from_ldb_val(module, ldb, &v); - if (dn == NULL) { - ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); - ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - ltdb->idxptr->error = ltdb_dn_list_store_full(module, dn, list); - talloc_free(dn); - if (ltdb->idxptr->error != 0) { - return -1; - } - return 0; -} - -/* cleanup the idxptr mode when transaction commits */ -int ltdb_index_transaction_commit(struct ldb_module *module) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - int ret; - - struct ldb_context *ldb = ldb_module_get_ctx(module); - - ldb_reset_err_string(ldb); - - if (ltdb->idxptr->itdb) { - tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module); - tdb_close(ltdb->idxptr->itdb); - } - - ret = ltdb->idxptr->error; - if (ret != LDB_SUCCESS) { - if (!ldb_errstring(ldb)) { - ldb_set_errstring(ldb, ldb_strerror(ret)); - } - ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); - } - - talloc_free(ltdb->idxptr); - ltdb->idxptr = NULL; - return ret; -} - -/* cleanup the idxptr mode when transaction cancels */ -int ltdb_index_transaction_cancel(struct ldb_module *module) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - if (ltdb->idxptr && ltdb->idxptr->itdb) { - tdb_close(ltdb->idxptr->itdb); - } - talloc_free(ltdb->idxptr); - ltdb->idxptr = NULL; - return LDB_SUCCESS; -} - - -/* - return the dn key to be used for an index - the caller is responsible for freeing -*/ -static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb, - const char *attr, const struct ldb_val *value, - const struct ldb_schema_attribute **ap) -{ - struct ldb_dn *ret; - struct ldb_val v; - const struct ldb_schema_attribute *a; - char *attr_folded; - int r; - - attr_folded = ldb_attr_casefold(ldb, attr); - if (!attr_folded) { - return NULL; - } - - a = ldb_schema_attribute_by_name(ldb, attr); - if (ap) { - *ap = a; - } - r = a->syntax->canonicalise_fn(ldb, ldb, value, &v); - if (r != LDB_SUCCESS) { - const char *errstr = ldb_errstring(ldb); - /* canonicalisation can be refused. For example, - a attribute that takes wildcards will refuse to canonicalise - if the value contains a wildcard */ - ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s", - attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:"")); - talloc_free(attr_folded); - return NULL; - } - if (ldb_should_b64_encode(ldb, &v)) { - char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); - if (!vstr) { - talloc_free(attr_folded); - return NULL; - } - ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); - talloc_free(vstr); - } else { - ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); - } - - if (v.data != value->data) { - talloc_free(v.data); - } - talloc_free(attr_folded); - - return ret; -} - -/* - see if a attribute value is in the list of indexed attributes -*/ -static bool ltdb_is_indexed(const struct ldb_message *index_list, const char *attr) -{ - unsigned int i; - struct ldb_message_element *el; - - el = ldb_msg_find_element(index_list, LTDB_IDXATTR); - if (el == NULL) { - return false; - } - - /* TODO: this is too expensive! At least use a binary search */ - for (i=0; inum_values; i++) { - if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { - return true; - } - } - return false; -} - -/* - in the following logic functions, the return value is treated as - follows: - - LDB_SUCCESS: we found some matching index values - - LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches - - LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, - we'll need a full search - */ - -/* - return a list of dn's that might match a simple indexed search (an - equality search only) - */ -static int ltdb_index_dn_simple(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb; - struct ldb_dn *dn; - int ret; - - ldb = ldb_module_get_ctx(module); - - list->count = 0; - list->dn = NULL; - - /* if the attribute isn't in the list of indexed attributes then - this node needs a full search */ - if (!ltdb_is_indexed(index_list, tree->u.equality.attr)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* the attribute is indexed. Pull the list of DNs that match the - search criterion */ - dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL); - if (!dn) return LDB_ERR_OPERATIONS_ERROR; - - ret = ltdb_dn_list_load(module, dn, list); - talloc_free(dn); - return ret; -} - - -static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); - -/* - return a list of dn's that might match a leaf indexed search - */ -static int ltdb_index_dn_leaf(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - list->dn = talloc_array(list, struct ldb_val, 1); - if (list->dn == NULL) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - list->dn[0] = tree->u.equality.value; - list->count = 1; - return LDB_SUCCESS; - } - return ltdb_index_dn_simple(module, tree, index_list, list); -} - - -/* - list intersection - list = list & list2 -*/ -static bool list_intersect(struct ldb_context *ldb, - struct dn_list *list, const struct dn_list *list2) -{ - struct dn_list *list3; - unsigned int i; - - if (list->count == 0) { - /* 0 & X == 0 */ - return true; - } - if (list2->count == 0) { - /* X & 0 == 0 */ - list->count = 0; - list->dn = NULL; - return true; - } - - /* the indexing code is allowed to return a longer list than - what really matches, as all results are filtered by the - full expression at the end - this shortcut avoids a lot of - work in some cases */ - if (list->count < 2 && list2->count > 10) { - return true; - } - if (list2->count < 2 && list->count > 10) { - list->count = list2->count; - list->dn = list2->dn; - /* note that list2 may not be the parent of list2->dn, - as list2->dn may be owned by ltdb->idxptr. In that - case we expect this reparent call to fail, which is - OK */ - talloc_reparent(list2, list, list2->dn); - return true; - } - - list3 = talloc_zero(list, struct dn_list); - if (list3 == NULL) { - return false; - } - - list3->dn = talloc_array(list3, struct ldb_val, list->count); - if (!list3->dn) { - talloc_free(list3); - return false; - } - list3->count = 0; - - for (i=0;icount;i++) { - if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) { - list3->dn[list3->count] = list->dn[i]; - list3->count++; - } - } - - list->dn = talloc_steal(list, list3->dn); - list->count = list3->count; - talloc_free(list3); - - return true; -} - - -/* - list union - list = list | list2 -*/ -static bool list_union(struct ldb_context *ldb, - struct dn_list *list, const struct dn_list *list2) -{ - struct ldb_val *dn3; - - if (list2->count == 0) { - /* X | 0 == X */ - return true; - } - - if (list->count == 0) { - /* 0 | X == X */ - list->count = list2->count; - list->dn = list2->dn; - /* note that list2 may not be the parent of list2->dn, - as list2->dn may be owned by ltdb->idxptr. In that - case we expect this reparent call to fail, which is - OK */ - talloc_reparent(list2, list, list2->dn); - return true; - } - - dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); - if (!dn3) { - ldb_oom(ldb); - return false; - } - - /* we allow for duplicates here, and get rid of them later */ - memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count); - memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count); - - list->dn = dn3; - list->count += list2->count; - - return true; -} - -static int ltdb_index_dn(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list); - - -/* - process an OR list (a union) - */ -static int ltdb_index_dn_or(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - list->dn = NULL; - list->count = 0; - - for (i=0; iu.list.num_elements; i++) { - struct dn_list *list2; - int ret; - - list2 = talloc_zero(list, struct dn_list); - if (list2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* X || 0 == X */ - talloc_free(list2); - continue; - } - - if (ret != LDB_SUCCESS) { - /* X || * == * */ - talloc_free(list2); - return ret; - } - - if (!list_union(ldb, list, list2)) { - talloc_free(list2); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - if (list->count == 0) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - return LDB_SUCCESS; -} - - -/* - NOT an index results - */ -static int ltdb_index_dn_not(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - /* the only way to do an indexed not would be if we could - negate the not via another not or if we knew the total - number of database elements so we could know that the - existing expression covered the whole database. - - instead, we just give up, and rely on a full index scan - (unless an outer & manages to reduce the list) - */ - return LDB_ERR_OPERATIONS_ERROR; -} - - -static bool ltdb_index_unique(struct ldb_context *ldb, - const char *attr) -{ - const struct ldb_schema_attribute *a; - a = ldb_schema_attribute_by_name(ldb, attr); - if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { - return true; - } - return false; -} - -/* - process an AND expression (intersection) - */ -static int ltdb_index_dn_and(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb; - unsigned int i; - bool found; - - ldb = ldb_module_get_ctx(module); - - list->dn = NULL; - list->count = 0; - - /* in the first pass we only look for unique simple - equality tests, in the hope of avoiding having to look - at any others */ - for (i=0; iu.list.num_elements; i++) { - const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; - int ret; - - if (subtree->operation != LDB_OP_EQUALITY || - !ltdb_index_unique(ldb, subtree->u.equality.attr)) { - continue; - } - - ret = ltdb_index_dn(module, subtree, index_list, list); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* 0 && X == 0 */ - return LDB_ERR_NO_SUCH_OBJECT; - } - if (ret == LDB_SUCCESS) { - /* a unique index match means we can - * stop. Note that we don't care if we return - * a few too many objects, due to later - * filtering */ - return LDB_SUCCESS; - } - } - - /* now do a full intersection */ - found = false; - - for (i=0; iu.list.num_elements; i++) { - const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; - struct dn_list *list2; - int ret; - - list2 = talloc_zero(list, struct dn_list); - if (list2 == NULL) { - return ldb_module_oom(module); - } - - ret = ltdb_index_dn(module, subtree, index_list, list2); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* X && 0 == 0 */ - list->dn = NULL; - list->count = 0; - talloc_free(list2); - return LDB_ERR_NO_SUCH_OBJECT; - } - - if (ret != LDB_SUCCESS) { - /* this didn't adding anything */ - talloc_free(list2); - continue; - } - - if (!found) { - talloc_reparent(list2, list, list->dn); - list->dn = list2->dn; - list->count = list2->count; - found = true; - } else if (!list_intersect(ldb, list, list2)) { - talloc_free(list2); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (list->count == 0) { - list->dn = NULL; - return LDB_ERR_NO_SUCH_OBJECT; - } - - if (list->count < 2) { - /* it isn't worth loading the next part of the tree */ - return LDB_SUCCESS; - } - } - - if (!found) { - /* none of the attributes were indexed */ - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* - return a list of matching objects using a one-level index - */ -static int ltdb_index_dn_one(struct ldb_module *module, - struct ldb_dn *parent_dn, - struct dn_list *list) -{ - struct ldb_context *ldb; - struct ldb_dn *key; - struct ldb_val val; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* work out the index key from the parent DN */ - val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn)); - val.length = strlen((char *)val.data); - key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL); - if (!key) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_dn_list_load(module, key, list); - talloc_free(key); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (list->count == 0) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - return LDB_SUCCESS; -} - -/* - return a list of dn's that might match a indexed search or - an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches - */ -static int ltdb_index_dn(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - int ret = LDB_ERR_OPERATIONS_ERROR; - - switch (tree->operation) { - case LDB_OP_AND: - ret = ltdb_index_dn_and(module, tree, index_list, list); - break; - - case LDB_OP_OR: - ret = ltdb_index_dn_or(module, tree, index_list, list); - break; - - case LDB_OP_NOT: - ret = ltdb_index_dn_not(module, tree, index_list, list); - break; - - case LDB_OP_EQUALITY: - ret = ltdb_index_dn_leaf(module, tree, index_list, list); - break; - - case LDB_OP_SUBSTRING: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_PRESENT: - case LDB_OP_APPROX: - case LDB_OP_EXTENDED: - /* we can't index with fancy bitops yet */ - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - return ret; -} - -/* - filter a candidate dn_list from an indexed search into a set of results - extracting just the given attributes -*/ -static int ltdb_index_filter(const struct dn_list *dn_list, - struct ltdb_context *ac, - uint32_t *match_count) -{ - struct ldb_context *ldb; - struct ldb_message *msg; - unsigned int i; - - ldb = ldb_module_get_ctx(ac->module); - - for (i = 0; i < dn_list->count; i++) { - struct ldb_dn *dn; - int ret; - bool matched; - - msg = ldb_msg_new(ac); - if (!msg) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]); - if (dn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_search_dn1(ac->module, dn, msg); - talloc_free(dn); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* the record has disappeared? yes, this can happen */ - talloc_free(msg); - continue; - } - - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { - /* an internal error */ - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_match_msg_error(ldb, msg, - ac->tree, ac->base, ac->scope, &matched); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - if (!matched) { - talloc_free(msg); - continue; - } - - /* filter the attributes that the user wants */ - ret = ltdb_filter_attrs(msg, ac->attrs); - - if (ret == -1) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - /* Regardless of success or failure, the msg - * is the callbacks responsiblity, and should - * not be talloc_free()'ed */ - ac->request_terminated = true; - return ret; - } - - (*match_count)++; - } - - return LDB_SUCCESS; -} - -/* - remove any duplicated entries in a indexed result - */ -static void ltdb_dn_list_remove_duplicates(struct dn_list *list) -{ - unsigned int i, new_count; - - if (list->count < 2) { - return; - } - - TYPESAFE_QSORT(list->dn, list->count, dn_list_cmp); - - new_count = 1; - for (i=1; icount; i++) { - if (dn_list_cmp(&list->dn[i], &list->dn[new_count-1]) != 0) { - if (new_count != i) { - list->dn[new_count] = list->dn[i]; - } - new_count++; - } - } - - list->count = new_count; -} - -/* - search the database with a LDAP-like expression using indexes - returns -1 if an indexed search is not possible, in which - case the caller should call ltdb_search_full() -*/ -int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private); - struct dn_list *dn_list; - int ret; - - /* see if indexing is enabled */ - if (!ltdb->cache->attribute_indexes && - !ltdb->cache->one_level_indexes && - ac->scope != LDB_SCOPE_BASE) { - /* fallback to a full search */ - return LDB_ERR_OPERATIONS_ERROR; - } - - dn_list = talloc_zero(ac, struct dn_list); - if (dn_list == NULL) { - return ldb_module_oom(ac->module); - } - - switch (ac->scope) { - case LDB_SCOPE_BASE: - dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); - if (dn_list->dn == NULL) { - talloc_free(dn_list); - return ldb_module_oom(ac->module); - } - dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base)); - if (dn_list->dn[0].data == NULL) { - talloc_free(dn_list); - return ldb_module_oom(ac->module); - } - dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); - dn_list->count = 1; - break; - - case LDB_SCOPE_ONELEVEL: - if (!ltdb->cache->one_level_indexes) { - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ltdb_index_dn_one(ac->module, ac->base, dn_list); - if (ret != LDB_SUCCESS) { - talloc_free(dn_list); - return ret; - } - break; - - case LDB_SCOPE_SUBTREE: - case LDB_SCOPE_DEFAULT: - if (!ltdb->cache->attribute_indexes) { - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); - if (ret != LDB_SUCCESS) { - talloc_free(dn_list); - return ret; - } - ltdb_dn_list_remove_duplicates(dn_list); - break; - } - - ret = ltdb_index_filter(dn_list, ac, match_count); - talloc_free(dn_list); - return ret; -} - -/* - add an index entry for one message element -*/ -static int ltdb_index_add1(struct ldb_module *module, const char *dn, - struct ldb_message_element *el, int v_idx) -{ - struct ldb_context *ldb; - struct ldb_dn *dn_key; - int ret; - const struct ldb_schema_attribute *a; - struct dn_list *list; - unsigned alloc_len; - - ldb = ldb_module_get_ctx(module); - - list = talloc_zero(module, struct dn_list); - if (list == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a); - if (!dn_key) { - talloc_free(list); - return LDB_ERR_OPERATIONS_ERROR; - } - talloc_steal(list, dn_key); - - ret = ltdb_dn_list_load(module, dn_key, list); - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(list); - return ret; - } - - if (ltdb_dn_list_find_str(list, dn) != -1) { - talloc_free(list); - return LDB_SUCCESS; - } - - if (list->count > 0 && - a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { - talloc_free(list); - ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s", - el->name, dn); - return LDB_ERR_ENTRY_ALREADY_EXISTS; - } - - /* overallocate the list a bit, to reduce the number of - * realloc trigered copies */ - alloc_len = ((list->count+1)+7) & ~7; - list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); - if (list->dn == NULL) { - talloc_free(list); - return LDB_ERR_OPERATIONS_ERROR; - } - list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn); - list->dn[list->count].length = strlen(dn); - list->count++; - - ret = ltdb_dn_list_store(module, dn_key, list); - - talloc_free(list); - - return ret; -} - -/* - add index entries for one elements in a message - */ -static int ltdb_index_add_el(struct ldb_module *module, const char *dn, - struct ldb_message_element *el) -{ - unsigned int i; - for (i = 0; i < el->num_values; i++) { - int ret = ltdb_index_add1(module, dn, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* - add index entries for all elements in a message - */ -static int ltdb_index_add_all(struct ldb_module *module, const char *dn, - struct ldb_message_element *elements, int num_el) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - unsigned int i; - - if (dn[0] == '@') { - return LDB_SUCCESS; - } - - if (ltdb->cache->indexlist->num_elements == 0) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - for (i = 0; i < num_el; i++) { - int ret; - if (!ltdb_is_indexed(ltdb->cache->indexlist, elements[i].name)) { - continue; - } - ret = ltdb_index_add_el(module, dn, &elements[i]); - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, - __location__ ": Failed to re-index %s in %s - %s", - elements[i].name, dn, ldb_errstring(ldb)); - return ret; - } - } - - return LDB_SUCCESS; -} - - -/* - insert a one level index for a message -*/ -static int ltdb_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - struct ldb_message_element el; - struct ldb_val val; - struct ldb_dn *pdn; - const char *dn; - int ret; - - /* We index for ONE Level only if requested */ - if (!ltdb->cache->one_level_indexes) { - return LDB_SUCCESS; - } - - pdn = ldb_dn_get_parent(module, msg->dn); - if (pdn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_get_linearized(msg->dn); - if (dn == NULL) { - talloc_free(pdn); - return LDB_ERR_OPERATIONS_ERROR; - } - - val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn)); - if (val.data == NULL) { - talloc_free(pdn); - return LDB_ERR_OPERATIONS_ERROR; - } - - val.length = strlen((char *)val.data); - el.name = LTDB_IDXONE; - el.values = &val; - el.num_values = 1; - - if (add) { - ret = ltdb_index_add1(module, dn, &el, 0); - } else { /* delete */ - ret = ltdb_index_del_value(module, msg->dn, &el, 0); - } - - talloc_free(pdn); - - return ret; -} - -/* - add the index entries for a new element in a record - The caller guarantees that these element values are not yet indexed -*/ -int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - if (ldb_dn_is_special(dn)) { - return LDB_SUCCESS; - } - if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { - return LDB_SUCCESS; - } - return ltdb_index_add_el(module, ldb_dn_get_linearized(dn), el); -} - -/* - add the index entries for a new record -*/ -int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg) -{ - const char *dn; - int ret; - - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - - dn = ldb_dn_get_linearized(msg->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); - if (ret != LDB_SUCCESS) { - return ret; - } - - return ltdb_index_onelevel(module, msg, 1); -} - - -/* - delete an index entry for one message element -*/ -int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el, unsigned int v_idx) -{ - struct ldb_context *ldb; - struct ldb_dn *dn_key; - const char *dn_str; - int ret, i; - unsigned int j; - struct dn_list *list; - - ldb = ldb_module_get_ctx(module); - - dn_str = ldb_dn_get_linearized(dn); - if (dn_str == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (dn_str[0] == '@') { - return LDB_SUCCESS; - } - - dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL); - if (!dn_key) { - return LDB_ERR_OPERATIONS_ERROR; - } - - list = talloc_zero(dn_key, struct dn_list); - if (list == NULL) { - talloc_free(dn_key); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_dn_list_load(module, dn_key, list); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* it wasn't indexed. Did we have an earlier error? If we did then - its gone now */ - talloc_free(dn_key); - return LDB_SUCCESS; - } - - if (ret != LDB_SUCCESS) { - talloc_free(dn_key); - return ret; - } - - i = ltdb_dn_list_find_str(list, dn_str); - if (i == -1) { - /* nothing to delete */ - talloc_free(dn_key); - return LDB_SUCCESS; - } - - j = (unsigned int) i; - if (j != list->count - 1) { - memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); - } - list->count--; - list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); - - ret = ltdb_dn_list_store(module, dn_key, list); - - talloc_free(dn_key); - - return ret; -} - -/* - delete the index entries for a element - return -1 on failure -*/ -int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - const char *dn_str; - int ret; - unsigned int i; - - if (!ltdb->cache->attribute_indexes) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - dn_str = ldb_dn_get_linearized(dn); - if (dn_str == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (dn_str[0] == '@') { - return LDB_SUCCESS; - } - - if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { - return LDB_SUCCESS; - } - for (i = 0; i < el->num_values; i++) { - ret = ltdb_index_del_value(module, dn, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* - delete the index entries for a record - return -1 on failure -*/ -int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - int ret; - unsigned int i; - - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - - ret = ltdb_index_onelevel(module, msg, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (!ltdb->cache->attribute_indexes) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - for (i = 0; i < msg->num_elements; i++) { - ret = ltdb_index_del_element(module, msg->dn, &msg->elements[i]); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - - -/* - traversal function that deletes all @INDEX records -*/ -static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_module *module = state; - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - const char *dnstr = "DN=" LTDB_INDEX ":"; - struct dn_list list; - struct ldb_dn *dn; - struct ldb_val v; - int ret; - - if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) { - return 0; - } - /* we need to put a empty list in the internal tdb for this - * index entry */ - list.dn = NULL; - list.count = 0; - - /* the offset of 3 is to remove the DN= prefix. */ - v.data = key.dptr + 3; - v.length = strnlen((char *)key.dptr, key.dsize) - 3; - - dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v); - ret = ltdb_dn_list_store(module, dn, &list); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Unable to store null index for %s\n", - ldb_dn_get_linearized(dn)); - talloc_free(dn); - return -1; - } - talloc_free(dn); - return 0; -} - -struct ltdb_reindex_context { - struct ldb_module *module; - int error; -}; - -/* - traversal function that adds @INDEX records during a re index -*/ -static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_context *ldb; - struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state; - struct ldb_module *module = ctx->module; - struct ldb_message *msg; - const char *dn = NULL; - int ret; - TDB_DATA key2; - - ldb = ldb_module_get_ctx(module); - - if (strncmp((char *)key.dptr, "DN=@", 4) == 0 || - strncmp((char *)key.dptr, "DN=", 3) != 0) { - return 0; - } - - msg = ldb_msg_new(module); - if (msg == NULL) { - return -1; - } - - ret = ltdb_unpack_data(module, &data, msg); - if (ret != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", - ldb_dn_get_linearized(msg->dn)); - talloc_free(msg); - return -1; - } - - /* check if the DN key has changed, perhaps due to the - case insensitivity of an element changing */ - key2 = ltdb_key(module, msg->dn); - if (key2.dptr == NULL) { - /* probably a corrupt record ... darn */ - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", - ldb_dn_get_linearized(msg->dn)); - talloc_free(msg); - return 0; - } - if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) { - tdb_delete(tdb, key); - tdb_store(tdb, key2, data, 0); - } - talloc_free(key2.dptr); - - if (msg->dn == NULL) { - dn = (char *)key.dptr + 3; - } else { - dn = ldb_dn_get_linearized(msg->dn); - } - - ret = ltdb_index_onelevel(module, msg, 1); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Adding special ONE LEVEL index failed (%s)!", - ldb_dn_get_linearized(msg->dn)); - talloc_free(msg); - return -1; - } - - ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); - - if (ret != LDB_SUCCESS) { - ctx->error = ret; - talloc_free(msg); - return -1; - } - - talloc_free(msg); - - return 0; -} - -/* - force a complete reindex of the database -*/ -int ltdb_reindex(struct ldb_module *module) -{ - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - int ret; - struct ltdb_reindex_context ctx; - - if (ltdb_cache_reload(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* first traverse the database deleting any @INDEX records by - * putting NULL entries in the in-memory tdb - */ - ret = tdb_traverse(ltdb->tdb, delete_index, module); - if (ret < 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* if we don't have indexes we have nothing todo */ - if (ltdb->cache->indexlist->num_elements == 0) { - return LDB_SUCCESS; - } - - ctx.module = module; - ctx.error = 0; - - /* now traverse adding any indexes for normal LDB records */ - ret = tdb_traverse(ltdb->tdb, re_index, &ctx); - if (ret < 0) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ctx.error != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); - return ctx.error; - } - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c deleted file mode 100644 index 7c13065aeef..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ /dev/null @@ -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 --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c deleted file mode 100644 index 46e2d749984..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ /dev/null @@ -1,618 +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 search functions - * - * Description: functions to search ldb+tdb databases - * - * Author: Andrew Tridgell - */ - -#include "ldb_tdb.h" -#include - -/* - add one element to a message -*/ -static int msg_add_element(struct ldb_message *ret, - const struct ldb_message_element *el, - int check_duplicates) -{ - unsigned int i; - struct ldb_message_element *e2, *elnew; - - if (check_duplicates && ldb_msg_find_element(ret, el->name)) { - /* its already there */ - return 0; - } - - e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); - if (!e2) { - return -1; - } - ret->elements = e2; - - elnew = &e2[ret->num_elements]; - - elnew->name = talloc_strdup(ret->elements, el->name); - if (!elnew->name) { - return -1; - } - - if (el->num_values) { - elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values); - if (!elnew->values) { - return -1; - } - } else { - elnew->values = NULL; - } - - for (i=0;inum_values;i++) { - elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); - if (elnew->values[i].length != el->values[i].length) { - return -1; - } - } - - elnew->num_values = el->num_values; - elnew->flags = el->flags; - - ret->num_elements++; - - return 0; -} - -/* - add the special distinguishedName element -*/ -static int msg_add_distinguished_name(struct ldb_message *msg) -{ - struct ldb_message_element el; - struct ldb_val val; - int ret; - - el.flags = 0; - el.name = "distinguishedName"; - el.num_values = 1; - el.values = &val; - el.flags = 0; - val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn); - val.length = strlen((char *)val.data); - - ret = msg_add_element(msg, &el, 1); - return ret; -} - -/* - add all elements from one message into another - */ -static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *ret, - const struct ldb_message *msg) -{ - struct ldb_context *ldb; - unsigned int i; - int check_duplicates = (ret->num_elements != 0); - - ldb = ldb_module_get_ctx(module); - - if (msg_add_distinguished_name(ret) != 0) { - return -1; - } - - for (i=0;inum_elements;i++) { - const struct ldb_schema_attribute *a; - a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); - if (a->flags & LDB_ATTR_FLAG_HIDDEN) { - continue; - } - if (msg_add_element(ret, &msg->elements[i], - check_duplicates) != 0) { - return -1; - } - } - - return 0; -} - - -/* - pull the specified list of attributes from a message - */ -static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char * const *attrs) -{ - struct ldb_message *ret; - unsigned int i; - - ret = talloc(mem_ctx, struct ldb_message); - if (!ret) { - return NULL; - } - - ret->dn = ldb_dn_copy(ret, msg->dn); - if (!ret->dn) { - talloc_free(ret); - return NULL; - } - - ret->num_elements = 0; - ret->elements = NULL; - - if (!attrs) { - if (msg_add_all_elements(module, ret, msg) != 0) { - talloc_free(ret); - return NULL; - } - return ret; - } - - for (i=0;attrs[i];i++) { - struct ldb_message_element *el; - - if (strcmp(attrs[i], "*") == 0) { - if (msg_add_all_elements(module, ret, msg) != 0) { - talloc_free(ret); - return NULL; - } - continue; - } - - if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { - if (msg_add_distinguished_name(ret) != 0) { - return NULL; - } - continue; - } - - el = ldb_msg_find_element(msg, attrs[i]); - if (!el) { - continue; - } - if (msg_add_element(ret, el, 1) != 0) { - talloc_free(ret); - return NULL; - } - } - - return ret; -} - -/* - search the database for a single simple dn. - return LDB_ERR_NO_SUCH_OBJECT on record-not-found - and LDB_SUCCESS on success -*/ -static int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - TDB_DATA tdb_key, tdb_data; - - if (ldb_dn_is_null(dn)) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - /* form the key */ - tdb_key = ltdb_key(module, dn); - if (!tdb_key.dptr) { - return LDB_ERR_OPERATIONS_ERROR; - } - - tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); - talloc_free(tdb_key.dptr); - if (!tdb_data.dptr) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - free(tdb_data.dptr); - return LDB_SUCCESS; -} - -/* - search the database for a single simple dn, returning all attributes - in a single message - - return LDB_ERR_NO_SUCH_OBJECT on record-not-found - and LDB_SUCCESS on success -*/ -int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - int ret; - TDB_DATA tdb_key, tdb_data; - - memset(msg, 0, sizeof(*msg)); - - /* form the key */ - tdb_key = ltdb_key(module, dn); - if (!tdb_key.dptr) { - return LDB_ERR_OPERATIONS_ERROR; - } - - tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); - talloc_free(tdb_key.dptr); - if (!tdb_data.dptr) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - msg->num_elements = 0; - msg->elements = NULL; - - ret = ltdb_unpack_data(module, &tdb_data, msg); - free(tdb_data.dptr); - if (ret == -1) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!msg->dn) { - msg->dn = ldb_dn_copy(msg, dn); - } - if (!msg->dn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* - add a set of attributes from a record to a set of results - return 0 on success, -1 on failure -*/ -int ltdb_add_attr_results(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg, - const char * const attrs[], - unsigned int *count, - struct ldb_message ***res) -{ - struct ldb_message *msg2; - struct ldb_message **res2; - - /* pull the attributes that the user wants */ - msg2 = ltdb_pull_attrs(module, mem_ctx, msg, attrs); - if (!msg2) { - return -1; - } - - /* add to the results list */ - res2 = talloc_realloc(mem_ctx, *res, struct ldb_message *, (*count)+2); - if (!res2) { - talloc_free(msg2); - return -1; - } - - (*res) = res2; - - (*res)[*count] = talloc_move(*res, &msg2); - (*res)[(*count)+1] = NULL; - (*count)++; - - return 0; -} - - - -/* - filter the specified list of attributes from a message - removing not requested attrs. - */ -int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs) -{ - unsigned int i; - int keep_all = 0; - struct ldb_message_element *el2; - uint32_t num_elements; - - if (attrs) { - /* check for special attrs */ - for (i = 0; attrs[i]; i++) { - if (strcmp(attrs[i], "*") == 0) { - keep_all = 1; - break; - } - - if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { - if (msg_add_distinguished_name(msg) != 0) { - return -1; - } - } - } - } else { - keep_all = 1; - } - - if (keep_all) { - if (msg_add_distinguished_name(msg) != 0) { - return -1; - } - return 0; - } - - el2 = talloc_array(msg, struct ldb_message_element, msg->num_elements); - if (el2 == NULL) { - return -1; - } - num_elements = 0; - - for (i = 0; i < msg->num_elements; i++) { - unsigned int j; - int found = 0; - - for (j = 0; attrs[j]; j++) { - if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) { - found = 1; - break; - } - } - - if (found) { - el2[num_elements] = msg->elements[i]; - talloc_steal(el2, el2[num_elements].name); - talloc_steal(el2, el2[num_elements].values); - num_elements++; - } - } - - talloc_free(msg->elements); - msg->elements = talloc_realloc(msg, el2, struct ldb_message_element, msg->num_elements); - if (msg->elements == NULL) { - return -1; - } - msg->num_elements = num_elements; - - return 0; -} - -/* - search function for a non-indexed search - */ -static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_context *ldb; - struct ltdb_context *ac; - struct ldb_message *msg; - int ret; - bool matched; - - ac = talloc_get_type(state, struct ltdb_context); - ldb = ldb_module_get_ctx(ac->module); - - if (key.dsize < 4 || - strncmp((char *)key.dptr, "DN=", 3) != 0) { - return 0; - } - - msg = ldb_msg_new(ac); - if (!msg) { - return -1; - } - - /* unpack the record */ - ret = ltdb_unpack_data(ac->module, &data, msg); - if (ret == -1) { - talloc_free(msg); - return -1; - } - - if (!msg->dn) { - msg->dn = ldb_dn_new(msg, ldb, - (char *)key.dptr + 3); - if (msg->dn == NULL) { - talloc_free(msg); - return -1; - } - } - - /* see if it matches the given expression */ - ret = ldb_match_msg_error(ldb, msg, - ac->tree, ac->base, ac->scope, &matched); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return -1; - } - if (!matched) { - talloc_free(msg); - return 0; - } - - /* filter the attributes that the user wants */ - ret = ltdb_filter_attrs(msg, ac->attrs); - - if (ret == -1) { - talloc_free(msg); - return -1; - } - - ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - ac->request_terminated = true; - /* the callback failed, abort the operation */ - return -1; - } - - return 0; -} - - -/* - search the database with a LDAP-like expression. - this is the "full search" non-indexed variant -*/ -static int ltdb_search_full(struct ltdb_context *ctx) -{ - void *data = ldb_module_get_private(ctx->module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - int ret; - - if (ltdb->in_transaction != 0) { - ret = tdb_traverse(ltdb->tdb, search_func, ctx); - } else { - ret = tdb_traverse_read(ltdb->tdb, search_func, ctx); - } - - if (ret < 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* - search the database with a LDAP-like expression. - choses a search method -*/ -int ltdb_search(struct ltdb_context *ctx) -{ - struct ldb_context *ldb; - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_lock_read(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ltdb_cache_load(module) != 0) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { - - /* Check what we should do with a NULL dn */ - switch (req->op.search.scope) { - case LDB_SCOPE_BASE: - ldb_asprintf_errstring(ldb, - "NULL Base DN invalid for a base search"); - ret = LDB_ERR_INVALID_DN_SYNTAX; - break; - case LDB_SCOPE_ONELEVEL: - ldb_asprintf_errstring(ldb, - "NULL Base DN invalid for a one-level search"); - ret = LDB_ERR_INVALID_DN_SYNTAX; - break; - case LDB_SCOPE_SUBTREE: - default: - /* We accept subtree searches from a NULL base DN, ie over the whole DB */ - ret = LDB_SUCCESS; - } - } else if (ldb_dn_is_valid(req->op.search.base) == false) { - - /* We don't want invalid base DNs here */ - ldb_asprintf_errstring(ldb, - "Invalid Base DN: %s", - ldb_dn_get_linearized(req->op.search.base)); - ret = LDB_ERR_INVALID_DN_SYNTAX; - - } else if (ltdb->check_base) { - /* This database has been marked as 'checkBaseOnSearch', so do a spot check of the base dn */ - ret = ltdb_search_base(module, req->op.search.base); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ldb_asprintf_errstring(ldb, - "No such Base DN: %s", - ldb_dn_get_linearized(req->op.search.base)); - } - - } else { - /* If we are not checking the base DN life is easy */ - ret = LDB_SUCCESS; - } - - ctx->tree = req->op.search.tree; - ctx->scope = req->op.search.scope; - ctx->base = req->op.search.base; - ctx->attrs = req->op.search.attrs; - - if (ret == LDB_SUCCESS) { - uint32_t match_count = 0; - - ret = ltdb_search_indexed(ctx, &match_count); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* Not in the index, therefore OK! */ - ret = LDB_SUCCESS; - - } - /* Check if we got just a normal error. - * In that case proceed to a full search unless we got a - * callback error */ - if ( ! ctx->request_terminated && ret != LDB_SUCCESS) { - /* Not indexed, so we need to do a full scan */ - if (ltdb->warn_unindexed) { - /* useful for debugging when slow performance - * is caused by unindexed searches */ - char *expression = ldb_filter_from_tree(ctx, ctx->tree); - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb FULL SEARCH: %s SCOPE: %s DN: %s\n", - expression, - req->op.search.scope==LDB_SCOPE_BASE?"base": - req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": - req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", - ldb_dn_get_linearized(req->op.search.base)); - - talloc_free(expression); - } - if (match_count != 0) { - /* the indexing code gave an error - * after having returned at least one - * entry. This means the indexes are - * corrupt or a database record is - * corrupt. We cannot continue with a - * full search or we may return - * duplicate entries - */ - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ltdb_search_full(ctx); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); - } - } - } - - ltdb_unlock_read(module); - - return ret; -} - diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c deleted file mode 100644 index 0d4be491235..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ /dev/null @@ -1,1519 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 - - ** 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_tdb - * - * Component: ldb tdb backend - * - * Description: core functions for tdb backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * Author: Simo Sorce - * - * - description: make it possible to use event contexts - * date: Jan 2008 - * Author: Simo Sorce - * - * - description: fix up memory leaks and small bugs - * date: Oct 2009 - * Author: Matthias Dieter Wallnöfer - */ - -#include "ldb_tdb.h" -#include - - -/* - map a tdb error code to a ldb error code -*/ -int ltdb_err_map(enum TDB_ERROR tdb_code) -{ - switch (tdb_code) { - case TDB_SUCCESS: - return LDB_SUCCESS; - case TDB_ERR_CORRUPT: - case TDB_ERR_OOM: - case TDB_ERR_EINVAL: - return LDB_ERR_OPERATIONS_ERROR; - case TDB_ERR_IO: - return LDB_ERR_PROTOCOL_ERROR; - case TDB_ERR_LOCK: -#ifndef BUILD_TDB2 - case TDB_ERR_NOLOCK: -#endif - return LDB_ERR_BUSY; -#ifndef BUILD_TDB2 - case TDB_ERR_LOCK_TIMEOUT: -#endif - return LDB_ERR_TIME_LIMIT_EXCEEDED; - case TDB_ERR_EXISTS: - return LDB_ERR_ENTRY_ALREADY_EXISTS; - case TDB_ERR_NOEXIST: - return LDB_ERR_NO_SUCH_OBJECT; - case TDB_ERR_RDONLY: - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - default: - break; - } - return LDB_ERR_OTHER; -} - -/* - lock the database for read - use by ltdb_search and ltdb_sequence_number -*/ -int ltdb_lock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - int ret = 0; - - if (ltdb->in_transaction == 0 && - ltdb->read_lock_count == 0) { - ret = tdb_lockall_read(ltdb->tdb); - } - if (ret == 0) { - ltdb->read_lock_count++; - } - return ret; -} - -/* - unlock the database after a ltdb_lock_read() -*/ -int ltdb_unlock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) { - tdb_unlockall_read(ltdb->tdb); - return 0; - } - ltdb->read_lock_count--; - return 0; -} - - -/* - form a TDB_DATA for a record key - caller frees - - note that the key for a record can depend on whether the - dn refers to a case sensitive index record or not -*/ -TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - TDB_DATA key; - char *key_str = NULL; - const char *dn_folded = NULL; - - /* - most DNs are case insensitive. The exception is index DNs for - case sensitive attributes - - there are 3 cases dealt with in this code: - - 1) if the dn doesn't start with @ then uppercase the attribute - names and the attributes values of case insensitive attributes - 2) if the dn starts with @ then leave it alone - - the indexing code handles the rest - */ - - dn_folded = ldb_dn_get_casefold(dn); - if (!dn_folded) { - goto failed; - } - - key_str = talloc_strdup(ldb, "DN="); - if (!key_str) { - goto failed; - } - - key_str = talloc_strdup_append_buffer(key_str, dn_folded); - if (!key_str) { - goto failed; - } - - key.dptr = (uint8_t *)key_str; - key.dsize = strlen(key_str) + 1; - - return key; - -failed: - errno = ENOMEM; - key.dptr = NULL; - key.dsize = 0; - return key; -} - -/* - check special dn's have valid attributes - currently only @ATTRIBUTES is checked -*/ -static int ltdb_check_special_dn(struct ldb_module *module, - const struct ldb_message *msg) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - unsigned int i, j; - - if (! ldb_dn_is_special(msg->dn) || - ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { - return LDB_SUCCESS; - } - - /* we have @ATTRIBUTES, let's check attributes are fine */ - /* should we check that we deny multivalued attributes ? */ - for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; - - for (j = 0; j < msg->elements[i].num_values; j++) { - if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { - ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return LDB_SUCCESS; -} - - -/* - we've made a modification to a dn - possibly reindex and - update sequence number -*/ -static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn) -{ - int ret = LDB_SUCCESS; - struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); - - /* only allow modifies inside a transaction, otherwise the - * ldb is unsafe */ - if (ltdb->in_transaction == 0) { - ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_dn_is_special(dn) && - (ldb_dn_check_special(dn, LTDB_INDEXLIST) || - ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) { - ret = ltdb_reindex(module); - } - - /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ - if (ret == LDB_SUCCESS && - !(ldb_dn_is_special(dn) && - ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { - ret = ltdb_increase_sequence_number(module); - } - - /* If the modify was to @OPTIONS, reload the cache */ - if (ret == LDB_SUCCESS && - ldb_dn_is_special(dn) && - (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) { - ret = ltdb_cache_reload(module); - } - - return ret; -} - -/* - store a record into the db -*/ -int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - TDB_DATA tdb_key, tdb_data; - int ret = LDB_SUCCESS; - - tdb_key = ltdb_key(module, msg->dn); - if (tdb_key.dptr == NULL) { - return LDB_ERR_OTHER; - } - - ret = ltdb_pack_data(module, msg, &tdb_data); - if (ret == -1) { - talloc_free(tdb_key.dptr); - return LDB_ERR_OTHER; - } - - ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); - if (ret != 0) { - ret = ltdb_err_map(tdb_error(ltdb->tdb)); - goto done; - } - -done: - talloc_free(tdb_key.dptr); - talloc_free(tdb_data.dptr); - - return ret; -} - - -/* - check if a attribute is a single valued, for a given element - */ -static bool ldb_tdb_single_valued(const struct ldb_schema_attribute *a, - struct ldb_message_element *el) -{ - if (!a) return false; - if (el != NULL) { - if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { - /* override from a ldb module, for example - used for the description field, which is - marked multi-valued in the schema but which - should not actually accept multiple - values */ - return true; - } - if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { - /* override from a ldb module, for example used for - deleted linked attribute entries */ - return false; - } - } - if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { - return true; - } - return false; -} - -static int ltdb_add_internal(struct ldb_module *module, - const struct ldb_message *msg) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret = LDB_SUCCESS; - unsigned int i; - - for (i=0;inum_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - } - - ret = ltdb_store(module, msg, TDB_INSERT); - if (ret != LDB_SUCCESS) { - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - ldb_asprintf_errstring(ldb, - "Entry %s already exists", - ldb_dn_get_linearized(msg->dn)); - } - return ret; - } - - ret = ltdb_index_add_new(module, msg); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ltdb_modified(module, msg->dn); - - return ret; -} - -/* - add a record to the database -*/ -static int ltdb_add(struct ltdb_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - int ret = LDB_SUCCESS; - - ret = ltdb_check_special_dn(module, req->op.add.message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_add_internal(module, req->op.add.message); - - return ret; -} - -/* - delete a record from the database, not updating indexes (used for deleting - index records) -*/ -int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - TDB_DATA tdb_key; - int ret; - - tdb_key = ltdb_key(module, dn); - if (!tdb_key.dptr) { - return LDB_ERR_OTHER; - } - - ret = tdb_delete(ltdb->tdb, tdb_key); - talloc_free(tdb_key.dptr); - - if (ret != 0) { - ret = ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return ret; -} - -static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn) -{ - struct ldb_message *msg; - int ret = LDB_SUCCESS; - - msg = ldb_msg_new(module); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* in case any attribute of the message was indexed, we need - to fetch the old record */ - ret = ltdb_search_dn1(module, dn, msg); - if (ret != LDB_SUCCESS) { - /* not finding the old record is an error */ - goto done; - } - - ret = ltdb_delete_noindex(module, dn); - if (ret != LDB_SUCCESS) { - goto done; - } - - /* remove any indexed attributes */ - ret = ltdb_index_delete(module, msg); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ltdb_modified(module, dn); - if (ret != LDB_SUCCESS) { - goto done; - } - -done: - talloc_free(msg); - return ret; -} - -/* - delete a record from the database -*/ -static int ltdb_delete(struct ltdb_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - int ret = LDB_SUCCESS; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_delete_internal(module, req->op.del.dn); - - return ret; -} - -/* - find an element by attribute name. At the moment this does a linear search, - it should be re-coded to use a binary search once all places that modify - records guarantee sorted order - - return the index of the first matching element if found, otherwise -1 -*/ -static int find_element(const struct ldb_message *msg, const char *name) -{ - unsigned int i; - for (i=0;inum_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { - return i; - } - } - return -1; -} - - -/* - add an element to an existing record. Assumes a elements array that we - can call re-alloc on, and assumed that we can re-use the data pointers from - the passed in additional values. Use with care! - - returns 0 on success, -1 on failure (and sets errno) -*/ -static int ltdb_msg_add_element(struct ldb_context *ldb, - struct ldb_message *msg, - struct ldb_message_element *el) -{ - struct ldb_message_element *e2; - unsigned int i; - - if (el->num_values == 0) { - /* nothing to do here - we don't add empty elements */ - return 0; - } - - e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, - msg->num_elements+1); - if (!e2) { - errno = ENOMEM; - return -1; - } - - msg->elements = e2; - - e2 = &msg->elements[msg->num_elements]; - - e2->name = el->name; - e2->flags = el->flags; - e2->values = talloc_array(msg->elements, - struct ldb_val, el->num_values); - if (!e2->values) { - errno = ENOMEM; - return -1; - } - for (i=0;inum_values;i++) { - e2->values[i] = el->values[i]; - } - e2->num_values = el->num_values; - - ++msg->num_elements; - - return 0; -} - -/* - delete all elements having a specified attribute name -*/ -static int msg_delete_attribute(struct ldb_module *module, - struct ldb_context *ldb, - struct ldb_message *msg, const char *name) -{ - unsigned int i; - int ret; - struct ldb_message_element *el; - - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - i = el - msg->elements; - - ret = ltdb_index_del_element(module, msg->dn, el); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_free(el->values); - if (msg->num_elements > (i+1)) { - memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1))); - } - msg->num_elements--; - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, - msg->num_elements); - return LDB_SUCCESS; -} - -/* - delete all elements matching an attribute name/value - - return LDB Error on failure -*/ -static int msg_delete_element(struct ldb_module *module, - struct ldb_message *msg, - const char *name, - const struct ldb_val *val) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - unsigned int i; - int found, ret; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - - found = find_element(msg, name); - if (found == -1) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - - i = (unsigned int) found; - el = &(msg->elements[i]); - - a = ldb_schema_attribute_by_name(ldb, el->name); - - for (i=0;inum_values;i++) { - bool matched; - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &el->values[i], val, &matched); - if (ret != LDB_SUCCESS) return ret; - } else { - matched = (a->syntax->comparison_fn(ldb, ldb, - &el->values[i], val) == 0); - } - if (matched) { - if (el->num_values == 1) { - return msg_delete_attribute(module, ldb, msg, name); - } - - ret = ltdb_index_del_value(module, msg->dn, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (inum_values-1) { - memmove(&el->values[i], &el->values[i+1], - sizeof(el->values[i])* - (el->num_values-(i+1))); - } - el->num_values--; - - /* per definition we find in a canonicalised message an - attribute value only once. So we are finished here */ - return LDB_SUCCESS; - } - } - - /* Not found */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; -} - - -/* - modify a record - internal interface - - yuck - this is O(n^2). Luckily n is usually small so we probably - get away with it, but if we ever have really large attribute lists - then we'll need to look at this again - - 'req' is optional, and is used to specify controls if supplied -*/ -int ltdb_modify_internal(struct ldb_module *module, - const struct ldb_message *msg, - struct ldb_request *req) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - TDB_DATA tdb_key, tdb_data; - struct ldb_message *msg2; - unsigned int i, j, k; - int ret = LDB_SUCCESS, idx; - struct ldb_control *control_permissive = NULL; - - if (req) { - control_permissive = ldb_request_get_control(req, - LDB_CONTROL_PERMISSIVE_MODIFY_OID); - } - - tdb_key = ltdb_key(module, msg->dn); - if (!tdb_key.dptr) { - return LDB_ERR_OTHER; - } - - tdb_data = tdb_fetch_compat(ltdb->tdb, tdb_key); - if (!tdb_data.dptr) { - talloc_free(tdb_key.dptr); - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - msg2 = ldb_msg_new(tdb_key.dptr); - if (msg2 == NULL) { - free(tdb_data.dptr); - ret = LDB_ERR_OTHER; - goto done; - } - - ret = ltdb_unpack_data(module, &tdb_data, msg2); - free(tdb_data.dptr); - if (ret == -1) { - ret = LDB_ERR_OTHER; - goto done; - } - - if (!msg2->dn) { - msg2->dn = msg->dn; - } - - for (i=0; inum_elements; i++) { - struct ldb_message_element *el = &msg->elements[i], *el2; - struct ldb_val *vals; - const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); - const char *dn; - - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, - "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_CONSTRAINT_VIOLATION; - goto done; - } - - /* make a copy of the array so that a permissive - * control can remove duplicates without changing the - * original values, but do not copy data as we do not - * need to keep it around once the operation is - * finished */ - if (control_permissive) { - el = talloc(msg2, struct ldb_message_element); - if (!el) { - ret = LDB_ERR_OTHER; - goto done; - } - *el = msg->elements[i]; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - for (j = 0; j < el->num_values; j++) { - el->values[j] = msg->elements[i].values[j]; - } - } - - if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* Checks if element already exists */ - idx = find_element(msg2, el->name); - if (idx == -1) { - if (ltdb_msg_add_element(ldb, msg2, el) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - ret = ltdb_index_add_element(module, msg2->dn, - el); - if (ret != LDB_SUCCESS) { - goto done; - } - } else { - j = (unsigned int) idx; - el2 = &(msg2->elements[j]); - - /* We cannot add another value on a existing one - if the attribute is single-valued */ - if (ldb_tdb_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* Check that values don't exist yet on multi- - valued attributes or aren't provided twice */ - for (j = 0; j < el->num_values; j++) { - if (ldb_msg_find_val(el2, &el->values[j]) != NULL) { - if (control_permissive) { - /* remove this one as if it was never added */ - el->num_values--; - for (k = j; k < el->num_values; k++) { - el->values[k] = el->values[k + 1]; - } - j--; /* rewind */ - - continue; - } - - ldb_asprintf_errstring(ldb, - "attribute '%s': value #%u on '%s' already exists", - el->name, j, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { - ldb_asprintf_errstring(ldb, - "attribute '%s': value #%u on '%s' provided more than once", - el->name, j, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - } - - /* Now combine existing and new values to a new - attribute record */ - vals = talloc_realloc(msg2->elements, - el2->values, struct ldb_val, - el2->num_values + el->num_values); - if (vals == NULL) { - ldb_oom(ldb); - ret = LDB_ERR_OTHER; - goto done; - } - - for (j=0; jnum_values; j++) { - vals[el2->num_values + j] = - ldb_val_dup(vals, &el->values[j]); - } - - el2->values = vals; - el2->num_values += el->num_values; - - ret = ltdb_index_add_element(module, msg2->dn, el); - if (ret != LDB_SUCCESS) { - goto done; - } - } - - break; - - case LDB_FLAG_MOD_REPLACE: - - if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* TODO: This is O(n^2) - replace with more efficient check */ - for (j=0; jnum_values; j++) { - if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { - ldb_asprintf_errstring(ldb, - "attribute '%s': value #%u on '%s' provided more than once", - el->name, j, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - } - - /* Checks if element already exists */ - idx = find_element(msg2, el->name); - if (idx != -1) { - j = (unsigned int) idx; - el2 = &(msg2->elements[j]); - if (ldb_msg_element_compare(el, el2) == 0) { - /* we are replacing with the same values */ - continue; - } - - /* Delete the attribute if it exists in the DB */ - if (msg_delete_attribute(module, ldb, msg2, - el->name) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - } - - /* Recreate it with the new values */ - if (ltdb_msg_add_element(ldb, msg2, el) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = ltdb_index_add_element(module, msg2->dn, el); - if (ret != LDB_SUCCESS) { - goto done; - } - - break; - - case LDB_FLAG_MOD_DELETE: - dn = ldb_dn_get_linearized(msg2->dn); - if (dn == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - if (msg->elements[i].num_values == 0) { - /* Delete the whole attribute */ - ret = msg_delete_attribute(module, ldb, msg2, - msg->elements[i].name); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && - control_permissive) { - ret = LDB_SUCCESS; - } else { - ldb_asprintf_errstring(ldb, - "attribute '%s': no such attribute for delete on '%s'", - msg->elements[i].name, dn); - } - if (ret != LDB_SUCCESS) { - goto done; - } - } else { - /* Delete specified values from an attribute */ - for (j=0; j < msg->elements[i].num_values; j++) { - ret = msg_delete_element(module, - msg2, - msg->elements[i].name, - &msg->elements[i].values[j]); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && - control_permissive) { - ret = LDB_SUCCESS; - } else { - ldb_asprintf_errstring(ldb, - "attribute '%s': no matching attribute value while deleting attribute on '%s'", - msg->elements[i].name, dn); - } - if (ret != LDB_SUCCESS) { - goto done; - } - } - } - break; - default: - ldb_asprintf_errstring(ldb, - "attribute '%s': invalid modify flags on '%s': 0x%x", - msg->elements[i].name, ldb_dn_get_linearized(msg->dn), - msg->elements[i].flags & LDB_FLAG_MOD_MASK); - ret = LDB_ERR_PROTOCOL_ERROR; - goto done; - } - } - - ret = ltdb_store(module, msg2, TDB_MODIFY); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ltdb_modified(module, msg2->dn); - if (ret != LDB_SUCCESS) { - goto done; - } - -done: - talloc_free(tdb_key.dptr); - return ret; -} - -/* - modify a record -*/ -static int ltdb_modify(struct ltdb_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - int ret = LDB_SUCCESS; - - ret = ltdb_check_special_dn(module, req->op.mod.message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_modify_internal(module, req->op.mod.message, req); - - return ret; -} - -/* - rename a record -*/ -static int ltdb_rename(struct ltdb_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct ldb_message *msg; - int ret = LDB_SUCCESS; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_cache_load(ctx->module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = ldb_msg_new(ctx); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* in case any attribute of the message was indexed, we need - to fetch the old record */ - ret = ltdb_search_dn1(module, req->op.rename.olddn, msg); - if (ret != LDB_SUCCESS) { - /* not finding the old record is an error */ - return ret; - } - - /* Always delete first then add, to avoid conflicts with - * unique indexes. We rely on the transaction to make this - * atomic - */ - ret = ltdb_delete_internal(module, msg->dn); - if (ret != LDB_SUCCESS) { - return ret; - } - - msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); - if (msg->dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_add_internal(module, msg); - - return ret; -} - -static int ltdb_start_trans(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - - if (tdb_transaction_start(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - ltdb->in_transaction++; - - ltdb_index_transaction_start(module); - - return LDB_SUCCESS; -} - -static int ltdb_prepare_commit(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - - if (ltdb->in_transaction != 1) { - return LDB_SUCCESS; - } - - if (ltdb_index_transaction_commit(module) != 0) { - tdb_transaction_cancel(ltdb->tdb); - ltdb->in_transaction--; - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) { - ltdb->in_transaction--; - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - ltdb->prepared_commit = true; - - return LDB_SUCCESS; -} - -static int ltdb_end_trans(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - - if (!ltdb->prepared_commit) { - int ret = ltdb_prepare_commit(module); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - ltdb->in_transaction--; - ltdb->prepared_commit = false; - - if (tdb_transaction_commit(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return LDB_SUCCESS; -} - -static int ltdb_del_trans(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); - - ltdb->in_transaction--; - - if (ltdb_index_transaction_cancel(module) != 0) { - tdb_transaction_cancel(ltdb->tdb); - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - tdb_transaction_cancel(ltdb->tdb); - return LDB_SUCCESS; -} - -/* - return sequenceNumber from @BASEINFO -*/ -static int ltdb_sequence_number(struct ltdb_context *ctx, - struct ldb_extended **ext) -{ - struct ldb_context *ldb; - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_seqnum_request *seq; - struct ldb_seqnum_result *res; - struct ldb_message *msg = NULL; - struct ldb_dn *dn; - const char *date; - int ret = LDB_SUCCESS; - - ldb = ldb_module_get_ctx(module); - - seq = talloc_get_type(req->op.extended.data, - struct ldb_seqnum_request); - if (seq == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ltdb_lock_read(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - res = talloc_zero(req, struct ldb_seqnum_result); - if (res == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - tmp_ctx = talloc_new(req); - if (tmp_ctx == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO); - if (dn == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = ltdb_search_dn1(module, dn, msg); - if (ret != LDB_SUCCESS) { - goto done; - } - - switch (seq->type) { - case LDB_SEQ_HIGHEST_SEQ: - res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); - break; - case LDB_SEQ_NEXT: - res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); - res->seq_num++; - break; - case LDB_SEQ_HIGHEST_TIMESTAMP: - date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL); - if (date) { - res->seq_num = ldb_string_to_time(date); - } else { - res->seq_num = 0; - /* zero is as good as anything when we don't know */ - } - break; - } - - *ext = talloc_zero(req, struct ldb_extended); - if (*ext == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; - (*ext)->data = talloc_steal(*ext, res); - -done: - talloc_free(tmp_ctx); - ltdb_unlock_read(module); - return ret; -} - -static void ltdb_request_done(struct ltdb_context *ctx, int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->error = error; - - req->callback(req, ares); -} - -static void ltdb_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct ltdb_context *ctx; - ctx = talloc_get_type(private_data, struct ltdb_context); - - if (!ctx->request_terminated) { - /* request is done now */ - ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); - } - - if (!ctx->request_terminated) { - /* neutralize the spy */ - ctx->spy->ctx = NULL; - } - talloc_free(ctx); -} - -static void ltdb_request_extended_done(struct ltdb_context *ctx, - struct ldb_extended *ext, - int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->response = ext; - ares->error = error; - - req->callback(req, ares); -} - -static void ltdb_handle_extended(struct ltdb_context *ctx) -{ - struct ldb_extended *ext = NULL; - int ret; - - if (strcmp(ctx->req->op.extended.oid, - LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { - /* get sequence number */ - ret = ltdb_sequence_number(ctx, &ext); - } else { - /* not recognized */ - ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - - ltdb_request_extended_done(ctx, ext, ret); -} - -static void ltdb_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct ltdb_context *ctx; - int ret; - - ctx = talloc_get_type(private_data, struct ltdb_context); - - if (ctx->request_terminated) { - goto done; - } - - switch (ctx->req->operation) { - case LDB_SEARCH: - ret = ltdb_search(ctx); - break; - case LDB_ADD: - ret = ltdb_add(ctx); - break; - case LDB_MODIFY: - ret = ltdb_modify(ctx); - break; - case LDB_DELETE: - ret = ltdb_delete(ctx); - break; - case LDB_RENAME: - ret = ltdb_rename(ctx); - break; - case LDB_EXTENDED: - ltdb_handle_extended(ctx); - goto done; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - } - - if (!ctx->request_terminated) { - /* request is done now */ - ltdb_request_done(ctx, ret); - } - -done: - if (!ctx->request_terminated) { - /* neutralize the spy */ - ctx->spy->ctx = NULL; - } - talloc_free(ctx); -} - -static int ltdb_request_destructor(void *ptr) -{ - struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy); - - if (spy->ctx != NULL) { - spy->ctx->request_terminated = true; - } - - return 0; -} - -static int ltdb_handle_request(struct ldb_module *module, - struct ldb_request *req) -{ - struct ldb_control *control_permissive; - struct ldb_context *ldb; - struct tevent_context *ev; - struct ltdb_context *ac; - struct tevent_timer *te; - struct timeval tv; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - control_permissive = ldb_request_get_control(req, - LDB_CONTROL_PERMISSIVE_MODIFY_OID); - - for (i = 0; req->controls && req->controls[i]; i++) { - if (req->controls[i]->critical && - req->controls[i] != control_permissive) { - ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", - req->controls[i]->oid); - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ev = ldb_get_event_context(ldb); - - ac = talloc_zero(ldb, struct ltdb_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac); - if (NULL == te) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - tv.tv_sec = req->starttime + req->timeout; - ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac); - if (NULL == ac->timeout_event) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* set a spy so that we do not try to use the request context - * if it is freed before ltdb_callback fires */ - ac->spy = talloc(req, struct ltdb_req_spy); - if (NULL == ac->spy) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->spy->ctx = ac; - - talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor); - - return LDB_SUCCESS; -} - -static int ltdb_init_rootdse(struct ldb_module *module) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - ret = ldb_mod_register_control(module, - LDB_CONTROL_PERMISSIVE_MODIFY_OID); - /* ignore errors on this - we expect it for non-sam databases */ - - /* there can be no module beyond the backend, just return */ - return LDB_SUCCESS; -} - -static const struct ldb_module_ops ltdb_ops = { - .name = "tdb", - .init_context = ltdb_init_rootdse, - .search = ltdb_handle_request, - .add = ltdb_handle_request, - .modify = ltdb_handle_request, - .del = ltdb_handle_request, - .rename = ltdb_handle_request, - .extended = ltdb_handle_request, - .start_transaction = ltdb_start_trans, - .end_transaction = ltdb_end_trans, - .prepare_commit = ltdb_prepare_commit, - .del_transaction = ltdb_del_trans, -}; - -/* - connect to the database -*/ -static int ltdb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - const char *path; - int tdb_flags, open_flags; - struct ltdb_private *ltdb; - - /* parse the url */ - if (strchr(url, ':')) { - if (strncmp(url, "tdb://", 6) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid tdb URL '%s'", url); - return LDB_ERR_OPERATIONS_ERROR; - } - path = url+6; - } else { - path = url; - } - - tdb_flags = TDB_DEFAULT | TDB_SEQNUM; - - /* check for the 'nosync' option */ - if (flags & LDB_FLG_NOSYNC) { - tdb_flags |= TDB_NOSYNC; - } - - /* and nommap option */ - if (flags & LDB_FLG_NOMMAP) { - tdb_flags |= TDB_NOMMAP; - } - - if (flags & LDB_FLG_RDONLY) { - open_flags = O_RDONLY; - } else { - open_flags = O_CREAT | O_RDWR; - } - - ltdb = talloc_zero(ldb, struct ltdb_private); - if (!ltdb) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* note that we use quite a large default hash size */ - ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, - tdb_flags, open_flags, - ldb_get_create_perms(ldb), ldb); - if (!ltdb->tdb) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Unable to open tdb '%s'", path); - talloc_free(ltdb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (getenv("LDB_WARN_UNINDEXED")) { - ltdb->warn_unindexed = true; - } - - ltdb->sequence_number = 0; - - module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops); - if (!module) { - talloc_free(ltdb); - return LDB_ERR_OPERATIONS_ERROR; - } - ldb_module_set_private(module, ltdb); - talloc_steal(module, ltdb); - - if (ltdb_cache_load(module) != 0) { - talloc_free(module); - talloc_free(ltdb); - return LDB_ERR_OPERATIONS_ERROR; - } - - *_module = module; - return LDB_SUCCESS; -} - -int ldb_tdb_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("tdb", ltdb_connect, false); -} diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h deleted file mode 100644 index 96ad43fbd6c..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ /dev/null @@ -1,139 +0,0 @@ -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "tdb_compat.h" -#include "ldb_module.h" - -/* this private structure is used by the ltdb backend in the - ldb_context */ -struct ltdb_private { - TDB_CONTEXT *tdb; - unsigned int connect_flags; - - unsigned long long sequence_number; - - /* the low level tdb seqnum - used to avoid loading BASEINFO when - possible */ - int tdb_seqnum; - - struct ltdb_cache { - struct ldb_message *indexlist; - struct ldb_message *attributes; - bool one_level_indexes; - bool attribute_indexes; - } *cache; - - int in_transaction; - - bool check_base; - struct ltdb_idxptr *idxptr; - bool prepared_commit; - int read_lock_count; - - bool warn_unindexed; -}; - -/* - the async local context - holds also internal search state during a full db search -*/ -struct ltdb_req_spy { - struct ltdb_context *ctx; -}; - -struct ltdb_context { - struct ldb_module *module; - struct ldb_request *req; - - bool request_terminated; - struct ltdb_req_spy *spy; - - /* search stuff */ - const struct ldb_parse_tree *tree; - struct ldb_dn *base; - enum ldb_scope scope; - const char * const *attrs; - struct tevent_timer *timeout_event; -}; - -/* special record types */ -#define LTDB_INDEX "@INDEX" -#define LTDB_INDEXLIST "@INDEXLIST" -#define LTDB_IDX "@IDX" -#define LTDB_IDXVERSION "@IDXVERSION" -#define LTDB_IDXATTR "@IDXATTR" -#define LTDB_IDXONE "@IDXONE" -#define LTDB_BASEINFO "@BASEINFO" -#define LTDB_OPTIONS "@OPTIONS" -#define LTDB_ATTRIBUTES "@ATTRIBUTES" - -/* special attribute types */ -#define LTDB_SEQUENCE_NUMBER "sequenceNumber" -#define LTDB_CHECK_BASE "checkBaseOnSearch" -#define LTDB_MOD_TIMESTAMP "whenChanged" -#define LTDB_OBJECTCLASS "objectClass" - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ - -int ltdb_cache_reload(struct ldb_module *module); -int ltdb_cache_load(struct ldb_module *module); -int ltdb_increase_sequence_number(struct ldb_module *module); -int ltdb_check_at_attributes_values(const struct ldb_val *value); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_index.c */ - -struct ldb_parse_tree; - -int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *); -int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg); -int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg); -int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el); -int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el); -int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, - struct ldb_message_element *el, unsigned int v_idx); -int ltdb_reindex(struct ldb_module *module); -int ltdb_index_transaction_start(struct ldb_module *module); -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, - const struct ldb_val *val); -void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); -int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg); -int ltdb_add_attr_results(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg, - const char * const attrs[], - unsigned int *count, - struct ldb_message ***res); -int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs); -int ltdb_search(struct ltdb_context *ctx); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ -int ltdb_lock_read(struct ldb_module *module); -int ltdb_unlock_read(struct ldb_module *module); -TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); -int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); -int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req); -int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn); -int ltdb_err_map(enum TDB_ERROR tdb_code); - -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb); diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c deleted file mode 100644 index 16a037a6c33..00000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** 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 . -*/ - -#include "ldb_tdb.h" -#include "dlinklist.h" - -/* FIXME: TDB2 does this internally, so no need to wrap multiple opens! */ -#if BUILD_TDB2 -static void ltdb_log_fn(struct tdb_context *tdb, - enum tdb_log_level level, - const char *message, - struct ldb_context *ldb) -{ - enum ldb_debug_level ldb_level; - const char *name = tdb_name(tdb); - - switch (level) { - case TDB_LOG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - case TDB_LOG_USE_ERROR: - case TDB_LOG_ERROR: - ldb_level = LDB_DEBUG_FATAL; - break; - default: - ldb_level = LDB_DEBUG_FATAL; - } - - ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); -} -#else /* !TDB2 */ -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - va_list ap; - const char *name = tdb_name(tdb); - struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); - enum ldb_debug_level ldb_level; - char *message; - - if (ldb == NULL) - return; - - va_start(ap, fmt); - message = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - - switch (level) { - case TDB_DEBUG_FATAL: - ldb_level = LDB_DEBUG_FATAL; - break; - case TDB_DEBUG_ERROR: - ldb_level = LDB_DEBUG_ERROR; - break; - case TDB_DEBUG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - break; - case TDB_DEBUG_TRACE: - ldb_level = LDB_DEBUG_TRACE; - break; - default: - ldb_level = LDB_DEBUG_FATAL; - } - - ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); - talloc_free(message); -} -#endif - -/* - the purpose of this code is to work around the braindead posix locking - rules, to allow us to have a ldb open more than once while allowing - locking to work - - TDB2 handles multiple opens, so we don't have this problem there. -*/ - -struct ltdb_wrap { - struct ltdb_wrap *next, *prev; - struct tdb_context *tdb; - dev_t device; - ino_t inode; -}; - -static struct ltdb_wrap *tdb_list; - -/* destroy the last connection to a tdb */ -static int ltdb_wrap_destructor(struct ltdb_wrap *w) -{ - tdb_close(w->tdb); - DLIST_REMOVE(tdb_list, w); - return 0; -} - -/* - wrapped connection to a tdb database. The caller should _not_ free - this as it is not a talloc structure (as tdb does not use talloc - yet). It will auto-close when the caller frees the mem_ctx that is - passed to this call - */ -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, - int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb) -{ - struct ltdb_wrap *w; - struct stat st; - - if (stat(path, &st) == 0) { - for (w=tdb_list;w;w=w->next) { - if (st.st_dev == w->device && st.st_ino == w->inode) { - if (!talloc_reference(mem_ctx, w)) { - return NULL; - } - return w->tdb; - } - } - } - - w = talloc(mem_ctx, struct ltdb_wrap); - if (w == NULL) { - return NULL; - } - - w->tdb = tdb_open_compat(path, hash_size, tdb_flags, open_flags, mode, ltdb_log_fn, ldb); - if (w->tdb == NULL) { - talloc_free(w); - return NULL; - } - - if (fstat(tdb_fd(w->tdb), &st) != 0) { - tdb_close(w->tdb); - talloc_free(w); - return NULL; - } - - w->device = st.st_dev; - w->inode = st.st_ino; - - talloc_set_destructor(w, ltdb_wrap_destructor); - - DLIST_ADD(tdb_list, w); - - return w->tdb; -} diff --git a/source4/lib/ldb/mainpage.dox b/source4/lib/ldb/mainpage.dox deleted file mode 100644 index bbd8d9c5025..00000000000 --- a/source4/lib/ldb/mainpage.dox +++ /dev/null @@ -1,80 +0,0 @@ -/** - -\mainpage ldb - -\section Overview - -ldb is a LDAP-like embedded database. It is not at all LDAP standards -compliant, so if you want a standards compliant database then please -see the excellent OpenLDAP -project.

- -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.

- -ldb is the database engine used in Samba4. - -\section Features - -The main features that separate ldb from other solutions are: - - Safe multi-reader, multi-writer, using byte range locking - - LDAP-like API - - fast operation - - choice of local tdb, local sqlite3 or remote LDAP backends - - integration with talloc - - schema-less operation, for trivial setup - - modules for extensions (such as schema support) - - easy setup of indexes and attribute properties - - ldbedit tool for database editing (reminiscent of 'vipw') - - ldif for import/export - -\section Documentation - -ldb has limited programmer and administrator documentation: - - a list of functions - - a list of examples - - a list of data structures - - a list of constants - -If you need more information than is presented in this document, you -may wish to look at the source code, especially the source code in the -tools directory. - -ldb makes use of the LDAP Data Interchange Format (LDIF), which is -documented in RFC -2849. - -\section Support - -ldb does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -\section Download - -You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -\verbatim - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc -\endverbatim - -To fetch via rsync use these commands: - -\verbatim - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . -\endverbatim - -\section Credits - -ldb is another product of the prolific Andrew Tridgell. - -*/ diff --git a/source4/lib/ldb/man/ldb.3.xml b/source4/lib/ldb/man/ldb.3.xml deleted file mode 100644 index 19d9a89e102..00000000000 --- a/source4/lib/ldb/man/ldb.3.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - ldb - 3 - - - - ldb - The Samba Project - A light-weight database library - - - - #include <ldb.h> - - - - description - - -ldb is a light weight embedded database library and API. With a -programming interface that is very similar to LDAP, ldb can store its -data either in a tdb(3) database or in a real LDAP database. - - - -When used with the tdb backend ldb does not require any database -daemon. Instead, ldb function calls are processed immediately by the -ldb library, which does IO directly on the database, while allowing -multiple readers/writers using operating system byte range locks. This -leads to an API with very low overheads, often resulting in speeds of -more than 10x what can be achieved with a more traditional LDAP -architecture. - - - -In a taxonomy of databases ldb would sit half way between key/value -pair databases (such as berkley db or tdb) and a full LDAP -database. With a structured attribute oriented API like LDAP and good -indexing capabilities, ldb can be used for quite sophisticated -applications that need a light weight database, without the -administrative overhead of a full LDAP installation. - - - -Included with ldb are a number of useful command line tools for -manipulating a ldb database. These tools are similar in style to the -equivalent ldap command line tools. - - - -In its default mode of operation with a tdb backend, ldb can also be -seen as a "schema-less LDAP". By default ldb does not require a -schema, which greatly reduces the complexity of getting started with -ldb databases. As the complexity of you application grows you can take -advantage of some of the optional schema-like attributes that ldb -offers, or you can migrate to using the full LDAP api while keeping -your exiting ldb code. - - - -If you are new to ldb, then I suggest starting with the manual pages -for ldbsearch(1) and ldbedit(1), and experimenting with a local -database. Then I suggest you look at the ldb_connect(3) and -ldb_search(3) manual pages. - - - - - TOOLS - - - - ldbsearch(1) - - command line ldb search utility - - - - ldbedit(1) - - edit all or part of a ldb database using your favourite editor - - - - ldbadd(1) - - add records to a ldb database using LDIF formatted input - - - - ldbdel(1) - - delete records from a ldb database - - - - ldbmodify(1) - - modify records in a ldb database using LDIF formatted input - - - - - - FUNCTIONS - - - - ldb_connect(3) - - connect to a ldb backend - - - - ldb_search(3) - - perform a database search - - - - ldb_add(3) - - add a record to the database - - - - ldb_delete(3) - - delete a record from the database - - - - ldb_modify(3) - - modify a record in the database - - - - ldb_errstring(3) - - retrieve extended error information from the last operation - - - - ldb_ldif_write(3) - - write a LDIF formatted message - - - - ldb_ldif_write_file(3) - - write a LDIF formatted message to a file - - - - ldb_ldif_read(3) - - read a LDIF formatted message - - - - ldb_ldif_read_free(3) - - free the result of a ldb_ldif_read() - - - - ldb_ldif_read_file(3) - - read a LDIF message from a file - - - - ldb_ldif_read_string(3) - - read a LDIF message from a string - - - - ldb_msg_find_element(3) - - find an element in a ldb_message - - - - ldb_val_equal_exact(3) - - compare two ldb_val structures - - - - ldb_msg_find_val(3) - - find an element by value - - - - ldb_msg_add_empty(3) - - add an empty message element to a ldb_message - - - - - ldb_msg_add(3) - - add a non-empty message element to a ldb_message - - - - - ldb_msg_element_compare(3) - - compare two ldb_message_element structures - - - - - ldb_msg_find_int(3) - - return an integer value from a ldb_message - - - - - ldb_msg_find_uint(3) - - return an unsigned integer value from a ldb_message - - - - - ldb_msg_find_double(3) - - return a double value from a ldb_message - - - - - ldb_msg_find_string(3) - - return a string value from a ldb_message - - - - - ldb_set_alloc(3) - - set the memory allocation function to be used by ldb - - - - - ldb_set_debug(3) - - set a debug handler to be used by ldb - - - - - ldb_set_debug_stderr(3) - - set a debug handler for stderr output - - - - - - Author - - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - -ldb is released under the GNU Lesser General Public License version 2 -or later. Please see the file COPYING for license details. - - - diff --git a/source4/lib/ldb/man/ldbadd.1.xml b/source4/lib/ldb/man/ldbadd.1.xml deleted file mode 100644 index b77b151e2df..00000000000 --- a/source4/lib/ldb/man/ldbadd.1.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - ldbadd - 1 - - - - - ldbadd - Command-line utility for adding records to an LDB - - - - - ldbadd - -h - -H LDB-URL - ldif-file1 - ldif-file2 - ... - - - - - DESCRIPTION - - ldbadd adds records to an ldb(3) database. It reads - the ldif(5) files specified on the command line and adds - the records from these files to the LDB database, which is specified - by the -H option or the LDB_URL environment variable. - - - If - is specified as a ldb file, the ldif input is read from - standard input. - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overrided by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbdel, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/source4/lib/ldb/man/ldbdel.1.xml b/source4/lib/ldb/man/ldbdel.1.xml deleted file mode 100644 index 41da3bc9845..00000000000 --- a/source4/lib/ldb/man/ldbdel.1.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - ldbdel - 1 - - - - - ldbdel - Command-line program for deleting LDB records - - - - - ldbdel - -h - -H LDB-URL - dn - ... - - - - - DESCRIPTION - - ldbdel deletes records from an ldb(3) database. - It deletes the records identified by the dn's specified - on the command-line. - - ldbdel uses either the database that is specified with - the -H option or the database specified by the LDB_URL environment - variable. - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overrided by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbadd, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - ldbdel was written by Andrew Tridgell. - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/source4/lib/ldb/man/ldbedit.1.xml b/source4/lib/ldb/man/ldbedit.1.xml deleted file mode 100644 index a2eec0579c2..00000000000 --- a/source4/lib/ldb/man/ldbedit.1.xml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - ldbedit - 1 - - - - - ldbedit - Edit LDB databases using your preferred editor - - - - - ldbedit - -? - --usage - -s base|one|sub - -b basedn - -a - -e editor - -H LDB-URL - expression - attributes - - - - - DESCRIPTION - - ldbedit is a utility that allows you to edit LDB entries (in - tdb files, sqlite files or LDAP servers) using your preferred editor. - ldbedit generates an LDIF file based on your query, allows you to edit - the LDIF, and then merges that LDIF back into the LDB backend. - - - - - - - OPTIONS - - - - -? - --help - - - Show list of available options, and a phrase describing what that option - does. - - - - - - --usage - - - Show list of available options. This is similar to the help option, - however it does not provide any description, and is hence shorter. - - - - - - -H <ldb-url> - - - LDB URL to connect to. For a tdb database, - this will be of the form - tdb://filename. - For a LDAP connection over unix domain - sockets, this will be of the form - ldapi://socket. For - a (potentially remote) LDAP connection over - TCP, this will be of the form - ldap://hostname. For - an SQLite database, this will be of the form - sqlite://filename. - - - - - - -s one|sub|base - Search scope to use. One-level, subtree or base. - - - - -a - -all - - Edit all records. This allows you to - apply the same change to a number of records - at once. You probably want to combine this - with an expression of the form - "objectclass=*". - - - - - - -e editor - --editor editor - - Specify the editor that should be used (overrides - the VISUAL and EDITOR environment - variables). If this option is not used, and - neither VISUAL nor EDITOR environment variables - are set, then the vi editor will be used. - - - - - - -b basedn - Specify Base Distinguished Name to use. - - - - -v - --verbose - - Make ldbedit more verbose about the - operations that are being performed. Without - this option, ldbedit will only provide a - summary change line. - - - - - - - - - - ENVIRONMENT - - - - LDB_URL - - LDB URL to connect to. This can be - overridden by using the -H command-line option.) - - - - - VISUAL and EDITOR - - - Environment variables used to determine what - editor to use. VISUAL takes precedence over - EDITOR, and both are overridden by the - -e command-line option. - - - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1) - - - - - AUTHOR - - - ldb was written by - Andrew Tridgell. - - - - If you wish to report a problem or make a suggestion then please see - the web site for - current contact and maintainer information. - - - - This manpage was written by Jelmer Vernooij and updated - by Brad Hards. - - - - - diff --git a/source4/lib/ldb/man/ldbmodify.1.xml b/source4/lib/ldb/man/ldbmodify.1.xml deleted file mode 100644 index 9bb492ab1bb..00000000000 --- a/source4/lib/ldb/man/ldbmodify.1.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - ldbmodify - 1 - - - - - ldbmodify - Modify records in a LDB database - - - - - ldbmodify - -H LDB-URL - ldif-file - - - - - DESCRIPTION - - - ldbmodify changes, adds and deletes records in a LDB database. - The changes that should be made to the LDB database are read from - the specified LDIF-file. If - is specified as the filename, input is read from stdin. - - - For now, see ldapmodify(1) for details on the LDIF file format. - - - - - - OPTIONS - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overrided by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbedit - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/source4/lib/ldb/man/ldbrename.1.xml b/source4/lib/ldb/man/ldbrename.1.xml deleted file mode 100644 index 3576bc27bbc..00000000000 --- a/source4/lib/ldb/man/ldbrename.1.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - ldbrename - 1 - - - - - ldbrename - Edit LDB databases using your favorite editor - - - - - ldbrename - -h - -o options - olddn - newdb - - - - - DESCRIPTION - - ldbrename is a utility that allows you to rename trees in - an LDB database based by DN. This utility takes - two arguments: the original - DN name of the top element and the DN to change it to. - - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - -o options - Extra ldb options, such as - modules. - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overrided by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbdel, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/source4/lib/ldb/man/ldbsearch.1.xml b/source4/lib/ldb/man/ldbsearch.1.xml deleted file mode 100644 index 623a5992e5e..00000000000 --- a/source4/lib/ldb/man/ldbsearch.1.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - ldbsearch - 1 - - - - - ldbsearch - Search for records in a LDB database - - - - - ldbsearch - -h - -s base|one|sub - -b basedn - -i - -H LDB-URL - expression - attributes - - - - - DESCRIPTION - - ldbsearch searches a LDB database for records matching the - specified expression (see the ldapsearch(1) manpage for - a description of the expression format). For each - record, the specified attributes are printed. - - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - -s one|sub|base - Search scope to use. One-level, subtree or base. - - - - -i - Read search expressions from stdin. - - - - -b basedn - Specify Base DN to use. - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overrided by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 4.0 of the Samba suite. - - - - SEE ALSO - - ldb(3), ldbedit(1) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c deleted file mode 100644 index 7482de826f0..00000000000 --- a/source4/lib/ldb/modules/asq.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** 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 attribute scoped query control module - * - * Description: this module searches all the objects pointed by - * the DNs contained in the references attribute - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct asq_context { - - enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_asq_control *asq_ctrl; - - const char * const *req_attrs; - char *req_attribute; - enum { - ASQ_CTRL_SUCCESS = 0, - ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, - ASQ_CTRL_UNWILLING_TO_PERFORM = 53, - ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 - } asq_ret; - - struct ldb_reply *base_res; - - struct ldb_request **reqs; - unsigned int num_reqs; - unsigned int cur_req; - - struct ldb_control **controls; -}; - -static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct asq_context *ac; - - ldb = ldb_module_get_ctx(module); - - ac = talloc_zero(req, struct asq_context); - if (ac == NULL) { - ldb_oom(ldb); - return NULL; - } - - ac->module = module; - ac->req = req; - - return ac; -} - -static int asq_search_continue(struct asq_context *ac); - -static int asq_search_terminate(struct asq_context *ac) -{ - struct ldb_asq_control *asq; - unsigned int i; - - if (ac->controls) { - for (i = 0; ac->controls[i]; i++) /* count em */ ; - } else { - i = 0; - } - - ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); - - if (ac->controls == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i] = talloc(ac->controls, struct ldb_control); - if (ac->controls[i] == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; - ac->controls[i]->critical = 0; - - asq = talloc_zero(ac->controls[i], struct ldb_asq_control); - if (asq == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - asq->result = ac->asq_ret; - - ac->controls[i]->data = asq; - - ac->controls[i + 1] = NULL; - - return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); -} - -static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ac->base_res = talloc_move(ac, &ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - /* next step */ - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - } - return LDB_SUCCESS; -} - -static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* pass the message up to the original callback as we - * do not have to elaborate on it any further */ - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_free(ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - } - - return LDB_SUCCESS; -} - -static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) -{ - struct ldb_context *ldb; - const char **base_attrs; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - ac->req_attrs = ac->req->op.search.attrs; - ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); - if (ac->req_attribute == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - base_attrs = talloc_array(ac, const char *, 2); - if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); - if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[1] = NULL; - - ret = ldb_build_search_req(base_req, ldb, ac, - ac->req->op.search.base, - LDB_SCOPE_BASE, - NULL, - (const char * const *)base_attrs, - NULL, - ac, asq_base_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) -{ - struct ldb_context *ldb; - struct ldb_control **saved_controls; - struct ldb_control *control; - struct ldb_dn *dn; - struct ldb_message_element *el; - unsigned int i; - int ret; - - if (ac->base_res == NULL) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - ldb = ldb_module_get_ctx(ac->module); - - el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); - /* no values found */ - if (el == NULL) { - ac->asq_ret = ASQ_CTRL_SUCCESS; - *terminated = true; - return asq_search_terminate(ac); - } - - ac->num_reqs = el->num_values; - ac->cur_req = 0; - ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); - if (ac->reqs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < el->num_values; i++) { - - dn = ldb_dn_new(ac, ldb, - (const char *)el->values[i].data); - if ( ! ldb_dn_validate(dn)) { - ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; - *terminated = true; - return asq_search_terminate(ac); - } - - ret = ldb_build_search_req_ex(&ac->reqs[i], - ldb, ac, - dn, LDB_SCOPE_BASE, - ac->req->op.search.tree, - ac->req_attrs, - ac->req->controls, - ac, asq_reqs_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* remove the ASQ control itself */ - control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); - if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -static int asq_search_continue(struct asq_context *ac) -{ - struct ldb_context *ldb; - bool terminated = false; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - switch (ac->step) { - case ASQ_SEARCH_BASE: - - /* build up the requests call chain */ - ret = asq_build_multiple_requests(ac, &terminated); - if (ret != LDB_SUCCESS || terminated) { - return ret; - } - - ac->step = ASQ_SEARCH_MULTI; - - return ldb_request(ldb, ac->reqs[ac->cur_req]); - - case ASQ_SEARCH_MULTI: - - ac->cur_req++; - - if (ac->cur_req == ac->num_reqs) { - /* done */ - return asq_search_terminate(ac); - } - - return ldb_request(ldb, ac->reqs[ac->cur_req]); - } - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int asq_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_request *base_req; - struct ldb_control *control; - struct asq_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* check if there's an ASQ control */ - control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = asq_context_init(module, req); - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* check the search is well formed */ - if (req->op.search.scope != LDB_SCOPE_BASE) { - ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; - return asq_search_terminate(ac); - } - - ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); - if (!ac->asq_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - ret = asq_build_first_request(ac, &base_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->step = ASQ_SEARCH_BASE; - - return ldb_request(ldb, base_req); -} - -static int asq_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_asq_module_ops = { - .name = "asq", - .search = asq_search, - .init_context = asq_init -}; - -int ldb_asq_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_asq_module_ops); -} diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c deleted file mode 100644 index 2d6c62fd54b..00000000000 --- a/source4/lib/ldb/modules/paged_results.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** 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: paged_result - * - * Component: ldb paged results control module - * - * Description: this module caches a complete search and sends back - * results in chunks as asked by the client - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct message_store { - /* keep the whole ldb_reply as an optimization - * instead of freeing and talloc-ing the container - * on each result */ - struct ldb_reply *r; - struct message_store *next; -}; - -struct private_data; - -struct results_store { - - struct private_data *priv; - - char *cookie; - time_t timestamp; - - struct results_store *next; - - struct message_store *first; - struct message_store *last; - int num_entries; - - struct message_store *first_ref; - struct message_store *last_ref; - - struct ldb_control **controls; -}; - -struct private_data { - unsigned int next_free_id; - struct results_store *store; - -}; - -static int store_destructor(struct results_store *del) -{ - struct private_data *priv = del->priv; - struct results_store *loop; - - if (priv->store == del) { - priv->store = del->next; - return 0; - } - - for (loop = priv->store; loop; loop = loop->next) { - if (loop->next == del) { - loop->next = del->next; - return 0; - } - } - - /* is not in list ? */ - return -1; -} - -static struct results_store *new_store(struct private_data *priv) -{ - struct results_store *newr; - unsigned int new_id = priv->next_free_id++; - - /* TODO: we should have a limit on the number of - * outstanding paged searches - */ - - newr = talloc(priv, struct results_store); - if (!newr) return NULL; - - newr->priv = priv; - - newr->cookie = talloc_asprintf(newr, "%d", new_id); - if (!newr->cookie) { - talloc_free(newr); - return NULL; - } - - newr->timestamp = time(NULL); - - newr->first = NULL; - newr->num_entries = 0; - newr->first_ref = NULL; - newr->controls = NULL; - - newr->next = priv->store; - priv->store = newr; - - talloc_set_destructor(newr, store_destructor); - - return newr; -} - -struct paged_context { - struct ldb_module *module; - struct ldb_request *req; - - struct results_store *store; - int size; - struct ldb_control **controls; -}; - -static int paged_results(struct paged_context *ac) -{ - struct ldb_paged_control *paged; - struct message_store *msg; - unsigned int i, num_ctrls; - int ret; - - if (ac->store == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - while (ac->store->num_entries > 0 && ac->size > 0) { - msg = ac->store->first; - ret = ldb_module_send_entry(ac->req, msg->r->message, msg->r->controls); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->store->first = msg->next; - talloc_free(msg); - ac->store->num_entries--; - ac->size--; - } - - while (ac->store->first_ref != NULL) { - msg = ac->store->first_ref; - ret = ldb_module_send_referral(ac->req, msg->r->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->store->first_ref = msg->next; - talloc_free(msg); - } - - /* return result done */ - num_ctrls = 1; - i = 0; - - if (ac->store->controls != NULL) { - while (ac->store->controls[i]) i++; /* counting */ - - num_ctrls += i; - } - - ac->controls = talloc_array(ac, struct ldb_control *, num_ctrls +1); - if (ac->controls == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac->controls[num_ctrls] = NULL; - - for (i = 0; i < (num_ctrls -1); i++) { - ac->controls[i] = talloc_reference(ac->controls, ac->store->controls[i]); - } - - ac->controls[i] = talloc(ac->controls, struct ldb_control); - if (ac->controls[i] == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->oid = talloc_strdup(ac->controls[i], - LDB_CONTROL_PAGED_RESULTS_OID); - if (ac->controls[i]->oid == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->critical = 0; - - paged = talloc(ac->controls[i], struct ldb_paged_control); - if (paged == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->data = paged; - - if (ac->size > 0) { - paged->size = 0; - paged->cookie = NULL; - paged->cookie_len = 0; - } else { - paged->size = ac->store->num_entries; - paged->cookie = talloc_strdup(paged, ac->store->cookie); - paged->cookie_len = strlen(paged->cookie) + 1; - } - - return LDB_SUCCESS; -} - -static int paged_search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct paged_context *ac ; - struct message_store *msg_store; - int ret; - - ac = talloc_get_type(req->context, struct paged_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - msg_store = talloc(ac->store, struct message_store); - if (msg_store == NULL) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - msg_store->next = NULL; - msg_store->r = talloc_steal(msg_store, ares); - - if (ac->store->first == NULL) { - ac->store->first = msg_store; - } else { - ac->store->last->next = msg_store; - } - ac->store->last = msg_store; - - ac->store->num_entries++; - - break; - - case LDB_REPLY_REFERRAL: - msg_store = talloc(ac->store, struct message_store); - if (msg_store == NULL) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - msg_store->next = NULL; - msg_store->r = talloc_steal(msg_store, ares); - - if (ac->store->first_ref == NULL) { - ac->store->first_ref = msg_store; - } else { - ac->store->last_ref->next = msg_store; - } - ac->store->last_ref = msg_store; - - break; - - case LDB_REPLY_DONE: - ac->store->controls = talloc_move(ac->store, &ares->controls); - ret = paged_results(ac); - return ldb_module_done(ac->req, ac->controls, - ares->response, ret); - } - - return LDB_SUCCESS; -} - -static int paged_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_control *control; - struct private_data *private_data; - struct ldb_paged_control *paged_ctrl; - struct ldb_control **saved_controls; - struct ldb_request *search_req; - struct paged_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* check if there's a paged request control */ - control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - paged_ctrl = talloc_get_type(control->data, struct ldb_paged_control); - if (!paged_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - private_data = talloc_get_type(ldb_module_get_private(module), - struct private_data); - - ac = talloc_zero(req, struct paged_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->size = paged_ctrl->size; - if (ac->size < 0) { - /* apparently some clients send more than 2^31. This - violates the ldap standard, but we need to cope */ - ac->size = 0x7FFFFFFF; - } - - /* check if it is a continuation search the store */ - if (paged_ctrl->cookie_len == 0) { - if (paged_ctrl->size == 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->store = new_store(private_data); - if (ac->store == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req_ex(&search_req, ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - ac, - paged_search_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!ldb_save_controls(control, search_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); - - } else { - struct results_store *current = NULL; - - /* TODO: age out old outstanding requests */ - for (current = private_data->store; current; current = current->next) { - if (strcmp(current->cookie, paged_ctrl->cookie) == 0) { - current->timestamp = time(NULL); - break; - } - } - if (current == NULL) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ac->store = current; - - /* check if it is an abandon */ - if (ac->size == 0) { - return ldb_module_done(req, NULL, NULL, - LDB_SUCCESS); - } - - ret = paged_results(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - return ldb_module_done(req, ac->controls, NULL, - LDB_SUCCESS); - } -} - -static int paged_request_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - struct private_data *data; - int ret; - - ldb = ldb_module_get_ctx(module); - - data = talloc(module, struct private_data); - if (data == NULL) { - return LDB_ERR_OTHER; - } - - data->next_free_id = 1; - data->store = NULL; - ldb_module_set_private(module, data); - - ret = ldb_mod_register_control(module, LDB_CONTROL_PAGED_RESULTS_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "paged_results:" - "Unable to register control with rootdse!"); - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_paged_results_module_ops = { - .name = "paged_results", - .search = paged_search, - .init_context = paged_request_init -}; - -int ldb_paged_results_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_paged_results_module_ops); -} diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c deleted file mode 100644 index 68eeb4c76e3..00000000000 --- a/source4/lib/ldb/modules/paged_searches.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - Copyright (C) Andrew Bartlett 2009 - - ** 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: paged_searches - * - * Component: ldb paged searches module - * - * Description: this module detects if the remote ldap server supports - * paged results and use them to transparently access all objects - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -#define PS_DEFAULT_PAGE_SIZE 500 -/* 500 objects per query seem to be a decent compromise - * the default AD limit per request is 1000 entries */ - -struct private_data { - - bool paged_supported; -}; - -struct ps_context { - struct ldb_module *module; - struct ldb_request *req; - - bool pending; - - char **saved_referrals; - unsigned int num_referrals; - - struct ldb_request *down_req; -}; - -static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct ldb_control *rep_control, *req_control; - struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; - ldb = ldb_module_get_ctx(ac->module); - - rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); - if (rep_control) { - paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); - } - - req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); - paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); - - if (!rep_control || !paged_rep_control) { - if (paged_req_control->cookie) { - /* something wrong here - why give us a control back befre, but not one now? */ - ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); - return LDB_ERR_OPERATIONS_ERROR; - } else { - /* No cookie received yet, valid to just return the full data set */ - - /* we are done */ - ac->pending = false; - return LDB_SUCCESS; - } - } - - if (paged_rep_control->cookie_len == 0) { - /* we are done */ - ac->pending = false; - return LDB_SUCCESS; - } - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - /* if there's a reply control we must find a request - * control matching it */ - - if (paged_req_control->cookie) { - talloc_free(paged_req_control->cookie); - } - - paged_req_control->cookie = talloc_memdup(req_control, - paged_rep_control->cookie, - paged_rep_control->cookie_len); - paged_req_control->cookie_len = paged_rep_control->cookie_len; - - ac->pending = true; - return LDB_SUCCESS; -} - -static int store_referral(struct ps_context *ac, char *referral) -{ - ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); - if (!ac->saved_referrals) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); - if (!ac->saved_referrals[ac->num_referrals]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->num_referrals++; - ac->saved_referrals[ac->num_referrals] = NULL; - - return LDB_SUCCESS; -} - -static int send_referrals(struct ps_context *ac) -{ - struct ldb_reply *ares; - int ret; - unsigned int i; - - for (i = 0; i < ac->num_referrals; i++) { - ares = talloc_zero(ac->req, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = ac->saved_referrals[i]; - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ps_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct ps_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_REFERRAL: - ret = store_referral(ac, ares->referral); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_DONE: - - ret = check_ps_continuation(ac, req, ares); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - if (ac->pending) { - - ret = ldb_next_request(ac->module, ac->down_req); - - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - } else { - - /* send referrals */ - ret = send_referrals(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - /* send REPLY_DONE */ - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - break; - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct private_data *private_data; - struct ps_context *ac; - struct ldb_paged_control *control; - int ret; - - private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); - ldb = ldb_module_get_ctx(module); - - /* check if paging is supported */ - if (!private_data || !private_data->paged_supported) { - /* do not touch this request paged controls not - * supported or we - * are just not setup yet */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct ps_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->pending = false; - ac->saved_referrals = NULL; - ac->num_referrals = 0; - - ldb = ldb_module_get_ctx(ac->module); - - control = talloc(ac, struct ldb_paged_control); - if (!control) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control->size = PS_DEFAULT_PAGE_SIZE; - control->cookie = NULL; - control->cookie_len = 0; - - ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, - ac->req->op.search.base, - ac->req->op.search.scope, - ac->req->op.search.tree, - ac->req->op.search.attrs, - ac->req->controls, - ac, - ps_callback, - ac->req); - LDB_REQ_SET_LOCATION(ac->down_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, - true, control); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(ac->down_req, control); - - return ldb_next_request(ac->module, ac->down_req); -} - -static int check_supported_paged(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct private_data *data; - - data = talloc_get_type(req->context, struct private_data); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - if (ldb_msg_check_string_attribute(ares->message, - "supportedControl", - LDB_CONTROL_PAGED_RESULTS_OID)) { - data->paged_supported = true; - } - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - break; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - static const char *attrs[] = { "supportedControl", NULL }; - struct private_data *data; - struct ldb_dn *base; - int ret; - struct ldb_request *req; - - ldb = ldb_module_get_ctx(module); - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - data->paged_supported = false; - - ldb_module_set_private(module, data); - - base = ldb_dn_new(module, ldb, ""); - if (base == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_build_search_req(&req, ldb, module, - base, LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, NULL, - data, check_supported_paged, - NULL); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_next_request(module, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_free(base); - talloc_free(req); - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_paged_searches_module_ops = { - .name = "paged_searches", - .search = ps_search, - .init_context = ps_init -}; - -int ldb_paged_searches_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_paged_searches_module_ops); -} diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c deleted file mode 100644 index 50b63aee133..00000000000 --- a/source4/lib/ldb/modules/rdn_name.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlett 2005-2009 - Copyright (C) Simo Sorce 2006-2008 - - ** 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: rdn_name - * - * Component: ldb rdn name module - * - * Description: keep a consistent name attribute on objects manpulations - * - * Author: Andrew Bartlett - * - * Modifications: - * - made the module async - * Simo Sorce Mar 2006 - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct rename_context { - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_reply *ares; -}; - -static int rdn_name_add_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); -} - -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_request *down_req; - struct rename_context *ac; - struct ldb_message *msg; - struct ldb_message_element *attribute; - const struct ldb_schema_attribute *a; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - msg = ldb_msg_copy_shallow(req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.add.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - /* Perhaps someone above us tried to set this? Then ignore it */ - ldb_msg_remove_attr(msg, "name"); - - ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - - a = ldb_schema_attribute_by_name(ldb, rdn_name); - if (a == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - attribute = ldb_msg_find_element(msg, rdn_name); - if (!attribute) { - /* add entry with normalised RDN information if possible */ - if (a->name != NULL) { - ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); - } else { - ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - } else { - /* normalise attribute name if possible */ - if (a->name != NULL) { - attribute->name = a->name; - } - /* normalise attribute value */ - for (i = 0; i < attribute->num_values; i++) { - bool matched; - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &rdn_val, &attribute->values[i], &matched); - if (ret != LDB_SUCCESS) return ret; - } else { - matched = (a->syntax->comparison_fn(ldb, msg, - &rdn_val, &attribute->values[i]) == 0); - } - if (matched) { - /* overwrite so it matches in case */ - attribute->values[i] = rdn_val; - break; - } - } - if (i == attribute->num_values) { - char *rdn_errstring = talloc_asprintf(ac, - "RDN mismatch on %s: %s (%.*s) should match one of:", - ldb_dn_get_linearized(msg->dn), rdn_name, - (int)rdn_val.length, (const char *)rdn_val.data); - for (i = 0; i < attribute->num_values; i++) { - rdn_errstring = talloc_asprintf_append( - rdn_errstring, " (%.*s)", - (int)attribute->values[i].length, - (const char *)attribute->values[i].data); - } - ldb_set_errstring(ldb, rdn_errstring); - /* Match AD's error here */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - } - - ret = ldb_build_add_req(&down_req, ldb, req, - msg, - req->controls, - ac, rdn_name_add_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(down_req, msg); - - /* go on with the call chain */ - return ldb_next_request(module, down_req); -} - -static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* send saved controls eventually */ - return ldb_module_done(ac->req, ac->ares->controls, - ac->ares->response, LDB_SUCCESS); -} - -static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *mod_req; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - struct ldb_message *msg; - int ret; - - ac = talloc_get_type(req->context, struct rename_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - goto error; - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - goto error; - } - - /* save reply for caller */ - ac->ares = talloc_steal(ac, ares); - - msg = ldb_msg_new(ac); - if (msg == NULL) { - goto error; - } - msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); - if (msg->dn == NULL) { - goto error; - } - - rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); - if (rdn_name == NULL) { - goto error; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - goto error; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.rename.olddn)); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_NAMING_VIOLATION); - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - goto error; - } - if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - goto error; - } - - ret = ldb_build_mod_req(&mod_req, ldb, - ac, msg, NULL, - ac, rdn_modify_callback, - req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_steal(mod_req, msg); - - /* go on with the call chain */ - return ldb_next_request(ac->module, mod_req); - -error: - return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); -} - -static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *down_req; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.newdn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - ret = ldb_build_rename_req(&down_req, - ldb, - ac, - req->op.rename.olddn, - req->op.rename.newdn, - req->controls, - ac, - rdn_rename_callback, - req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* rename first, modify "name" if rename is ok */ - return ldb_next_request(module, down_req); -} - -static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const struct ldb_val *rdn_val_p; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return ldb_next_request(module, req); - } - - rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - if (ldb_msg_find_element(req->op.mod.message, "distinguishedName")) { - ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - if (ldb_msg_find_element(req->op.mod.message, "name")) { - ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { - ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - /* All OK, they kept their fingers out of the special attributes */ - return ldb_next_request(module, req); -} - -static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) { - return ldb_next_request(module, req); - } - - rdn_name = ldb_dn_get_rdn_name(req->op.search.base); - rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); - if ((rdn_name != NULL) && (rdn_val_p == NULL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.search.base)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - return ldb_next_request(module, req); -} - -static const struct ldb_module_ops ldb_rdn_name_module_ops = { - .name = "rdn_name", - .add = rdn_name_add, - .modify = rdn_name_modify, - .rename = rdn_name_rename, - .search = rdn_name_search -}; - -int ldb_rdn_name_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_rdn_name_module_ops); -} diff --git a/source4/lib/ldb/modules/skel.c b/source4/lib/ldb/modules/skel.c deleted file mode 100644 index 1ce3ec1df97..00000000000 --- a/source4/lib/ldb/modules/skel.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 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 skel module - * - * Description: example module - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct private_data { - - char *some_private_data; -}; - -/* search */ -static int skel_search(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* add */ -static int skel_add(struct ldb_module *module, struct ldb_request *req){ - return ldb_next_request(module, req); -} - -/* modify */ -static int skel_modify(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* delete */ -static int skel_delete(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* rename */ -static int skel_rename(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* start a transaction */ -static int skel_start_trans(struct ldb_module *module) -{ - return ldb_next_start_trans(module); -} - -/* end a transaction */ -static int skel_end_trans(struct ldb_module *module) -{ - return ldb_next_end_trans(module); -} - -/* delete a transaction */ -static int skel_del_trans(struct ldb_module *module) -{ - return ldb_next_del_trans(module); -} - -static int skel_destructor(struct ldb_module *ctx) -{ - struct private_data *data; - - data = talloc_get_type(ldb_module_get_private(ctx), struct private_data); - - /* put your clean-up functions here */ - if (data->some_private_data) talloc_free(data->some_private_data); - - return 0; -} - -static int skel_request(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -static int skel_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - struct private_data *data; - - ldb = ldb_module_get_ctx(module); - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - data->some_private_data = NULL; - ldb_module_set_private(module, data); - - talloc_set_destructor (module, skel_destructor); - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_skel_module_ops = { - .name = "skel", - .init_context = skel_init, - .search = skel_search, - .add = skel_add, - .modify = skel_modify, - .del = skel_delete, - .rename = skel_rename, - .request = skel_request, - .start_transaction = skel_start_trans, - .end_transaction = skel_end_trans, - .del_transaction = skel_del_trans, -}; - -int ldb_skel_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_skel_module_ops); -} diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c deleted file mode 100644 index c6fce2d96e0..00000000000 --- a/source4/lib/ldb/modules/sort.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** 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 server side sort control module - * - * Description: this module sorts the results of a search - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct opaque { - struct ldb_context *ldb; - const struct ldb_attrib_handler *h; - const char *attribute; - int reverse; - int result; -}; - -struct sort_context { - struct ldb_module *module; - - const char *attributeName; - const char *orderingRule; - int reverse; - - struct ldb_request *req; - struct ldb_message **msgs; - char **referrals; - unsigned int num_msgs; - unsigned int num_refs; - - const struct ldb_schema_attribute *a; - int sort_result; -}; - -static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) -{ - struct ldb_control **controls; - struct ldb_sort_resp_control *resp; - unsigned int i; - - if (*ctrls) { - controls = *ctrls; - for (i = 0; controls[i]; i++); - controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); - } else { - i = 0; - controls = talloc_array(mem_ctx, struct ldb_control *, 2); - } - if (! controls ) - return LDB_ERR_OPERATIONS_ERROR; - - *ctrls = controls; - - controls[i+1] = NULL; - controls[i] = talloc(controls, struct ldb_control); - if (! controls[i] ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; - controls[i]->critical = 0; - - resp = talloc(controls[i], struct ldb_sort_resp_control); - if (! resp ) - return LDB_ERR_OPERATIONS_ERROR; - - resp->result = result; - resp->attr_desc = talloc_strdup(resp, desc); - - if (! resp->attr_desc ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->data = resp; - - return LDB_SUCCESS; -} - -static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) -{ - struct sort_context *ac = talloc_get_type(opaque, struct sort_context); - struct ldb_message_element *el1, *el2; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->sort_result != 0) { - /* an error occurred previously, - * let's exit the sorting by returning always 0 */ - return 0; - } - - el1 = ldb_msg_find_element(*msg1, ac->attributeName); - el2 = ldb_msg_find_element(*msg2, ac->attributeName); - - if (!el1 && el2) { - return 1; - } - if (el1 && !el2) { - return -1; - } - if (!el1 && !el2) { - return 0; - } - - if (ac->reverse) - return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], &el1->values[0]); - - return ac->a->syntax->comparison_fn(ldb, ac, &el1->values[0], &el2->values[0]); -} - -static int server_sort_results(struct sort_context *ac) -{ - struct ldb_context *ldb; - struct ldb_reply *ares; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - ac->a = ldb_schema_attribute_by_name(ldb, ac->attributeName); - ac->sort_result = 0; - - LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); - - if (ac->sort_result != LDB_SUCCESS) { - return ac->sort_result; - } - - for (i = 0; i < ac->num_msgs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_move(ares, &ac->msgs[i]); - - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - for (i = 0; i < ac->num_refs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_move(ares, &ac->referrals[i]); - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct sort_context *ac; - struct ldb_context *ldb; - int ret; - - ac = talloc_get_type(req->context, struct sort_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); - if (! ac->msgs) { - talloc_free(ares); - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); - ac->num_msgs++; - ac->msgs[ac->num_msgs] = NULL; - - break; - - case LDB_REPLY_REFERRAL: - ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); - if (! ac->referrals) { - talloc_free(ares); - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); - ac->num_refs++; - ac->referrals[ac->num_refs] = NULL; - - break; - - case LDB_REPLY_DONE: - - ret = server_sort_results(ac); - return ldb_module_done(ac->req, ares->controls, - ares->response, ret); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int server_sort_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct ldb_server_sort_control **sort_ctrls; - struct ldb_control **saved_controls; - struct ldb_control **controls; - struct ldb_request *down_req; - struct sort_context *ac; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* check if there's a server sort control */ - control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct sort_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); - if (!sort_ctrls) { - return LDB_ERR_PROTOCOL_ERROR; - } - - /* FIXME: we do not support more than one attribute for sorting right now */ - /* FIXME: we need to check if the attribute type exist or return an error */ - - if (sort_ctrls[1] != NULL) { - if (control->critical) { - - /* callback immediately */ - ret = build_response(req, &controls, - LDB_ERR_UNWILLING_TO_PERFORM, - "sort control is not complete yet"); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(req, controls, NULL, ret); - } else { - /* just pass the call down and don't do any sorting */ - return ldb_next_request(module, req); - } - } - - ac->attributeName = sort_ctrls[0]->attributeName; - ac->orderingRule = sort_ctrls[0]->orderingRule; - ac->reverse = sort_ctrls[0]->reverse; - - ret = ldb_build_search_req_ex(&down_req, ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - ac, - server_sort_search_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!ldb_save_controls(control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, down_req); -} - -static int server_sort_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "server_sort:" - "Unable to register control with rootdse!"); - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_server_sort_module_ops = { - .name = "server_sort", - .search = server_sort_search, - .init_context = server_sort_init -}; - -int ldb_server_sort_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_server_sort_module_ops); -} diff --git a/source4/lib/ldb/nssldb/README.txt b/source4/lib/ldb/nssldb/README.txt deleted file mode 100644 index ddba62b3804..00000000000 --- a/source4/lib/ldb/nssldb/README.txt +++ /dev/null @@ -1,34 +0,0 @@ - -This test code requires a tdb that is configured for to use the asq module. -You can do that adding the following record to a tdb: - -dn: @MODULES -@LIST: asq - -Other modules can be used as well (like rdn_name for example) - -The uidNumber 0 and the gidNumber 0 are considered invalid. - -The user records should contain the followin attributes: -uid (required) the user name -userPassword (optional) the user password (if not present "LDB" is - returned in the password field) -uidNumber (required) the user uid -gidNumber (required) the user primary gid -gecos (optional) the GECOS -homeDirectory (required) the home directory -loginShell (required) the login shell -memberOf (required) all the groups the user is member of should - be reported here using their DNs. The - primary group as well. - -The group accounts should contain the following attributes: -cn (required) the group name -uesrPassword (optional) the group password (if not present "LDB" is - returned in the password field) -gidNumber (required) the group gid -member (optional) the DNs of the member users, also the ones - that have this group as primary - - -SSS diff --git a/source4/lib/ldb/nssldb/ldb-grp.c b/source4/lib/ldb/nssldb/ldb-grp.c deleted file mode 100644 index 5e7556dc735..00000000000 --- a/source4/lib/ldb/nssldb/ldb-grp.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_gr_attrs[] = { - "cn", - "userPassword", - "gidNumber", - NULL -}; - -const char *_ldb_nss_mem_attrs[] = { - "uid", - NULL -}; - -#define _NSS_LDB_ENOMEM(amem) \ - do { \ - if ( ! amem) { \ - errno = ENOMEM; \ - talloc_free(memctx); \ - return NSS_STATUS_UNAVAIL; \ - } \ - } while(0) - -/* This setgrent, getgrent, endgrent is not very efficient */ - -NSS_STATUS _nss_ldb_setgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res != NULL) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &_ldb_nss_ctx->gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - _LDB_NSS_GRENT_FILTER); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); - if ( ! res) { - errno = *errnop = ENOMEM; - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return NSS_STATUS_UNAVAIL; - } - - ret = _ldb_nss_group_request(&res, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - talloc_free(res); - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return ret; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], - res); - - talloc_free(res); - - if (ret != NSS_STATUS_SUCCESS) { - if (ret != NSS_STATUS_TRYAGAIN) { - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - } - return ret; - } - - /* this entry is ok, increment counter to nex entry */ - _ldb_nss_ctx->gr_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - if (gid == 0) { /* we don't serve root gid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) -{ - int ret; - char *filter; - const char * attrs[] = { "uidNumber", "gidNumber", NULL }; - struct ldb_result *uid_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this name */ - filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &uid_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(mem_res, uid_res); - - /* if none found return */ - if (uid_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (uid_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - uid_res->msgs[0]->dn, - attrs, - "memberOf"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_initgr(group, - limit, - start, - size, - groups, - errnop, - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; - -done: - talloc_free(mem_res); - return ret; -} diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c deleted file mode 100644 index 92b0635561e..00000000000 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -struct _ldb_nss_context *_ldb_nss_ctx = NULL; - -NSS_STATUS _ldb_nss_init(void) -{ - int ret; - - pid_t mypid = getpid(); - - if (_ldb_nss_ctx != NULL) { - if (_ldb_nss_ctx->pid == mypid) { - /* already initialized */ - return NSS_STATUS_SUCCESS; - } else { - /* we are in a forked child now, reinitialize */ - talloc_free(_ldb_nss_ctx); - _ldb_nss_ctx = NULL; - } - } - - _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); - if (_ldb_nss_ctx == NULL) { - return NSS_STATUS_UNAVAIL; - } - - _ldb_nss_ctx->pid = mypid; - - _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); - if (_ldb_nss_ctx->ldb == NULL) { - goto failed; - } - - ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); - if (ret != LDB_SUCCESS) { - goto failed; - } - - _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); - if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { - goto failed; - } - - _ldb_nss_ctx->pw_cur = 0; - _ldb_nss_ctx->pw_res = NULL; - _ldb_nss_ctx->gr_cur = 0; - _ldb_nss_ctx->gr_res = NULL; - - return NSS_STATUS_SUCCESS; - -failed: - /* talloc_free(_ldb_nss_ctx); */ - _ldb_nss_ctx = NULL; - return NSS_STATUS_UNAVAIL; -} - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg) -{ - int len; - int bufpos; - const char *tmp; - - bufpos = 0; - - /* get username */ - tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_passwd = &buffer[bufpos]; - bufpos += len; - - /* this backend never serves an uid 0 user */ - result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); - if (result->pw_uid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); - if (result->pw_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* get gecos */ - tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_gecos = &buffer[bufpos]; - bufpos += len; - - /* get homeDirectory */ - tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_dir = &buffer[bufpos]; - bufpos += len; - - /* get shell */ - tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_shell = &buffer[bufpos]; - bufpos += len; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members) -{ - const char *tmp; - size_t len; - size_t bufpos; - size_t lsize; - unsigned int i; - - bufpos = 0; - - /* get group name */ - tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_passwd = &buffer[bufpos]; - bufpos += len; - - result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); - if (result->gr_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* check if there is enough memory for the list of pointers */ - lsize = (members->count + 1) * sizeof(char *); - - /* align buffer on pointer boundary */ - bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); - if ((buflen - bufpos) < lsize) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - - result->gr_mem = (char **)&buffer[bufpos]; - bufpos += lsize; - - for (i = 0; i < members->count; i++) { - tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_mem[i] = &buffer[bufpos]; - bufpos += len; - } - - result->gr_mem[i] = NULL; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist) -{ - NSS_STATUS ret; - unsigned int i; - - for (i = 0; i < grlist->count; i++) { - - if (limit && (*start > limit)) { - /* TODO: warn no all groups were reported */ - *errnop = 0; - ret = NSS_STATUS_SUCCESS; - goto done; - } - - if (*start == *size) { - /* buffer full, enlarge it */ - long int gs; - gid_t *gm; - - gs = (*size) + 32; - if (limit && (gs > limit)) { - gs = limit; - } - - gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); - if ( ! gm) { - *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - *groups = gm; - *size = gs; - } - - (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); - if ((*groups)[*start] == 0 || (*groups)[*start] == group) { - /* skip root group or primary group */ - continue; - } - (*start)++; - - } - - *errnop = 0; - ret = NSS_STATUS_SUCCESS; -done: - return ret; -} - -#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr) -{ - struct ldb_control **ctrls; - struct ldb_control *ctrl; - struct ldb_asq_control *asqc; - struct ldb_request *req; - int ret; - struct ldb_result *res = *_res; - - ctrls = talloc_array(res, struct ldb_control *, 2); - _LDB_NSS_ALLOC_CHECK(ctrls); - - ctrl = talloc(ctrls, struct ldb_control); - _LDB_NSS_ALLOC_CHECK(ctrl); - - asqc = talloc(ctrl, struct ldb_asq_control); - _LDB_NSS_ALLOC_CHECK(asqc); - - asqc->source_attribute = talloc_strdup(asqc, mattr); - _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); - - asqc->request = 1; - asqc->src_attr_len = strlen(asqc->source_attribute); - ctrl->oid = LDB_CONTROL_ASQ_OID; - ctrl->critical = 1; - ctrl->data = asqc; - ctrls[0] = ctrl; - ctrls[1] = NULL; - - ret = ldb_build_search_req( - &req, - _ldb_nss_ctx->ldb, - res, - group_dn, - LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, - ctrls, - res, - ldb_search_default_callback); - - if (ret != LDB_SUCCESS) { - errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); - - ret = ldb_request(_ldb_nss_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } else { - talloc_free(req); - return NSS_STATUS_UNAVAIL; - } - - talloc_free(req); - return NSS_STATUS_SUCCESS; -} - diff --git a/source4/lib/ldb/nssldb/ldb-nss.h b/source4/lib/ldb/nssldb/ldb-nss.h deleted file mode 100644 index 583876fea67..00000000000 --- a/source4/lib/ldb/nssldb/ldb-nss.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef _LDB_NSS -#define _LDB_NSS - -#include "includes.h" -#include "ldb/include/includes.h" - -#include -#include -#include - -#define _LDB_NSS_URL "etc/users.ldb" -#define _LDB_NSS_BASEDN "CN=Users,CN=System" -#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" -#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" -#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" - -#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" -#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" -#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" - -typedef enum nss_status NSS_STATUS; - -struct _ldb_nss_context { - - pid_t pid; - - struct ldb_context *ldb; - struct ldb_dn *base; - - int pw_cur; - struct ldb_result *pw_res; - - int gr_cur; - struct ldb_result *gr_res; -}; - -NSS_STATUS _ldb_nss_init(void); - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg); - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members); - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist); - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr); - -#endif /* _LDB_NSS */ diff --git a/source4/lib/ldb/nssldb/ldb-pwd.c b/source4/lib/ldb/nssldb/ldb-pwd.c deleted file mode 100644 index 6ab103a6fed..00000000000 --- a/source4/lib/ldb/nssldb/ldb-pwd.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_pw_attrs[] = { - "uid", - "userPassword", - "uidNumber", - "gidNumber", - "gecos", - "homeDirectory", - "loginShell", - NULL -}; - -NSS_STATUS _nss_ldb_setpwent(void) -{ - int ret; - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res != NULL) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &_ldb_nss_ctx->pw_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - _LDB_NSS_PWENT_FILTER); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endpwent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, - char *buffer, - int buflen, - int *errnop) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - if (uid == 0) { /* we don't serve root uid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - -NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this name */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - diff --git a/source4/lib/ldb/pyldb-util.pc.in b/source4/lib/ldb/pyldb-util.pc.in deleted file mode 100644 index 348ae8b95d6..00000000000 --- a/source4/lib/ldb/pyldb-util.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -modulesdir=@LDB_MODULESDIR@ - -Name: pyldb-util -Description: Python bindings for LDB -Version: @PACKAGE_VERSION@ -Requires: ldb -Libs: @LIB_RPATH@ -L${libdir} -lpyldb-util -Cflags: -I${includedir} -URL: http://ldb.samba.org/ diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c deleted file mode 100644 index e2a2e7180e1..00000000000 --- a/source4/lib/ldb/pyldb.c +++ /dev/null @@ -1,3302 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb. - - Copyright (C) 2005,2006 Tim Potter - Copyright (C) 2006 Simo Sorce - Copyright (C) 2007-2010 Jelmer Vernooij - Copyright (C) 2009-2010 Matthias Dieter Wallnöfer - Copyright (C) 2009-2011 Andrew Tridgell - Copyright (C) 2009-2011 Andrew Bartlett - - ** 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 . -*/ - -#include -#include -#include "ldb_private.h" -#include "pyldb.h" - -void initldb(void); -static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); -static PyObject *PyExc_LdbError; - -staticforward PyTypeObject PyLdbControl; -staticforward PyTypeObject PyLdbResult; -staticforward PyTypeObject PyLdbMessage; -staticforward PyTypeObject PyLdbModule; -staticforward PyTypeObject PyLdbDn; -staticforward PyTypeObject PyLdb; -staticforward PyTypeObject PyLdbMessageElement; -staticforward PyTypeObject PyLdbTree; -static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); -static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); -static struct ldb_message_element *PyObject_AsMessageElement( - TALLOC_CTX *mem_ctx, - PyObject *set_obj, - unsigned int flags, - const char *attr_name); - -/* There's no Py_ssize_t in 2.4, apparently */ -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 -typedef int Py_ssize_t; -typedef inquiry lenfunc; -typedef intargfunc ssizeargfunc; -#endif - -#ifndef Py_RETURN_NONE -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - -#define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1)) - - - -static PyObject *py_ldb_control_str(PyLdbControlObject *self) -{ - if (self->data != NULL) { - char* control = ldb_control_to_string(self->mem_ctx, self->data); - if (control == NULL) { - PyErr_NoMemory(); - return NULL; - } - return PyString_FromString(control); - } else { - return PyString_FromFormat("ldb control"); - } -} - -static void py_ldb_control_dealloc(PyLdbControlObject *self) -{ - if (self->mem_ctx != NULL) { - talloc_free(self->mem_ctx); - } - self->data = NULL; - self->ob_type->tp_free(self); -} - -static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self) -{ - return PyString_FromString(self->data->oid); -} - -static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self) -{ - return PyBool_FromLong(self->data->critical); -} - -static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) -{ - if (PyObject_IsTrue(value)) { - self->data->critical = true; - } else { - self->data->critical = false; - } - return 0; -} - -static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - char *data = NULL; - const char * const kwnames[] = { "ldb", "data", NULL }; - struct ldb_control *parsed_controls; - PyLdbControlObject *ret; - PyObject *py_ldb; - TALLOC_CTX *mem_ctx; - struct ldb_context *ldb_ctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os", - discard_const_p(char *, kwnames), - &py_ldb, &data)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ldb_ctx = PyLdb_AsLdbContext(py_ldb); - parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); - - if (!parsed_controls) { - talloc_free(mem_ctx); - PyErr_SetString(PyExc_ValueError, "unable to parse control string"); - return NULL; - } - - ret = PyObject_New(PyLdbControlObject, type); - if (ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - ret->mem_ctx = mem_ctx; - - ret->data = talloc_move(mem_ctx, &parsed_controls); - if (ret->data == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - return (PyObject *)ret; -} - -static PyGetSetDef py_ldb_control_getset[] = { - { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL }, - { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL }, - { NULL } -}; - -static PyTypeObject PyLdbControl = { - .tp_name = "ldb.control", - .tp_dealloc = (destructor)py_ldb_control_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbControlObject), - .tp_getset = py_ldb_control_getset, - .tp_doc = "LDB control.", - .tp_str = (reprfunc)py_ldb_control_str, - .tp_new = py_ldb_control_new, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) -{ - if (ret == LDB_ERR_PYTHON_EXCEPTION) - return; /* Python exception should already be set, just keep that */ - - PyErr_SetObject(error, - Py_BuildValue(discard_const_p(char, "(i,s)"), ret, - ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); -} - -static PyObject *PyObject_FromLdbValue(struct ldb_val *val) -{ - return PyString_FromStringAndSize((const char *)val->data, val->length); -} - -/** - * Create a Python object from a ldb_result. - * - * @param result LDB result to convert - * @return Python object with converted result (a list object) - */ -static PyObject *PyLdbControl_FromControl(struct ldb_control *control) -{ - TALLOC_CTX *ctl_ctx = talloc_new(NULL); - PyLdbControlObject *ctrl; - if (ctl_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); - if (ctrl == NULL) { - talloc_free(ctl_ctx); - PyErr_NoMemory(); - return NULL; - } - ctrl->mem_ctx = ctl_ctx; - ctrl->data = talloc_steal(ctrl->mem_ctx, control); - if (ctrl->data == NULL) { - Py_DECREF(ctrl); - PyErr_NoMemory(); - return NULL; - } - return (PyObject*) ctrl; -} - -/** - * Create a Python object from a ldb_result. - * - * @param result LDB result to convert - * @return Python object with converted result (a list object) - */ -static PyObject *PyLdbResult_FromResult(struct ldb_result *result) -{ - PyLdbResultObject *ret; - PyObject *list, *controls, *referals; - Py_ssize_t i; - - if (result == NULL) { - Py_RETURN_NONE; - } - - ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - list = PyList_New(result->count); - if (list == NULL) { - PyErr_NoMemory(); - Py_DECREF(ret); - return NULL; - } - - for (i = 0; i < result->count; i++) { - PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); - } - - ret->mem_ctx = talloc_new(NULL); - if (ret->mem_ctx == NULL) { - Py_DECREF(list); - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - - ret->msgs = list; - - if (result->controls) { - controls = PyList_New(1); - if (controls == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - for (i=0; result->controls[i]; i++) { - PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); - if (ctrl == NULL) { - Py_DECREF(ret); - Py_DECREF(controls); - PyErr_NoMemory(); - return NULL; - } - PyList_SetItem(controls, i, ctrl); - } - } else { - /* - * No controls so we keep an empty list - */ - controls = PyList_New(0); - if (controls == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - } - - ret->controls = controls; - - i = 0; - - while (result->refs && result->refs[i]) { - i++; - } - - referals = PyList_New(i); - if (referals == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - - for (i = 0;result->refs && result->refs[i]; i++) { - PyList_SetItem(referals, i, PyString_FromString(result->refs[i])); - } - ret->referals = referals; - return (PyObject *)ret; -} - -/** - * Create a LDB Result from a Python object. - * If conversion fails, NULL will be returned and a Python exception set. - * - * @param mem_ctx Memory context in which to allocate the LDB Result - * @param obj Python object to convert - * @return a ldb_result, or NULL if the conversion failed - */ -static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, - PyObject *obj) -{ - struct ldb_result *res; - Py_ssize_t i; - - if (obj == Py_None) - return NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - res->count = PyList_Size(obj); - res->msgs = talloc_array(res, struct ldb_message *, res->count); - for (i = 0; i < res->count; i++) { - PyObject *item = PyList_GetItem(obj, i); - res->msgs[i] = PyLdbMessage_AsMessage(item); - } - return res; -} - -static PyObject *py_ldb_dn_validate(PyLdbDnObject *self) -{ - return PyBool_FromLong(ldb_dn_validate(self->dn)); -} - -static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self) -{ - return PyBool_FromLong(ldb_dn_is_valid(self->dn)); -} - -static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self) -{ - return PyBool_FromLong(ldb_dn_is_special(self->dn)); -} - -static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self) -{ - return PyBool_FromLong(ldb_dn_is_null(self->dn)); -} - -static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self) -{ - return PyString_FromString(ldb_dn_get_casefold(self->dn)); -} - -static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) -{ - return PyString_FromString(ldb_dn_get_linearized(self->dn)); -} - -static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self) -{ - return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn)); -} - -static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self) -{ - return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); -} - -static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "mode", NULL }; - int mode = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", - discard_const_p(char *, kwnames), - &mode)) - return NULL; - return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); -} - -static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) -{ - char *name; - const struct ldb_val *val; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - val = ldb_dn_get_extended_component(self->dn, name); - if (val == NULL) { - Py_RETURN_NONE; - } - - return PyString_FromStringAndSize((const char *)val->data, val->length); -} - -static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) -{ - char *name; - PyObject *value; - int err; - - if (!PyArg_ParseTuple(args, "sO", &name, &value)) - return NULL; - - if (value == Py_None) { - err = ldb_dn_set_extended_component(self->dn, name, NULL); - } else { - struct ldb_val val; - if (!PyString_Check(value)) { - PyErr_SetString(PyExc_TypeError, "Expected a string argument"); - return NULL; - } - val.data = (uint8_t *)PyString_AsString(value); - val.length = PyString_Size(value); - err = ldb_dn_set_extended_component(self->dn, name, &val); - } - - if (err != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) -{ - return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn)))); -} - -static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args) -{ - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - return ldb_dn_check_special(self->dn, name)?Py_True:Py_False; -} - -static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2) -{ - int ret; - ret = ldb_dn_compare(dn1->dn, dn2->dn); - if (ret < 0) ret = -1; - if (ret > 0) ret = 1; - return ret; -} - -static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self) -{ - struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self); - struct ldb_dn *parent; - PyLdbDnObject *py_ret; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - parent = ldb_dn_get_parent(mem_ctx, dn); - if (parent == NULL) { - talloc_free(mem_ctx); - Py_RETURN_NONE; - } - - py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - py_ret->mem_ctx = mem_ctx; - py_ret->dn = parent; - return (PyObject *)py_ret; -} - -#define dn_ldb_ctx(dn) ((struct ldb_context *)dn) - -static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args) -{ - PyObject *py_other; - struct ldb_dn *dn, *other; - if (!PyArg_ParseTuple(args, "O", &py_other)) - return NULL; - - dn = PyLdbDn_AsDn((PyObject *)self); - - if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other)) - return NULL; - - return ldb_dn_add_child(dn, other)?Py_True:Py_False; -} - -static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args) -{ - PyObject *py_other; - struct ldb_dn *other, *dn; - if (!PyArg_ParseTuple(args, "O", &py_other)) - return NULL; - - dn = PyLdbDn_AsDn((PyObject *)self); - - if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other)) - return NULL; - - return ldb_dn_add_base(dn, other)?Py_True:Py_False; -} - -static PyMethodDef py_ldb_dn_methods[] = { - { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, - "S.validate() -> bool\n" - "Validate DN is correct." }, - { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS, - "S.is_valid() -> bool\n" }, - { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS, - "S.is_special() -> bool\n" - "Check whether this is a special LDB DN." }, - { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS, - "Check whether this is a null DN." }, - { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, - NULL }, - { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS, - NULL }, - { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, - "S.canonical_str() -> string\n" - "Canonical version of this DN (like a posix path)." }, - { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, - "S.canonical_ex_str() -> string\n" - "Canonical version of this DN (like a posix path, with terminating newline)." }, - { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS, - "S.extended_str(mode=1) -> string\n" - "Extended version of this DN" }, - { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, - "S.parent() -> dn\n" - "Get the parent for this DN." }, - { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, - "S.add_child(dn) -> None\n" - "Add a child DN to this DN." }, - { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS, - "S.add_base(dn) -> None\n" - "Add a base DN to this DN." }, - { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, - "S.check_special(name) -> bool\n\n" - "Check if name is a special DN name"}, - { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, - "S.get_extended_component(name) -> string\n\n" - "returns a DN extended component as a binary string"}, - { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, - "S.set_extended_component(name, value) -> string\n\n" - "set a DN extended component as a binary string"}, - { NULL } -}; - -static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) -{ - return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self)); -} - -static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other) -{ - struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), - *other; - PyLdbDnObject *py_ret; - - if (!PyObject_AsDn(NULL, py_other, NULL, &other)) - return NULL; - - py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = talloc_new(NULL); - py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); - ldb_dn_add_child(py_ret->dn, other); - return (PyObject *)py_ret; -} - -static PySequenceMethods py_ldb_dn_seq = { - .sq_length = (lenfunc)py_ldb_dn_len, - .sq_concat = (binaryfunc)py_ldb_dn_concat, -}; - -static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - struct ldb_dn *ret; - char *str; - PyObject *py_ldb; - struct ldb_context *ldb_ctx; - TALLOC_CTX *mem_ctx; - PyLdbDnObject *py_ret; - const char * const kwnames[] = { "ldb", "dn", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os", - discard_const_p(char *, kwnames), - &py_ldb, &str)) - return NULL; - - ldb_ctx = PyLdb_AsLdbContext(py_ldb); - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret = ldb_dn_new(mem_ctx, ldb_ctx, str); - if (!ldb_dn_validate(ret)) { - talloc_free(mem_ctx); - PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); - return NULL; - } - - py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0); - if (ret == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = mem_ctx; - py_ret->dn = ret; - return (PyObject *)py_ret; -} - -static void py_ldb_dn_dealloc(PyLdbDnObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbDn = { - .tp_name = "ldb.Dn", - .tp_methods = py_ldb_dn_methods, - .tp_str = (reprfunc)py_ldb_dn_get_linearized, - .tp_repr = (reprfunc)py_ldb_dn_repr, - .tp_compare = (cmpfunc)py_ldb_dn_compare, - .tp_as_sequence = &py_ldb_dn_seq, - .tp_doc = "A LDB distinguished name.", - .tp_new = py_ldb_dn_new, - .tp_dealloc = (destructor)py_ldb_dn_dealloc, - .tp_basicsize = sizeof(PyLdbDnObject), - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -/* Debug */ -static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); -static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) -{ - PyObject *fn = (PyObject *)context; - PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap)); -} - -static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args) -{ - PyObject *cb; - - if (!PyArg_ParseTuple(args, "O", &cb)) - return NULL; - - Py_INCREF(cb); - /* FIXME: Where do we DECREF cb ? */ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self)); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args) -{ - unsigned int perms; - if (!PyArg_ParseTuple(args, "I", &perms)) - return NULL; - - ldb_set_create_perms(PyLdb_AsLdbContext(self), perms); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) -{ - char *modules_dir; - if (!PyArg_ParseTuple(args, "s", &modules_dir)) - return NULL; - - ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_start(PyLdbObject *self) -{ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_commit(PyLdbObject *self) -{ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self) -{ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_cancel(PyLdbObject *self) -{ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self) -{ - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_repr(PyLdbObject *self) -{ - return PyString_FromFormat(""); -} - -static PyObject *py_ldb_get_root_basedn(PyLdbObject *self) -{ - struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return PyLdbDn_FromDn(dn); -} - - -static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) -{ - struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return PyLdbDn_FromDn(dn); -} - -static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) -{ - struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return PyLdbDn_FromDn(dn); -} - -static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) -{ - struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return PyLdbDn_FromDn(dn); -} - -static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, - const char *paramname) -{ - const char **ret; - Py_ssize_t i; - if (!PyList_Check(list)) { - PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); - return NULL; - } - ret = talloc_array(NULL, const char *, PyList_Size(list)+1); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - for (i = 0; i < PyList_Size(list); i++) { - PyObject *item = PyList_GetItem(list, i); - if (!PyString_Check(item)) { - PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); - return NULL; - } - ret[i] = talloc_strndup(ret, PyString_AsString(item), - PyString_Size(item)); - } - ret[i] = NULL; - return ret; -} - -static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "url", "flags", "options", NULL }; - char *url = NULL; - PyObject *py_options = Py_None; - const char **options; - unsigned int flags = 0; - int ret; - struct ldb_context *ldb; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", - discard_const_p(char *, kwnames), - &url, &flags, &py_options)) - return -1; - - ldb = PyLdb_AsLdbContext(self); - - if (py_options == Py_None) { - options = NULL; - } else { - options = PyList_AsStringList(ldb, py_options, "options"); - if (options == NULL) - return -1; - } - - if (url != NULL) { - ret = ldb_connect(ldb, url, flags, options); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb); - return -1; - } - } - - talloc_free(options); - return 0; -} - -static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyLdbObject *ret; - struct ldb_context *ldb; - ret = (PyLdbObject *)type->tp_alloc(type, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ldb = ldb_init(ret->mem_ctx, NULL); - - if (ldb == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret->ldb_ctx = ldb; - return (PyObject *)ret; -} - -static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - char *url; - unsigned int flags = 0; - PyObject *py_options = Py_None; - int ret; - const char **options; - const char * const kwnames[] = { "url", "flags", "options", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO", - discard_const_p(char *, kwnames), - &url, &flags, &py_options)) - return NULL; - - if (py_options == Py_None) { - options = NULL; - } else { - options = PyList_AsStringList(NULL, py_options, "options"); - if (options == NULL) - return NULL; - } - - ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options); - talloc_free(options); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_msg; - PyObject *py_controls = Py_None; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - struct ldb_control **parsed_controls; - struct ldb_message *msg; - int ret; - TALLOC_CTX *mem_ctx; - bool validate=true; - const char * const kwnames[] = { "message", "controls", "validate", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", - discard_const_p(char *, kwnames), - &py_msg, &py_controls, &validate)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = PyLdb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (!PyLdbMessage_Check(py_msg)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); - talloc_free(mem_ctx); - return NULL; - } - msg = PyLdbMessage_AsMessage(py_msg); - - if (validate) { - ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - talloc_free(mem_ctx); - return NULL; - } - } - - ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - if (ldb_ctx->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); - } - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - - -/** - * Obtain a ldb message from a Python Dictionary object. - * - * @param mem_ctx Memory context - * @param py_obj Python Dictionary object - * @param ldb_ctx LDB context - * @param mod_flags Flags to be set on every message element - * @return ldb_message on success or NULL on failure - */ -static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, - PyObject *py_obj, - struct ldb_context *ldb_ctx, - unsigned int mod_flags) -{ - struct ldb_message *msg; - unsigned int msg_pos = 0; - Py_ssize_t dict_pos = 0; - PyObject *key, *value; - struct ldb_message_element *msg_el; - PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); - - msg = ldb_msg_new(mem_ctx); - msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); - - if (dn_value) { - if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { - PyErr_SetString(PyExc_TypeError, "unable to import dn object"); - return NULL; - } - if (msg->dn == NULL) { - PyErr_SetString(PyExc_TypeError, "dn set but not found"); - return NULL; - } - } else { - PyErr_SetString(PyExc_TypeError, "no dn set"); - return NULL; - } - - while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { - char *key_str = PyString_AsString(key); - if (strcmp(key_str, "dn") != 0) { - msg_el = PyObject_AsMessageElement(msg->elements, value, - mod_flags, key_str); - if (msg_el == NULL) { - PyErr_SetString(PyExc_TypeError, "unable to import element"); - return NULL; - } - memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); - msg_pos++; - } - } - - msg->num_elements = msg_pos; - - return msg; -} - -static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_obj; - int ret; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - struct ldb_message *msg = NULL; - PyObject *py_controls = Py_None; - TALLOC_CTX *mem_ctx; - struct ldb_control **parsed_controls; - const char * const kwnames[] = { "message", "controls", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", - discard_const_p(char *, kwnames), - &py_obj, &py_controls)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = PyLdb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (PyLdbMessage_Check(py_obj)) { - msg = PyLdbMessage_AsMessage(py_obj); - } else if (PyDict_Check(py_obj)) { - msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); - } else { - PyErr_SetString(PyExc_TypeError, - "Dictionary or LdbMessage object expected!"); - } - - if (!msg) { - /* we should have a PyErr already set */ - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - if (ldb_ctx->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); - } - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_dn; - struct ldb_dn *dn; - int ret; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - PyObject *py_controls = Py_None; - TALLOC_CTX *mem_ctx; - struct ldb_control **parsed_controls; - const char * const kwnames[] = { "dn", "controls", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", - discard_const_p(char *, kwnames), - &py_dn, &py_controls)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = PyLdb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - if (ldb_ctx->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); - } - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_dn1, *py_dn2; - struct ldb_dn *dn1, *dn2; - int ret; - struct ldb_context *ldb; - TALLOC_CTX *mem_ctx; - PyObject *py_controls = Py_None; - struct ldb_control **parsed_controls; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; - - ldb_ctx = PyLdb_AsLdbContext(self); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", - discard_const_p(char *, kwnames), - &py_dn1, &py_dn2, &py_controls)) - return NULL; - - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb = PyLdb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - - if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) { - talloc_free(mem_ctx); - return NULL; - } - - if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) { - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - if (ldb_ctx->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); - } - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args) -{ - char *attribute, *syntax; - unsigned int flags; - int ret; - if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax)) - return NULL; - - ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); - - Py_RETURN_NONE; -} - -static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) -{ - if (ldif == NULL) { - Py_RETURN_NONE; - } else { - /* We don't want this attached to the 'ldb' any more */ - return Py_BuildValue(discard_const_p(char, "(iO)"), - ldif->changetype, - PyLdbMessage_FromMessage(ldif->msg)); - } -} - - -static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) -{ - int changetype; - PyObject *py_msg; - struct ldb_ldif ldif; - PyObject *ret; - char *string; - TALLOC_CTX *mem_ctx; - - if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) - return NULL; - - if (!PyLdbMessage_Check(py_msg)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); - return NULL; - } - - ldif.msg = PyLdbMessage_AsMessage(py_msg); - ldif.changetype = changetype; - - mem_ctx = talloc_new(NULL); - - string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif); - if (!string) { - PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); - return NULL; - } - - ret = PyString_FromString(string); - - talloc_free(mem_ctx); - - return ret; -} - -static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) -{ - PyObject *list; - struct ldb_ldif *ldif; - const char *s; - - TALLOC_CTX *mem_ctx; - - if (!PyArg_ParseTuple(args, "s", &s)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (!mem_ctx) { - Py_RETURN_NONE; - } - - list = PyList_New(0); - while (s && *s != '\0') { - ldif = ldb_ldif_read_string(self->ldb_ctx, &s); - talloc_steal(mem_ctx, ldif); - if (ldif) { - PyList_Append(list, ldb_ldif_to_pyobject(ldif)); - } else { - PyErr_SetString(PyExc_ValueError, "unable to parse ldif string"); - talloc_free(mem_ctx); - return NULL; - } - } - talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */ - return PyObject_GetIter(list); -} - -static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) -{ - int ldb_ret; - PyObject *py_msg_old; - PyObject *py_msg_new; - struct ldb_message *diff; - struct ldb_context *ldb; - PyObject *py_ret; - - if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) - return NULL; - - if (!PyLdbMessage_Check(py_msg_old)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message"); - return NULL; - } - - if (!PyLdbMessage_Check(py_msg_new)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message"); - return NULL; - } - - ldb = PyLdb_AsLdbContext(self); - ldb_ret = ldb_msg_difference(ldb, ldb, - PyLdbMessage_AsMessage(py_msg_old), - PyLdbMessage_AsMessage(py_msg_new), - &diff); - if (ldb_ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); - return NULL; - } - - py_ret = PyLdbMessage_FromMessage(diff); - - talloc_unlink(ldb, diff); - - return py_ret; -} - -static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args) -{ - const struct ldb_schema_attribute *a; - struct ldb_val old_val; - struct ldb_val new_val; - TALLOC_CTX *mem_ctx; - PyObject *ret; - char *element_name; - PyObject *val; - - if (!PyArg_ParseTuple(args, "sO", &element_name, &val)) - return NULL; - - mem_ctx = talloc_new(NULL); - - old_val.data = (uint8_t *)PyString_AsString(val); - old_val.length = PyString_Size(val); - - a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name); - - if (a == NULL) { - Py_RETURN_NONE; - } - - if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) { - talloc_free(mem_ctx); - Py_RETURN_NONE; - } - - ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); - - talloc_free(mem_ctx); - - return ret; -} - -static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_base = Py_None; - int scope = LDB_SCOPE_DEFAULT; - char *expr = NULL; - PyObject *py_attrs = Py_None; - PyObject *py_controls = Py_None; - const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL }; - int ret; - struct ldb_result *res; - struct ldb_request *req; - const char **attrs; - struct ldb_context *ldb_ctx; - struct ldb_control **parsed_controls; - struct ldb_dn *base; - PyObject *py_ret; - TALLOC_CTX *mem_ctx; - - /* type "int" rather than "enum" for "scope" is intentional */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", - discard_const_p(char *, kwnames), - &py_base, &scope, &expr, &py_attrs, &py_controls)) - return NULL; - - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = PyLdb_AsLdbContext(self); - - if (py_attrs == Py_None) { - attrs = NULL; - } else { - attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs"); - if (attrs == NULL) { - talloc_free(mem_ctx); - return NULL; - } - } - - if (py_base == Py_None) { - base = ldb_get_default_basedn(ldb_ctx); - } else { - if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) { - talloc_free(attrs); - return NULL; - } - } - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - res = talloc_zero(mem_ctx, struct ldb_result); - if (res == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, - base, - scope, - expr, - attrs, - parsed_controls, - res, - ldb_search_default_callback, - NULL); - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - talloc_steal(req, attrs); - - ret = ldb_request(ldb_ctx, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - py_ret = PyLdbResult_FromResult(res); - - talloc_free(mem_ctx); - - return py_ret; -} - -static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) -{ - char *name; - void *data; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - data = ldb_get_opaque(PyLdb_AsLdbContext(self), name); - - if (data == NULL) - Py_RETURN_NONE; - - /* FIXME: More interpretation */ - - return Py_True; -} - -static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) -{ - char *name; - PyObject *data; - - if (!PyArg_ParseTuple(args, "sO", &name, &data)) - return NULL; - - /* FIXME: More interpretation */ - - ldb_set_opaque(PyLdb_AsLdbContext(self), name, data); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_modules(PyLdbObject *self) -{ - struct ldb_context *ldb = PyLdb_AsLdbContext(self); - PyObject *ret = PyList_New(0); - struct ldb_module *mod; - - for (mod = ldb->modules; mod; mod = mod->next) { - PyList_Append(ret, PyLdbModule_FromModule(mod)); - } - - return ret; -} - -static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) -{ - struct ldb_context *ldb = PyLdb_AsLdbContext(self); - int type, ret; - uint64_t value; - - if (!PyArg_ParseTuple(args, "i", &type)) - return NULL; - - /* FIXME: More interpretation */ - - ret = ldb_sequence_number(ldb, type, &value); - - if (ret != LDB_SUCCESS) { - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); - return NULL; - } - return PyLong_FromLongLong(value); -} -static PyMethodDef py_ldb_methods[] = { - { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, - "S.set_debug(callback) -> None\n" - "Set callback for LDB debug messages.\n" - "The callback should accept a debug level and debug text." }, - { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, - "S.set_create_perms(mode) -> None\n" - "Set mode to use when creating new LDB files." }, - { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS, - "S.set_modules_dir(path) -> None\n" - "Set path LDB should search for modules" }, - { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, - "S.transaction_start() -> None\n" - "Start a new transaction." }, - { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, - "S.transaction_prepare_commit() -> None\n" - "prepare to commit a new transaction (2-stage commit)." }, - { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, - "S.transaction_commit() -> None\n" - "commit a new transaction." }, - { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, - "S.transaction_cancel() -> None\n" - "cancel a new transaction." }, - { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, - NULL }, - { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS, - NULL }, - { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS, - NULL }, - { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS, - NULL }, - { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, - NULL }, - { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, - "S.connect(url, flags=0, options=None) -> None\n" - "Connect to a LDB URL." }, - { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS, - "S.modify(message, controls=None, validate=False) -> None\n" - "Modify an entry." }, - { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS, - "S.add(message, controls=None) -> None\n" - "Add an entry." }, - { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS, - "S.delete(dn, controls=None) -> None\n" - "Remove an entry." }, - { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS, - "S.rename(old_dn, new_dn, controls=None) -> None\n" - "Rename an entry." }, - { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS, - "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n" - "Search in a database.\n" - "\n" - ":param base: Optional base DN to search\n" - ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" - ":param expression: Optional search expression\n" - ":param attrs: Attributes to return (defaults to all)\n" - ":param controls: Optional list of controls\n" - ":return: Iterator over Message objects\n" - }, - { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, - NULL }, - { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, - NULL }, - { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS, - NULL }, - { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, - "S.parse_ldif(ldif) -> iter(messages)\n" - "Parse a string formatted using LDIF." }, - { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, - "S.write_ldif(message, changetype) -> ldif\n" - "Print the message as a string formatted using LDIF." }, - { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, - "S.msg_diff(Message) -> Message\n" - "Return an LDB Message of the difference between two Message objects." }, - { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS, - "S.get_opaque(name) -> value\n" - "Get an opaque value set on this LDB connection. \n" - ":note: The returned value may not be useful in Python." - }, - { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS, - "S.set_opaque(name, value) -> None\n" - "Set an opaque value on this LDB connection. \n" - ":note: Passing incorrect values may cause crashes." }, - { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS, - "S.modules() -> list\n" - "Return the list of modules on this LDB connection " }, - { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, - "S.sequence_number(type) -> value\n" - "Return the value of the sequence according to the requested type" }, - { NULL }, -}; - -static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) -{ - PyLdbModuleObject *ret; - - ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->mod = talloc_reference(ret->mem_ctx, mod); - return (PyObject *)ret; -} - -static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure) -{ - return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules); -} - -static PyGetSetDef py_ldb_getset[] = { - { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL }, - { NULL } -}; - -static int py_ldb_contains(PyLdbObject *self, PyObject *obj) -{ - struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self); - struct ldb_dn *dn; - struct ldb_result *result; - unsigned int count; - int ret; - - if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { - return -1; - } - - ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, - NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return -1; - } - - count = result->count; - - talloc_free(result); - - if (count > 1) { - PyErr_Format(PyExc_RuntimeError, - "Searching for [%s] dn gave %u results!", - ldb_dn_get_linearized(dn), - count); - return -1; - } - - return count; -} - -static PySequenceMethods py_ldb_seq = { - .sq_contains = (objobjproc)py_ldb_contains, -}; - -static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) -{ - PyLdbObject *ret; - - ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx); - return (PyObject *)ret; -} - -static void py_ldb_dealloc(PyLdbObject *self) -{ - talloc_free(self->mem_ctx); - self->ob_type->tp_free(self); -} - -static PyTypeObject PyLdb = { - .tp_name = "ldb.Ldb", - .tp_methods = py_ldb_methods, - .tp_repr = (reprfunc)py_ldb_repr, - .tp_new = py_ldb_new, - .tp_init = (initproc)py_ldb_init, - .tp_dealloc = (destructor)py_ldb_dealloc, - .tp_getset = py_ldb_getset, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbObject), - .tp_doc = "Connection to a LDB database.", - .tp_as_sequence = &py_ldb_seq, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static void py_ldb_result_dealloc(PyLdbResultObject *self) -{ - talloc_free(self->mem_ctx); - Py_DECREF(self->msgs); - Py_DECREF(self->referals); - Py_DECREF(self->controls); - self->ob_type->tp_free(self); -} - -static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->msgs); - return self->msgs; -} - -static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->controls); - return self->controls; -} - -static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->referals); - return self->referals; -} - -static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) -{ - Py_ssize_t size; - if (self->msgs == NULL) { - PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); - return NULL; - } - size = PyList_Size(self->msgs); - return PyInt_FromLong(size); -} - -static PyGetSetDef py_ldb_result_getset[] = { - { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL }, - { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL }, - { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL }, - { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL }, - { NULL } -}; - -static PyObject *py_ldb_result_iter(PyLdbResultObject *self) -{ - return PyObject_GetIter(self->msgs); -} - -static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) -{ - return PySequence_Size(self->msgs); -} - -static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) -{ - return PySequence_GetItem(self->msgs, idx); -} - -static PySequenceMethods py_ldb_result_seq = { - .sq_length = (lenfunc)py_ldb_result_len, - .sq_item = (ssizeargfunc)py_ldb_result_find, -}; - -static PyObject *py_ldb_result_repr(PyLdbObject *self) -{ - return PyString_FromFormat(""); -} - - -static PyTypeObject PyLdbResult = { - .tp_name = "ldb.Result", - .tp_repr = (reprfunc)py_ldb_result_repr, - .tp_dealloc = (destructor)py_ldb_result_dealloc, - .tp_iter = (getiterfunc)py_ldb_result_iter, - .tp_getset = py_ldb_result_getset, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbResultObject), - .tp_as_sequence = &py_ldb_result_seq, - .tp_doc = "LDB result.", - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) -{ - return PyString_FromFormat("", PyLdbModule_AsModule(self)->ops->name); -} - -static PyObject *py_ldb_module_str(PyLdbModuleObject *self) -{ - return PyString_FromString(PyLdbModule_AsModule(self)->ops->name); -} - -static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self) -{ - PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self) -{ - PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self) -{ - PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_base, *py_tree, *py_attrs, *py_ret; - int ret, scope; - struct ldb_request *req; - const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL }; - struct ldb_module *mod; - const char * const*attrs; - - /* type "int" rather than "enum" for "scope" is intentional */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO", - discard_const_p(char *, kwnames), - &py_base, &scope, &py_tree, &py_attrs)) - return NULL; - - mod = self->mod; - - if (py_attrs == Py_None) { - attrs = NULL; - } else { - attrs = PyList_AsStringList(NULL, py_attrs, "attrs"); - if (attrs == NULL) - return NULL; - } - - ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), - scope, NULL /* expr */, attrs, - NULL /* controls */, NULL, NULL, NULL); - - talloc_steal(req, attrs); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - req->op.search.res = NULL; - - ret = mod->ops->search(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - py_ret = PyLdbResult_FromResult(req->op.search.res); - - talloc_free(req); - - return py_ret; -} - - -static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args) -{ - struct ldb_request *req; - PyObject *py_message; - int ret; - struct ldb_module *mod; - - if (!PyArg_ParseTuple(args, "O", &py_message)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_ADD; - req->op.add.message = PyLdbMessage_AsMessage(py_message); - - mod = PyLdbModule_AsModule(self); - ret = mod->ops->add(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_message; - struct ldb_module *mod; - - if (!PyArg_ParseTuple(args, "O", &py_message)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_MODIFY; - req->op.mod.message = PyLdbMessage_AsMessage(py_message); - - mod = PyLdbModule_AsModule(self); - ret = mod->ops->modify(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_dn; - - if (!PyArg_ParseTuple(args, "O", &py_dn)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_DELETE; - req->op.del.dn = PyLdbDn_AsDn(py_dn); - - ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_dn1, *py_dn2; - - if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - - req->operation = LDB_RENAME; - req->op.rename.olddn = PyLdbDn_AsDn(py_dn1); - req->op.rename.newdn = PyLdbDn_AsDn(py_dn2); - - ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_module_methods[] = { - { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL }, - { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, - { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, - { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, - { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL }, - { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, - { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, - { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, - { NULL }, -}; - -static void py_ldb_module_dealloc(PyLdbModuleObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbModule = { - .tp_name = "ldb.LdbModule", - .tp_methods = py_ldb_module_methods, - .tp_repr = (reprfunc)py_ldb_module_repr, - .tp_str = (reprfunc)py_ldb_module_str, - .tp_basicsize = sizeof(PyLdbModuleObject), - .tp_dealloc = (destructor)py_ldb_module_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - - -/** - * Create a ldb_message_element from a Python object. - * - * This will accept any sequence objects that contains strings, or - * a string object. - * - * A reference to set_obj will be borrowed. - * - * @param mem_ctx Memory context - * @param set_obj Python object to convert - * @param flags ldb_message_element flags to set - * @param attr_name Name of the attribute - * @return New ldb_message_element, allocated as child of mem_ctx - */ -static struct ldb_message_element *PyObject_AsMessageElement( - TALLOC_CTX *mem_ctx, - PyObject *set_obj, - unsigned int flags, - const char *attr_name) -{ - struct ldb_message_element *me; - - if (PyLdbMessageElement_Check(set_obj)) { - PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; - /* We have to talloc_reference() the memory context, not the pointer - * which may not actually be it's own context */ - if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { - return PyLdbMessageElement_AsMessageElement(set_obj); - } - return NULL; - } - - me = talloc(mem_ctx, struct ldb_message_element); - if (me == NULL) { - PyErr_NoMemory(); - return NULL; - } - - me->name = talloc_strdup(me, attr_name); - me->flags = flags; - if (PyString_Check(set_obj)) { - me->num_values = 1; - me->values = talloc_array(me, struct ldb_val, me->num_values); - me->values[0].length = PyString_Size(set_obj); - me->values[0].data = talloc_memdup(me, - (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1); - } else if (PySequence_Check(set_obj)) { - Py_ssize_t i; - me->num_values = PySequence_Size(set_obj); - me->values = talloc_array(me, struct ldb_val, me->num_values); - for (i = 0; i < me->num_values; i++) { - PyObject *obj = PySequence_GetItem(set_obj, i); - if (!PyString_Check(obj)) { - PyErr_Format(PyExc_TypeError, - "Expected string as element %zd in list", i); - talloc_free(me); - return NULL; - } - - me->values[i].length = PyString_Size(obj); - me->values[i].data = talloc_memdup(me, - (uint8_t *)PyString_AsString(obj), me->values[i].length+1); - } - } else { - talloc_free(me); - me = NULL; - } - - return me; -} - - -static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, - struct ldb_message_element *me) -{ - Py_ssize_t i; - PyObject *result; - - /* Python << 2.5 doesn't have PySet_New and PySet_Add. */ - result = PyList_New(me->num_values); - - for (i = 0; i < me->num_values; i++) { - PyList_SetItem(result, i, - PyObject_FromLdbValue(&me->values[i])); - } - - return result; -} - -static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) -{ - unsigned int i; - if (!PyArg_ParseTuple(args, "I", &i)) - return NULL; - if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values) - Py_RETURN_NONE; - - return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i])); -} - -static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) -{ - struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); - return PyInt_FromLong(el->flags); -} - -static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) -{ - unsigned int flags; - struct ldb_message_element *el; - if (!PyArg_ParseTuple(args, "I", &flags)) - return NULL; - - el = PyLdbMessageElement_AsMessageElement(self); - el->flags = flags; - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_msg_element_methods[] = { - { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, - { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, - { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, - { NULL }, -}; - -static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) -{ - return PyLdbMessageElement_AsMessageElement(self)->num_values; -} - -static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx) -{ - struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); - if (idx < 0 || idx >= el->num_values) { - PyErr_SetString(PyExc_IndexError, "Out of range"); - return NULL; - } - return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); -} - -static PySequenceMethods py_ldb_msg_element_seq = { - .sq_length = (lenfunc)py_ldb_msg_element_len, - .sq_item = (ssizeargfunc)py_ldb_msg_element_find, -}; - -static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other) -{ - int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), - PyLdbMessageElement_AsMessageElement(other)); - return SIGN(ret); -} - -static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self) -{ - return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self))); -} - -static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) -{ - PyLdbMessageElementObject *ret; - ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->el = el; - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *py_elements = NULL; - struct ldb_message_element *el; - unsigned int flags = 0; - char *name = NULL; - const char * const kwnames[] = { "elements", "flags", "name", NULL }; - PyLdbMessageElementObject *ret; - TALLOC_CTX *mem_ctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", - discard_const_p(char *, kwnames), - &py_elements, &flags, &name)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - if (py_elements != NULL) { - Py_ssize_t i; - if (PyString_Check(py_elements)) { - el->num_values = 1; - el->values = talloc_array(el, struct ldb_val, 1); - if (el->values == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - el->values[0].length = PyString_Size(py_elements); - el->values[0].data = talloc_memdup(el->values, - (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1); - } else if (PySequence_Check(py_elements)) { - el->num_values = PySequence_Size(py_elements); - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - for (i = 0; i < el->num_values; i++) { - PyObject *item = PySequence_GetItem(py_elements, i); - if (item == NULL) { - talloc_free(mem_ctx); - return NULL; - } - if (!PyString_Check(item)) { - PyErr_Format(PyExc_TypeError, - "Expected string as element %zd in list", i); - talloc_free(mem_ctx); - return NULL; - } - el->values[i].length = PyString_Size(item); - el->values[i].data = talloc_memdup(el, - (uint8_t *)PyString_AsString(item), el->values[i].length+1); - } - } else { - PyErr_SetString(PyExc_TypeError, - "Expected string or list"); - talloc_free(mem_ctx); - return NULL; - } - } - - el->flags = flags; - el->name = talloc_strdup(el, name); - - ret = PyObject_New(PyLdbMessageElementObject, type); - if (ret == NULL) { - talloc_free(mem_ctx); - return NULL; - } - - ret->mem_ctx = mem_ctx; - ret->el = el; - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self) -{ - char *element_str = NULL; - Py_ssize_t i; - struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); - PyObject *ret; - - for (i = 0; i < el->num_values; i++) { - PyObject *o = py_ldb_msg_element_find(self, i); - if (element_str == NULL) - element_str = talloc_strdup(NULL, PyObject_REPR(o)); - else - element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o)); - } - - if (element_str != NULL) { - ret = PyString_FromFormat("MessageElement([%s])", element_str); - talloc_free(element_str); - } else { - ret = PyString_FromString("MessageElement([])"); - } - - return ret; -} - -static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) -{ - struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); - - if (el->num_values == 1) - return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length); - else - Py_RETURN_NONE; -} - -static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbMessageElement = { - .tp_name = "ldb.MessageElement", - .tp_basicsize = sizeof(PyLdbMessageElementObject), - .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, - .tp_repr = (reprfunc)py_ldb_msg_element_repr, - .tp_str = (reprfunc)py_ldb_msg_element_str, - .tp_methods = py_ldb_msg_element_methods, - .tp_compare = (cmpfunc)py_ldb_msg_element_cmp, - .tp_iter = (getiterfunc)py_ldb_msg_element_iter, - .tp_as_sequence = &py_ldb_msg_element_seq, - .tp_new = py_ldb_msg_element_new, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - - -static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) -{ - PyObject *py_ldb; - PyObject *py_dict; - PyObject *py_ret; - struct ldb_message *msg; - struct ldb_context *ldb_ctx; - unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; - - if (!PyArg_ParseTuple(args, "O!O!|I", - &PyLdb, &py_ldb, &PyDict_Type, &py_dict, - &mod_flags)) { - return NULL; - } - - /* mask only flags we are going to use */ - mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); - if (!mod_flags) { - PyErr_SetString(PyExc_ValueError, - "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" - " expected as mod_flag value"); - return NULL; - } - - ldb_ctx = PyLdb_AsLdbContext(py_ldb); - - msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); - if (!msg) { - return NULL; - } - - py_ret = PyLdbMessage_FromMessage(msg); - - talloc_unlink(ldb_ctx, msg); - - return py_ret; -} - -static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - ldb_msg_remove_attr(self->msg, name); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - Py_ssize_t i, j = 0; - PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); - if (msg->dn != NULL) { - PyList_SetItem(obj, j, PyString_FromString("dn")); - j++; - } - for (i = 0; i < msg->num_elements; i++) { - PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name)); - j++; - } - return obj; -} - -static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) -{ - struct ldb_message_element *el; - char *name; - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - if (!PyString_Check(py_name)) { - PyErr_SetNone(PyExc_TypeError); - return NULL; - } - name = PyString_AsString(py_name); - if (!strcmp(name, "dn")) - return PyLdbDn_FromDn(msg->dn); - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return NULL; - } - return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); -} - -static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) -{ - PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); - if (ret == NULL) { - PyErr_SetString(PyExc_KeyError, "No such element"); - return NULL; - } - return ret; -} - -static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args) -{ - PyObject *name, *ret, *retobj; - retobj = NULL; - if (!PyArg_ParseTuple(args, "O|O", &name, &retobj)) - return NULL; - - ret = py_ldb_msg_getitem_helper(self, name); - if (ret == NULL) { - if (PyErr_Occurred()) - return NULL; - if (retobj != NULL) { - return retobj; - } else { - Py_RETURN_NONE; - } - } - return ret; -} - -static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - Py_ssize_t i, j = 0; - PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); - if (msg->dn != NULL) { - PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn))); - j++; - } - for (i = 0; i < msg->num_elements; i++, j++) { - PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); - PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); - PyList_SetItem(l, j, value); - } - return l; -} - -static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - Py_ssize_t i = 0; - PyObject *l = PyList_New(msg->num_elements); - for (i = 0; i < msg->num_elements; i++) { - PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); - } - return l; -} - -static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - PyLdbMessageElementObject *py_element; - int ret; - struct ldb_message_element *el; - - if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) - return NULL; - - el = talloc_reference(msg, py_element->el); - if (el == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret = ldb_msg_add(msg, el, el->flags); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_msg_methods[] = { - { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, - "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" - "Class method to create ldb.Message object from Dictionary.\n" - "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, - { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, - "S.keys() -> list\n\n" - "Return sequence of all attribute names." }, - { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, - "S.remove(name)\n\n" - "Remove all entries for attributes with the specified name."}, - { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL }, - { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, - { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, - { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, - "S.append(element)\n\n" - "Add an element to this message." }, - { NULL }, -}; - -static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) -{ - PyObject *list, *iter; - - list = py_ldb_msg_keys(self); - iter = PyObject_GetIter(list); - Py_DECREF(list); - return iter; -} - -static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value) -{ - char *attr_name; - - if (!PyString_Check(name)) { - PyErr_SetNone(PyExc_TypeError); - return -1; - } - - attr_name = PyString_AsString(name); - if (value == NULL) { - /* delitem */ - ldb_msg_remove_attr(self->msg, attr_name); - } else { - struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, - value, 0, attr_name); - if (el == NULL) - return -1; - ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name); - ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags); - } - return 0; -} - -static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) -{ - return PyLdbMessage_AsMessage(self)->num_elements; -} - -static PyMappingMethods py_ldb_msg_mapping = { - .mp_length = (lenfunc)py_ldb_msg_length, - .mp_subscript = (binaryfunc)py_ldb_msg_getitem, - .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem, -}; - -static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "dn", NULL }; - struct ldb_message *ret; - TALLOC_CTX *mem_ctx; - PyObject *pydn = NULL; - PyLdbMessageObject *py_ret; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", - discard_const_p(char *, kwnames), - &pydn)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret = ldb_msg_new(mem_ctx); - if (ret == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - - if (pydn != NULL) { - struct ldb_dn *dn; - if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) { - talloc_free(mem_ctx); - return NULL; - } - ret->dn = talloc_reference(ret, dn); - } - - py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - py_ret->mem_ctx = mem_ctx; - py_ret->msg = ret; - return (PyObject *)py_ret; -} - -static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) -{ - PyLdbMessageObject *ret; - - ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->msg = talloc_reference(ret->mem_ctx, msg); - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - return PyLdbDn_FromDn(msg->dn); -} - -static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) -{ - struct ldb_message *msg = PyLdbMessage_AsMessage(self); - if (!PyLdbDn_Check(value)) { - PyErr_SetNone(PyExc_TypeError); - return -1; - } - - msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value)); - return 0; -} - -static PyGetSetDef py_ldb_msg_getset[] = { - { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL }, - { NULL } -}; - -static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self) -{ - PyObject *dict = PyDict_New(), *ret; - if (PyDict_Update(dict, (PyObject *)self) != 0) - return NULL; - ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict)); - Py_DECREF(dict); - return ret; -} - -static void py_ldb_msg_dealloc(PyLdbMessageObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1, - PyLdbMessageObject *py_msg2) -{ - struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1), - *msg2 = PyLdbMessage_AsMessage(py_msg2); - unsigned int i; - int ret; - - if ((msg1->dn != NULL) || (msg2->dn != NULL)) { - ret = ldb_dn_compare(msg1->dn, msg2->dn); - if (ret != 0) { - return SIGN(ret); - } - } - - ret = msg1->num_elements - msg2->num_elements; - if (ret != 0) { - return SIGN(ret); - } - - for (i = 0; i < msg1->num_elements; i++) { - ret = ldb_msg_element_compare_name(&msg1->elements[i], - &msg2->elements[i]); - if (ret != 0) { - return SIGN(ret); - } - - ret = ldb_msg_element_compare(&msg1->elements[i], - &msg2->elements[i]); - if (ret != 0) { - return SIGN(ret); - } - } - - return 0; -} - -static PyTypeObject PyLdbMessage = { - .tp_name = "ldb.Message", - .tp_methods = py_ldb_msg_methods, - .tp_getset = py_ldb_msg_getset, - .tp_as_mapping = &py_ldb_msg_mapping, - .tp_basicsize = sizeof(PyLdbMessageObject), - .tp_dealloc = (destructor)py_ldb_msg_dealloc, - .tp_new = py_ldb_msg_new, - .tp_repr = (reprfunc)py_ldb_msg_repr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_iter = (getiterfunc)py_ldb_msg_iter, - .tp_compare = (cmpfunc)py_ldb_msg_compare, -}; - -static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) -{ - PyLdbTreeObject *ret; - - ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret->mem_ctx = talloc_new(NULL); - ret->tree = talloc_reference(ret->mem_ctx, tree); - return (PyObject *)ret; -} - -static void py_ldb_tree_dealloc(PyLdbTreeObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbTree = { - .tp_name = "ldb.Tree", - .tp_basicsize = sizeof(PyLdbTreeObject), - .tp_dealloc = (destructor)py_ldb_tree_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -/* Ldb_module */ -static int py_module_search(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_base, *py_attrs, *py_tree; - - py_base = PyLdbDn_FromDn(req->op.search.base); - - if (py_base == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_tree = PyLdbTree_FromTree(req->op.search.tree); - - if (py_tree == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - if (req->op.search.attrs == NULL) { - py_attrs = Py_None; - } else { - int i, len; - for (len = 0; req->op.search.attrs[len]; len++); - py_attrs = PyList_New(len); - for (i = 0; i < len; i++) - PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i])); - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"), - discard_const_p(char, "OiOO"), - py_base, req->op.search.scope, py_tree, py_attrs); - - Py_DECREF(py_attrs); - Py_DECREF(py_tree); - Py_DECREF(py_base); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - req->op.search.res = PyLdbResult_AsResult(NULL, py_result); - if (req->op.search.res == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_add(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_msg; - - py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message)); - - if (py_msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"), - discard_const_p(char, "O"), - py_msg); - - Py_DECREF(py_msg); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_modify(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_msg; - - py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message)); - - if (py_msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"), - discard_const_p(char, "O"), - py_msg); - - Py_DECREF(py_msg); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_del(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_dn; - - py_dn = PyLdbDn_FromDn(req->op.del.dn); - - if (py_dn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"), - discard_const_p(char, "O"), - py_dn); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_rename(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_olddn, *py_newdn; - - py_olddn = PyLdbDn_FromDn(req->op.rename.olddn); - - if (py_olddn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_newdn = PyLdbDn_FromDn(req->op.rename.newdn); - - if (py_newdn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"), - discard_const_p(char, "OO"), - py_olddn, py_newdn); - - Py_DECREF(py_olddn); - Py_DECREF(py_newdn); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_request(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"), - discard_const_p(char, "")); - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int py_module_extended(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"), - discard_const_p(char, "")); - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int py_module_start_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_end_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_del_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_destructor(struct ldb_module *mod) -{ - Py_DECREF((PyObject *)mod->private_data); - return 0; -} - -static int py_module_init(struct ldb_module *mod) -{ - PyObject *py_class = (PyObject *)mod->ops->private_data; - PyObject *py_result, *py_next, *py_ldb; - - py_ldb = PyLdb_FromLdbContext(mod->ldb); - - if (py_ldb == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_next = PyLdbModule_FromModule(mod->next); - - if (py_next == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"), - py_ldb, py_next); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - mod->private_data = py_result; - - talloc_set_destructor(mod, py_module_destructor); - - return ldb_next_init(mod); -} - -static PyObject *py_register_module(PyObject *module, PyObject *args) -{ - int ret; - struct ldb_module_ops *ops; - PyObject *input; - - if (!PyArg_ParseTuple(args, "O", &input)) - return NULL; - - ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops); - if (ops == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name")))); - - Py_INCREF(input); - ops->private_data = input; - ops->init_context = py_module_init; - ops->search = py_module_search; - ops->add = py_module_add; - ops->modify = py_module_modify; - ops->del = py_module_del; - ops->rename = py_module_rename; - ops->request = py_module_request; - ops->extended = py_module_extended; - ops->start_transaction = py_module_start_transaction; - ops->end_transaction = py_module_end_transaction; - ops->del_transaction = py_module_del_transaction; - - ret = ldb_register_module(ops); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyObject *py_timestring(PyObject *module, PyObject *args) -{ - /* most times "time_t" is a signed integer type with 32 or 64 bit: - * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ - long int t_val; - char *tresult; - PyObject *ret; - if (!PyArg_ParseTuple(args, "l", &t_val)) - return NULL; - tresult = ldb_timestring(NULL, (time_t) t_val); - ret = PyString_FromString(tresult); - talloc_free(tresult); - return ret; -} - -static PyObject *py_string_to_time(PyObject *module, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "s", &str)) - return NULL; - - return PyInt_FromLong(ldb_string_to_time(str)); -} - -static PyObject *py_valid_attr_name(PyObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - return PyBool_FromLong(ldb_valid_attr_name(name)); -} - -static PyMethodDef py_ldb_global_methods[] = { - { "register_module", py_register_module, METH_VARARGS, - "S.register_module(module) -> None\n" - "Register a LDB module."}, - { "timestring", py_timestring, METH_VARARGS, - "S.timestring(int) -> string\n" - "Generate a LDAP time string from a UNIX timestamp" }, - { "string_to_time", py_string_to_time, METH_VARARGS, - "S.string_to_time(string) -> int\n" - "Parse a LDAP time string into a UNIX timestamp." }, - { "valid_attr_name", py_valid_attr_name, METH_VARARGS, - "S.valid_attr_name(name) -> bool\n" - "Check whether the supplied name is a valid attribute name." }, - { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS, - NULL }, - { NULL } -}; - -void initldb(void) -{ - PyObject *m; - - if (PyType_Ready(&PyLdbDn) < 0) - return; - - if (PyType_Ready(&PyLdbMessage) < 0) - return; - - if (PyType_Ready(&PyLdbMessageElement) < 0) - return; - - if (PyType_Ready(&PyLdb) < 0) - return; - - if (PyType_Ready(&PyLdbModule) < 0) - return; - - if (PyType_Ready(&PyLdbTree) < 0) - return; - - if (PyType_Ready(&PyLdbResult) < 0) - return; - - if (PyType_Ready(&PyLdbControl) < 0) - return; - - m = Py_InitModule3("ldb", py_ldb_global_methods, - "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."); - if (m == NULL) - return; - - PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ)); - PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP)); - PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT)); - PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT)); - PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE)); - PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL)); - PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE)); - - PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE)); - PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD)); - PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE)); - PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY)); - - PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD)); - PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE)); - PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE)); - - PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS)); - PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR)); - PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR)); - PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED)); - PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED)); - PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE)); - PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE)); - PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED)); - PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED)); - PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL)); - PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED)); - PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION)); - PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED)); - PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS)); - PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE)); - PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE)); - PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING)); - PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION)); - PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)); - PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX)); - PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT)); - PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM)); - PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX)); - PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM)); - PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION)); - PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS)); - PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS)); - PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY)); - PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE)); - PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM)); - PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT)); - PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION)); - PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION)); - PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF)); - PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN)); - PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS)); - PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED)); - PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); - PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER)); - - PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY)); - PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC)); - PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT)); - PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP)); - - PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText")); - - PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL); - PyModule_AddObject(m, "LdbError", PyExc_LdbError); - - Py_INCREF(&PyLdb); - Py_INCREF(&PyLdbDn); - Py_INCREF(&PyLdbModule); - Py_INCREF(&PyLdbMessage); - Py_INCREF(&PyLdbMessageElement); - Py_INCREF(&PyLdbTree); - Py_INCREF(&PyLdbResult); - Py_INCREF(&PyLdbControl); - - PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); - PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn); - PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage); - PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement); - PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); - PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); - PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); - - PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION)); - -#define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(val)) - - ADD_LDB_STRING(LDB_SYNTAX_DN); - ADD_LDB_STRING(LDB_SYNTAX_DN); - ADD_LDB_STRING(LDB_SYNTAX_DIRECTORY_STRING); - ADD_LDB_STRING(LDB_SYNTAX_INTEGER); - ADD_LDB_STRING(LDB_SYNTAX_BOOLEAN); - ADD_LDB_STRING(LDB_SYNTAX_OCTET_STRING); - ADD_LDB_STRING(LDB_SYNTAX_UTC_TIME); -} diff --git a/source4/lib/ldb/pyldb.h b/source4/lib/ldb/pyldb.h deleted file mode 100644 index 04d8ff856c1..00000000000 --- a/source4/lib/ldb/pyldb.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb. - - Copyright (C) 2007-2008 Jelmer Vernooij - - ** 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 . -*/ - -#ifndef _PYLDB_H_ -#define _PYLDB_H_ - -#include - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_context *ldb_ctx; -} PyLdbObject; - -#define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx -#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_dn *dn; -} PyLdbDnObject; - -PyObject *PyLdbDn_FromDn(struct ldb_dn *); -bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn); -#define PyLdbDn_AsDn(pyobj) ((PyLdbDnObject *)pyobj)->dn -#define PyLdbDn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn) - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_message *msg; -} PyLdbMessageObject; -#define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) -#define PyLdbMessage_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_module *mod; -} PyLdbModuleObject; -#define PyLdbModule_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_message_element *el; -} PyLdbMessageElementObject; -#define PyLdbMessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el -#define PyLdbMessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_parse_tree *tree; -} PyLdbTreeObject; -#define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - PyObject *msgs; - PyObject *referals; - PyObject *controls; -} PyLdbResultObject; - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_control *data; -} PyLdbControlObject; - -#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \ - if (ret != LDB_SUCCESS) { \ - PyErr_SetLdbError(err, ret, ldb); \ - return NULL; \ - } - -/* Picked out of thin air. To do this properly, we should probably have some part of the - * errors in LDB be allocated to bindings ? */ -#define LDB_ERR_PYTHON_EXCEPTION 142 - -#endif /* _PYLDB_H_ */ diff --git a/source4/lib/ldb/pyldb_util.c b/source4/lib/ldb/pyldb_util.c deleted file mode 100644 index 79077416be4..00000000000 --- a/source4/lib/ldb/pyldb_util.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb - utility functions. - - Copyright (C) 2007-2010 Jelmer Vernooij - - ** 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 . -*/ - -#include -#include "ldb.h" -#include "pyldb.h" - -static PyObject *ldb_module = NULL; - -/* There's no Py_ssize_t in 2.4, apparently */ -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 -typedef int Py_ssize_t; -typedef inquiry lenfunc; -typedef intargfunc ssizeargfunc; -#endif - -#ifndef Py_RETURN_NONE -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - - -/** - * Find out PyTypeObject in ldb module for a given typename - */ -static PyTypeObject * PyLdb_GetPyType(const char *typename) -{ - PyObject *py_obj = NULL; - - if (ldb_module == NULL) { - ldb_module = PyImport_ImportModule("ldb"); - if (ldb_module == NULL) { - return NULL; - } - } - - py_obj = PyObject_GetAttrString(ldb_module, typename); - - return (PyTypeObject*)py_obj; -} - -/** - * Obtain a ldb DN from a Python object. - * - * @param mem_ctx Memory context - * @param object Python object - * @param ldb_ctx LDB context - * @return Whether or not the conversion succeeded - */ -bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, - struct ldb_context *ldb_ctx, struct ldb_dn **dn) -{ - struct ldb_dn *odn; - PyTypeObject *PyLdb_Dn_Type; - - if (ldb_ctx != NULL && PyString_Check(object)) { - odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object)); - *dn = odn; - return true; - } - - PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); - if (PyLdb_Dn_Type == NULL) { - return false; - } - - if (PyObject_TypeCheck(object, PyLdb_Dn_Type)) { - *dn = PyLdbDn_AsDn(object); - return true; - } - - PyErr_SetString(PyExc_TypeError, "Expected DN"); - return false; -} - -PyObject *PyLdbDn_FromDn(struct ldb_dn *dn) -{ - PyLdbDnObject *py_ret; - PyTypeObject *PyLdb_Dn_Type; - - if (dn == NULL) { - Py_RETURN_NONE; - } - - PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); - if (PyLdb_Dn_Type == NULL) { - return NULL; - } - - py_ret = (PyLdbDnObject *)PyLdb_Dn_Type->tp_alloc(PyLdb_Dn_Type, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = talloc_new(NULL); - py_ret->dn = talloc_reference(py_ret->mem_ctx, dn); - return (PyObject *)py_ret; -} diff --git a/source4/lib/ldb/tests/init.ldif b/source4/lib/ldb/tests/init.ldif deleted file mode 100644 index 97b4561e378..00000000000 --- a/source4/lib/ldb/tests/init.ldif +++ /dev/null @@ -1,41 +0,0 @@ -dn: o=University of Michigan,c=TEST -objectclass: organization -objectclass: domainRelatedObject -l: Ann Arbor, Michigan -st: Michigan -o: University of Michigan -o: UMICH -o: UM -o: U-M -o: U of M -description: The University of Michigan at Ann Arbor -postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 - 09 $ US -telephonenumber: +1 313 764-1817 -associateddomain: example.com - -# there was an empty "seeAlso" here - -dn: ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -uidNumber: 0 -gidNumber: 0 - -dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: Ldb Test -uidNumber: 0 -gidNumber: 0 - -dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: LdbTspace -description: test white space removal in comparisons -uidNumber: 0 -gidNumber: 0 diff --git a/source4/lib/ldb/tests/init_slapd.sh b/source4/lib/ldb/tests/init_slapd.sh deleted file mode 100755 index cf06acd08b9..00000000000 --- a/source4/lib/ldb/tests/init_slapd.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -rm -rf tests/tmp/db -mkdir -p tests/tmp/db - -if [ -f tests/tmp/slapd.pid ]; then - kill `cat tests/tmp/slapd.pid` - sleep 1 -fi -if [ -f tests/tmp/slapd.pid ]; then - kill -9 `cat tests/tmp/slapd.pid` - rm -f tests/tmp/slapd.pid -fi - -# we don't consider a slapadd failure as a test suite failure, as it -# has nothing to do with ldb - -MODCONF=tests/tmp/modules.conf -rm -f $MODCONF -touch $MODCONF || exit 1 - -slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { - echo "enabling sladp modules" -cat > $MODCONF < - -import os -import unittest - -import ldb - - -def filename(): - import tempfile - try: - dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") - except KeyError: - dir_prefix = None - return tempfile.mktemp(dir=dir_prefix) - -class NoContextTests(unittest.TestCase): - - def test_valid_attr_name(self): - self.assertTrue(ldb.valid_attr_name("foo")) - self.assertFalse(ldb.valid_attr_name("24foo")) - - def test_timestring(self): - self.assertEquals("19700101000000.0Z", ldb.timestring(0)) - self.assertEquals("20071119191012.0Z", ldb.timestring(1195499412)) - - def test_string_to_time(self): - self.assertEquals(0, ldb.string_to_time("19700101000000.0Z")) - self.assertEquals(1195499412, ldb.string_to_time("20071119191012.0Z")) - - -class SimpleLdb(unittest.TestCase): - - def test_connect(self): - ldb.Ldb(filename()) - - def test_connect_none(self): - ldb.Ldb() - - def test_connect_later(self): - x = ldb.Ldb() - x.connect(filename()) - - def test_repr(self): - x = ldb.Ldb() - self.assertTrue(repr(x).startswith("]", repr(x.modules())) - - def test_search(self): - l = ldb.Ldb(filename()) - self.assertEquals(len(l.search()), 1) - - def test_search_controls(self): - l = ldb.Ldb(filename()) - self.assertEquals(len(l.search(controls=["paged_results:0:5"])), 1) - - def test_search_attrs(self): - l = ldb.Ldb(filename()) - self.assertEquals(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) - - def test_search_string_dn(self): - l = ldb.Ldb(filename()) - self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) - - def test_search_attr_string(self): - l = ldb.Ldb(filename()) - self.assertRaises(TypeError, l.search, attrs="dc") - - def test_opaque(self): - l = ldb.Ldb(filename()) - l.set_opaque("my_opaque", l) - self.assertTrue(l.get_opaque("my_opaque") is not None) - self.assertEquals(None, l.get_opaque("unknown")) - - def test_search_scope_base(self): - l = ldb.Ldb(filename()) - self.assertEquals(len(l.search(ldb.Dn(l, "dc=foo1"), - ldb.SCOPE_ONELEVEL)), 0) - - def test_delete(self): - l = ldb.Ldb(filename()) - self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) - - def test_delete_w_unhandled_ctrl(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo1") - m["b"] = ["a"] - l.add(m) - self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) - l.delete(m.dn) - - def test_contains(self): - name = filename() - l = ldb.Ldb(name) - self.assertFalse(ldb.Dn(l, "dc=foo3") in l) - l = ldb.Ldb(name) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo3") - m["b"] = ["a"] - l.add(m) - try: - self.assertTrue(ldb.Dn(l, "dc=foo3") in l) - finally: - l.delete(m.dn) - - def test_get_config_basedn(self): - l = ldb.Ldb(filename()) - self.assertEquals(None, l.get_config_basedn()) - - def test_get_root_basedn(self): - l = ldb.Ldb(filename()) - self.assertEquals(None, l.get_root_basedn()) - - def test_get_schema_basedn(self): - l = ldb.Ldb(filename()) - self.assertEquals(None, l.get_schema_basedn()) - - def test_get_default_basedn(self): - l = ldb.Ldb(filename()) - self.assertEquals(None, l.get_default_basedn()) - - def test_add(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo4") - m["bla"] = "bla" - self.assertEquals(len(l.search()), 1) - l.add(m) - try: - self.assertEquals(len(l.search()), 2) - finally: - l.delete(ldb.Dn(l, "dc=foo4")) - - def test_add_w_unhandled_ctrl(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo4") - m["bla"] = "bla" - self.assertEquals(len(l.search()), 1) - self.assertRaises(ldb.LdbError, lambda: l.add(m,["search_options:1:2"])) - - def test_add_dict(self): - l = ldb.Ldb(filename()) - m = {"dn": ldb.Dn(l, "dc=foo5"), - "bla": "bla"} - self.assertEquals(len(l.search()), 1) - l.add(m) - try: - self.assertEquals(len(l.search()), 2) - finally: - l.delete(ldb.Dn(l, "dc=foo5")) - - def test_add_dict_string_dn(self): - l = ldb.Ldb(filename()) - m = {"dn": "dc=foo6", "bla": "bla"} - self.assertEquals(len(l.search()), 1) - l.add(m) - try: - self.assertEquals(len(l.search()), 2) - finally: - l.delete(ldb.Dn(l, "dc=foo6")) - - def test_rename(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo7") - m["bla"] = "bla" - self.assertEquals(len(l.search()), 1) - l.add(m) - try: - l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) - self.assertEquals(len(l.search()), 2) - finally: - l.delete(ldb.Dn(l, "dc=bar")) - - def test_rename_string_dns(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo8") - m["bla"] = "bla" - self.assertEquals(len(l.search()), 1) - l.add(m) - self.assertEquals(len(l.search()), 2) - try: - l.rename("dc=foo8", "dc=bar") - self.assertEquals(len(l.search()), 2) - finally: - l.delete(ldb.Dn(l, "dc=bar")) - - def test_modify_delete(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m["bla"] = ["1234"] - l.add(m) - rm = l.search(m.dn)[0] - self.assertEquals(["1234"], list(rm["bla"])) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") - self.assertEquals(ldb.FLAG_MOD_DELETE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEquals(1, len(rm)) - rm = l.search(m.dn, attrs=["bla"]) - self.assertEquals(0, len(rm)) - finally: - l.delete(ldb.Dn(l, "dc=modifydelete")) - - def test_modify_add(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ["1234"] - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEquals(2, len(rm)) - self.assertEquals(["1234", "456"], list(rm["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_modify_replace(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m["bla"] = ["1234", "456"] - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") - self.assertEquals(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEquals(2, len(rm)) - self.assertEquals(["789"], list(rm["bla"])) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEquals(1, len(rm)) - finally: - l.delete(ldb.Dn(l, "dc=modify2")) - - def test_modify_flags_change(self): - l = ldb.Ldb(filename()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ["1234"] - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEquals(2, len(rm)) - self.assertEquals(["1234", "456"], list(rm["bla"])) - - # Now create another modify, but switch the flags before we do it - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - m["bla"].set_flags(ldb.FLAG_MOD_DELETE) - l.modify(m) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEquals(1, len(rm)) - self.assertEquals(["1234"], list(rm["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_transaction_commit(self): - l = ldb.Ldb(filename()) - l.transaction_start() - m = ldb.Message(ldb.Dn(l, "dc=foo9")) - m["foo"] = ["bar"] - l.add(m) - l.transaction_commit() - l.delete(m.dn) - - def test_transaction_cancel(self): - l = ldb.Ldb(filename()) - l.transaction_start() - m = ldb.Message(ldb.Dn(l, "dc=foo10")) - m["foo"] = ["bar"] - l.add(m) - l.transaction_cancel() - self.assertEquals(0, len(l.search(ldb.Dn(l, "dc=foo10")))) - - def test_set_debug(self): - def my_report_fn(level, text): - pass - l = ldb.Ldb(filename()) - l.set_debug(my_report_fn) - - def test_zero_byte_string(self): - """Testing we do not get trapped in the \0 byte in a property string.""" - l = ldb.Ldb(filename()) - l.add({ - "dn" : "dc=somedn", - "objectclass" : "user", - "cN" : "LDAPtestUSER", - "givenname" : "ldap", - "displayname" : "foo\0bar", - }) - res = l.search(expression="(dn=dc=somedn)") - self.assertEquals("foo\0bar", res[0]["displayname"][0]) - - def test_no_crash_broken_expr(self): - l = ldb.Ldb(filename()) - self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"])) - - -class DnTests(unittest.TestCase): - - def setUp(self): - self.ldb = ldb.Ldb(filename()) - - def test_set_dn_invalid(self): - x = ldb.Message() - def assign(): - x.dn = "astring" - self.assertRaises(TypeError, assign) - - def test_eq(self): - x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") - y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") - self.assertEquals(x, y) - y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") - self.assertNotEquals(x, y) - - def test_str(self): - x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe") - self.assertEquals(x.__str__(), "dc=foo12,bar=bloe") - - def test_repr(self): - x = ldb.Dn(self.ldb, "dc=foo13,bla=blie") - self.assertEquals(x.__repr__(), "Dn('dc=foo13,bla=blie')") - - def test_get_casefold(self): - x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe") - self.assertEquals(x.get_casefold(), "DC=FOO14,BAR=bloe") - - def test_validate(self): - x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe") - self.assertTrue(x.validate()) - - def test_parent(self): - x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe") - self.assertEquals("bar=bloe", x.parent().__str__()) - - def test_parent_nonexistant(self): - x = ldb.Dn(self.ldb, "@BLA") - self.assertEquals(None, x.parent()) - - def test_is_valid(self): - x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe") - self.assertTrue(x.is_valid()) - x = ldb.Dn(self.ldb, "") - self.assertTrue(x.is_valid()) - - def test_is_special(self): - x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe") - self.assertFalse(x.is_special()) - x = ldb.Dn(self.ldb, "@FOOBAR") - self.assertTrue(x.is_special()) - - def test_check_special(self): - x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe") - self.assertFalse(x.check_special("FOOBAR")) - x = ldb.Dn(self.ldb, "@FOOBAR") - self.assertTrue(x.check_special("@FOOBAR")) - - def test_len(self): - x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe") - self.assertEquals(2, len(x)) - x = ldb.Dn(self.ldb, "dc=foo21") - self.assertEquals(1, len(x)) - - def test_add_child(self): - x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") - self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe"))) - self.assertEquals("bla=bloe,dc=foo22,bar=bloe", x.__str__()) - - def test_add_base(self): - x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") - base = ldb.Dn(self.ldb, "bla=bloe") - self.assertTrue(x.add_base(base)) - self.assertEquals("dc=foo23,bar=bloe,bla=bloe", x.__str__()) - - def test_add(self): - x = ldb.Dn(self.ldb, "dc=foo24") - y = ldb.Dn(self.ldb, "bar=bla") - self.assertEquals("dc=foo24,bar=bla", str(y + x)) - - def test_parse_ldif(self): - msgs = self.ldb.parse_ldif("dn: foo=bar\n") - msg = msgs.next() - self.assertEquals("foo=bar", str(msg[1].dn)) - self.assertTrue(isinstance(msg[1], ldb.Message)) - ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) - self.assertEquals("dn: foo=bar\n\n", ldif) - - def test_parse_ldif_more(self): - msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") - msg = msgs.next() - self.assertEquals("foo=bar", str(msg[1].dn)) - msg = msgs.next() - self.assertEquals("bar=bar", str(msg[1].dn)) - - def test_canonical_string(self): - x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe") - self.assertEquals("/bloe/foo25", x.canonical_str()) - - def test_canonical_ex_string(self): - x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe") - self.assertEquals("/bloe\nfoo26", x.canonical_ex_str()) - - -class LdbMsgTests(unittest.TestCase): - - def setUp(self): - self.msg = ldb.Message() - - def test_init_dn(self): - self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27")) - self.assertEquals("dc=foo27", str(self.msg.dn)) - - def test_iter_items(self): - self.assertEquals(0, len(self.msg.items())) - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo28") - self.assertEquals(1, len(self.msg.items())) - - def test_repr(self): - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo29") - self.msg["dc"] = "foo" - self.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self.msg)) - - def test_len(self): - self.assertEquals(0, len(self.msg)) - - def test_notpresent(self): - self.assertRaises(KeyError, lambda: self.msg["foo"]) - - def test_del(self): - del self.msg["foo"] - - def test_add(self): - self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) - - def test_elements_empty(self): - self.assertEquals([], self.msg.elements()) - - def test_elements(self): - el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.msg.add(el) - self.assertEquals([el], self.msg.elements()) - - def test_add_value(self): - self.assertEquals(0, len(self.msg)) - self.msg["foo"] = ["foo"] - self.assertEquals(1, len(self.msg)) - - def test_add_value_multiple(self): - self.assertEquals(0, len(self.msg)) - self.msg["foo"] = ["foo", "bla"] - self.assertEquals(1, len(self.msg)) - self.assertEquals(["foo", "bla"], list(self.msg["foo"])) - - def test_set_value(self): - self.msg["foo"] = ["fool"] - self.assertEquals(["fool"], list(self.msg["foo"])) - self.msg["foo"] = ["bar"] - self.assertEquals(["bar"], list(self.msg["foo"])) - - def test_keys(self): - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") - self.msg["foo"] = ["bla"] - self.msg["bar"] = ["bla"] - self.assertEquals(["dn", "foo", "bar"], self.msg.keys()) - - def test_dn(self): - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") - self.assertEquals("@BASEINFO", self.msg.dn.__str__()) - - def test_get_dn(self): - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") - self.assertEquals("@BASEINFO", self.msg.get("dn").__str__()) - - def test_get_invalid(self): - self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") - self.assertRaises(TypeError, self.msg.get, 42) - - def test_get_other(self): - self.msg["foo"] = ["bar"] - self.assertEquals("bar", self.msg.get("foo")[0]) - - def test_get_default(self): - self.assertEquals(None, self.msg.get("tatayoyo")) - - self.assertEquals("anniecordie", self.msg.get("tatayoyo", "anniecordie")) - - def test_get_unknown(self): - self.assertEquals(None, self.msg.get("lalalala")) - - def test_msg_diff(self): - l = ldb.Ldb() - msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") - msg1 = msgs.next()[1] - msg2 = msgs.next()[1] - msgdiff = l.msg_diff(msg1, msg2) - self.assertEquals("foo=bar", msgdiff.get("dn").__str__()) - self.assertRaises(KeyError, lambda: msgdiff["foo"]) - self.assertEquals(1, len(msgdiff)) - - def test_equal_empty(self): - msg1 = ldb.Message() - msg2 = ldb.Message() - self.assertEquals(msg1, msg2) - - def test_equal_simplel(self): - db = ldb.Ldb(filename()) - msg1 = ldb.Message() - msg1.dn = ldb.Dn(db, "foo=bar") - msg2 = ldb.Message() - msg2.dn = ldb.Dn(db, "foo=bar") - self.assertEquals(msg1, msg2) - msg1['foo'] = 'bar' - msg2['foo'] = 'bar' - self.assertEquals(msg1, msg2) - msg2['foo'] = 'blie' - self.assertNotEquals(msg1, msg2) - msg2['foo'] = 'blie' - - def test_from_dict(self): - rec = {"dn": "dc=fromdict", - "a1": ["a1-val1", "a1-val1"]} - l = ldb.Ldb() - # check different types of input Flags - for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: - m = ldb.Message.from_dict(l, rec, flags) - self.assertEquals(rec["a1"], list(m["a1"])) - self.assertEquals(flags, m["a1"].flags()) - # check input params - self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) - self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) - self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) - # Message.from_dict expects dictionary with 'dn' - err_rec = {"a1": ["a1-val1", "a1-val1"]} - self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) - - - -class MessageElementTests(unittest.TestCase): - - def test_cmp_element(self): - x = ldb.MessageElement(["foo"]) - y = ldb.MessageElement(["foo"]) - z = ldb.MessageElement(["bzr"]) - self.assertEquals(x, y) - self.assertNotEquals(x, z) - - def test_create_iterable(self): - x = ldb.MessageElement(["foo"]) - self.assertEquals(["foo"], list(x)) - - def test_repr(self): - x = ldb.MessageElement(["foo"]) - self.assertEquals("MessageElement(['foo'])", repr(x)) - x = ldb.MessageElement(["foo", "bla"]) - self.assertEquals(2, len(x)) - self.assertEquals("MessageElement(['foo','bla'])", repr(x)) - - def test_get_item(self): - x = ldb.MessageElement(["foo", "bar"]) - self.assertEquals("foo", x[0]) - self.assertEquals("bar", x[1]) - self.assertEquals("bar", x[-1]) - self.assertRaises(IndexError, lambda: x[45]) - - def test_len(self): - x = ldb.MessageElement(["foo", "bar"]) - self.assertEquals(2, len(x)) - - def test_eq(self): - x = ldb.MessageElement(["foo", "bar"]) - y = ldb.MessageElement(["foo", "bar"]) - self.assertEquals(y, x) - x = ldb.MessageElement(["foo"]) - self.assertNotEquals(y, x) - y = ldb.MessageElement(["foo"]) - self.assertEquals(y, x) - - def test_extended(self): - el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEquals("MessageElement(['456'])", repr(el)) - - -class ModuleTests(unittest.TestCase): - - def test_register_module(self): - class ExampleModule: - name = "example" - ldb.register_module(ExampleModule) - - def test_use_module(self): - ops = [] - class ExampleModule: - name = "bla" - - def __init__(self, ldb, next): - ops.append("init") - self.next = next - - def search(self, *args, **kwargs): - return self.next.search(*args, **kwargs) - - def request(self, *args, **kwargs): - pass - - name = filename() - ldb.register_module(ExampleModule) - if os.path.exists(name): - os.unlink(name) - l = ldb.Ldb(name) - l.add({"dn": "@MODULES", "@LIST": "bla"}) - self.assertEquals([], ops) - l = ldb.Ldb(name) - self.assertEquals(["init"], ops) - -class LdbResultTests(unittest.TestCase): - - def setUp(self): - name = filename() - self.name = name - if os.path.exists(name): - os.unlink(name) - self.l = ldb.Ldb(name) - self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": "samba.org"}) - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": "Admins"}) - self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": "Users"}) - self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": "OU #1"}) - self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": "OU #2"}) - self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": "OU #3"}) - self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": "OU #4"}) - self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": "OU #5"}) - self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": "OU #6"}) - self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": "OU #7"}) - self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": "OU #8"}) - self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": "OU #9"}) - self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": "OU #10"}) - - def tearDown(self): - if os.path.exists(self.name): - os.unlink(self.name) - - def test_return_type(self): - res = self.l.search() - self.assertEquals(str(res), "") - - def test_get_msgs(self): - res = self.l.search() - list = res.msgs - - def test_get_controls(self): - res = self.l.search() - list = res.controls - - def test_get_referals(self): - res = self.l.search() - list = res.referals - - def test_iter_msgs(self): - found = False - for l in self.l.search().msgs: - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - def test_iter_msgs_count(self): - self.assertTrue(self.l.search().count > 0) - # 13 objects has been added to the DC=SAMBA, DC=ORG - self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) - - def test_iter_controls(self): - res = self.l.search().controls - it = iter(res) - - def test_create_control(self): - self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") - c = ldb.Control(self.l, "relax:1") - self.assertEquals(c.critical, True) - self.assertEquals(c.oid, "1.3.6.1.4.1.4203.666.5.12") - - def test_iter_refs(self): - res = self.l.search().referals - it = iter(res) - - def test_iter_as_sequence_msgs(self): - found = False - res = self.l.search().msgs - - for i in range(0, len(res)): - l = res[i] - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - def test_iter_as_sequence(self): - found = False - res = self.l.search() - - for i in range(0, len(res)): - l = res[i] - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - -class VersionTests(unittest.TestCase): - - def test_version(self): - self.assertTrue(isinstance(ldb.__version__, str)) - - -if __name__ == '__main__': - import unittest - unittest.TestProgram() diff --git a/source4/lib/ldb/tests/samba4.png b/source4/lib/ldb/tests/samba4.png deleted file mode 100644 index c8096889a67..00000000000 Binary files a/source4/lib/ldb/tests/samba4.png and /dev/null differ diff --git a/source4/lib/ldb/tests/sample_module.c b/source4/lib/ldb/tests/sample_module.c deleted file mode 100644 index bee40a5e80f..00000000000 --- a/source4/lib/ldb/tests/sample_module.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2007 - - ** 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 . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -static int sample_add(struct ldb_module *mod, struct ldb_request *req) -{ - struct ldb_control *control; - - ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample"); - - /* check if there's a relax control */ - control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(mod, req); - } else { - return LDB_ERR_UNWILLING_TO_PERFORM; - } -} - -static int sample_modify(struct ldb_module *mod, struct ldb_request *req) -{ - struct ldb_control *control; - - /* check if there's a relax control */ - control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(mod, req); - } else { - return LDB_ERR_UNWILLING_TO_PERFORM; - } -} - - -static struct ldb_module_ops ldb_sample_module_ops = { - .name = "sample", - .add = sample_add, - .del = sample_modify, - .modify = sample_modify, -}; - -int ldb_sample_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_sample_module_ops); -} diff --git a/source4/lib/ldb/tests/schema-tests/schema-add-test.ldif b/source4/lib/ldb/tests/schema-tests/schema-add-test.ldif deleted file mode 100644 index 472ab48fac9..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-add-test.ldif +++ /dev/null @@ -1,66 +0,0 @@ -dn: CN=Users,DC=schema,DC=test -objectClass: top -objectClass: container -cn: Users -description: Default container for upgraded user accounts -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -uSNChanged: 1 -showInAdvancedViewOnly: FALSE -name: Users -objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 -systemFlags: 0x8c000000 -objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -nTSecurityDescriptor: foo - -dn: CN=Administrator,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: person -objectClass: organizationalPerson -objectClass: user -cn: Administrator -description: Built-in account for administering the computer/domain -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test -memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test -uSNChanged: 1 -name: Administrator -objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c -userAccountControl: 0x10200 -badPwdCount: 0 -codePage: 0 -countryCode: 0 -badPasswordTime: 0 -lastLogoff: 0 -lastLogon: 0 -pwdLastSet: 0 -primaryGroupID: 513 -objectSid: S-1-5-21-43662522-77495566-38969261-500 -adminCount: 1 -accountExpires: 9223372036854775807 -logonCount: 0 -sAMAccountName: Administrator -sAMAccountType: 0x30000000 -objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -unicodePwd: samba -nTSecurityDescriptor: foo - -dn: CN=Test,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: test -cn: Test -description: This is a test -objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test -nTSecurityDescriptor: foo -instanceType: 4 - diff --git a/source4/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif b/source4/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif deleted file mode 100644 index b9767244854..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -replace: description -description: this test must not fail - diff --git a/source4/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif b/source4/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif deleted file mode 100644 index fa193af6832..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: description -# this test must not fail - diff --git a/source4/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif b/source4/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif deleted file mode 100644 index 8ab7798f9ce..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: description -description: this test must not fail - diff --git a/source4/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif b/source4/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif deleted file mode 100644 index cbf0e60bbea..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: foo -foo: this test must fail - diff --git a/source4/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif b/source4/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif deleted file mode 100644 index bc64e9edb61..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: nTSecurityDescriptor -# this test must fail - diff --git a/source4/lib/ldb/tests/schema-tests/schema.ldif b/source4/lib/ldb/tests/schema-tests/schema.ldif deleted file mode 100644 index 4ab1932839b..00000000000 --- a/source4/lib/ldb/tests/schema-tests/schema.ldif +++ /dev/null @@ -1,100 +0,0 @@ -dn: @INDEXLIST -@IDXATTR: name -@IDXATTR: sAMAccountName -@IDXATTR: objectSid -@IDXATTR: objectClass -@IDXATTR: member -@IDXATTR: uidNumber -@IDXATTR: gidNumber -@IDXATTR: unixName -@IDXATTR: privilege -@IDXATTR: lDAPDisplayName - -dn: @ATTRIBUTES -realm: CASE_INSENSITIVE -userPrincipalName: CASE_INSENSITIVE -servicePrincipalName: CASE_INSENSITIVE -name: CASE_INSENSITIVE -dn: CASE_INSENSITIVE -sAMAccountName: CASE_INSENSITIVE -objectClass: CASE_INSENSITIVE -unicodePwd: HIDDEN -ntPwdHash: HIDDEN -ntPwdHistory: HIDDEN -lmPwdHash: HIDDEN -lmPwdHistory: HIDDEN -createTimestamp: HIDDEN -modifyTimestamp: HIDDEN - -dn: @MODULES -@LIST: timestamps,schema - -dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: top -cn: Top -uSNCreated: 1 -uSNChanged: 1 -subClassOf: top -systemMustContain: objectClass -systemMayContain: structuralObjectClass -systemMayContain: createTimeStamp -systemMayContain: modifyTimeStamp -systemMayContain: creatorsName -systemMayContain: modifiersName -systemMayContain: hasSubordinates -systemMayContain: subschemaSubentry -systemMayContain: collectiveSubentry -systemMayContain: entryUUID -systemMayContain: entryCSN -systemMayContain: namingCSN -systemMayContain: superiorUUID -systemMayContain: contextCSN -systemMayContain: whenCreated -systemMayContain: whenChanged -systemMayContain: uSNCreated -systemMayContain: uSNChanged -systemMayContain: distinguishedName -systemMayContain: name -systemMayContain: cn -systemMayContain: userPassword -systemMayContain: labeledURI - -dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: classSchema -cn: Class-Schema -uSNCreated: 2 -uSNChanged: 2 -lDAPDisplayName: classSchema -subClassOf: top -systemMustContain: cn -systemMustContain: subClassOf -systemMayContain: systemPossSuperiors -systemMayContain: systemOnly -systemMayContain: systemMustContain -systemMayContain: systemMayContain -systemMayContain: systemAuxiliaryClass -systemMayContain: possSuperiors -systemMayContain: mustContain -systemMayContain: mayContain -systemMayContain: lDAPDisplayName -systemMayContain: auxiliaryClass - -dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -cn: Attribute-Schema -uSNCreated: 3 -uSNChanged: 3 -lDAPDisplayName: attributeSchema -subClassOf: top -systemMustContain: oMSyntax -systemMustContain: lDAPDisplayName -systemMustContain: isSingleValued -systemMustContain: cn -systemMustContain: attributeSyntax -systemMustContain: attributeID - diff --git a/source4/lib/ldb/tests/slapd.conf b/source4/lib/ldb/tests/slapd.conf deleted file mode 100644 index fa2789d8c17..00000000000 --- a/source4/lib/ldb/tests/slapd.conf +++ /dev/null @@ -1,26 +0,0 @@ -loglevel 0 - -include tests/schema/core.schema -include tests/schema/cosine.schema -include tests/schema/inetorgperson.schema -include tests/schema/openldap.schema -include tests/schema/nis.schema - - -pidfile tests/tmp/slapd.pid -argsfile tests/tmp/slapd.args - -access to * by * write - -allow update_anon bind_anon_dn - -include tests/tmp/modules.conf - -defaultsearchbase "o=University of Michigan,c=TEST" - -backend bdb -database bdb -suffix "o=University of Michigan,c=TEST" -directory tests/tmp/db -index objectClass eq -index uid eq diff --git a/source4/lib/ldb/tests/start_slapd.sh b/source4/lib/ldb/tests/start_slapd.sh deleted file mode 100755 index 11679d47a3e..00000000000 --- a/source4/lib/ldb/tests/start_slapd.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -mkdir -p $LDBDIR/tests/tmp/db - -# running slapd in the background (with &) means it stays in the same process group, so it can be -# killed by timelimit -slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & - -sleep 2 diff --git a/source4/lib/ldb/tests/test-attribs.ldif b/source4/lib/ldb/tests/test-attribs.ldif deleted file mode 100644 index 79508c4b7bc..00000000000 --- a/source4/lib/ldb/tests/test-attribs.ldif +++ /dev/null @@ -1,6 +0,0 @@ -dn: @ATTRIBUTES -uid: CASE_INSENSITIVE -cn: CASE_INSENSITIVE -ou: CASE_INSENSITIVE -dn: CASE_INSENSITIVE - diff --git a/source4/lib/ldb/tests/test-config.ldif b/source4/lib/ldb/tests/test-config.ldif deleted file mode 100644 index 7926a9e3c58..00000000000 --- a/source4/lib/ldb/tests/test-config.ldif +++ /dev/null @@ -1,67 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=Config,cn=Samba -objectclass: globalconfig -LocalConfigCn: cn=%U,cn=Config,cn=Samba -LocalConfigCn;1: cn=%U,cn=Config,cn=Samba -LocalConfigCn;2: cn=%I,cn=Config,cn=Samba -LocalConfigCn;3: cn=%M,cn=Config,cn=Samba - -############# -dn: cn=Protocol,cn=Global,cn=Config,cn=Samba -maxXmit: 7000 - -################################ -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge - -################################# -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge -Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba - -#### ((objectClass=fileshare)(cn=test)) -############################## -# [test] share -dn: cn=test,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: test -Comment: a test share -Path: /home/tridge/samba4/prefix/test -ReadOnly: no - -##################################### -# [msdn] a remote proxy share, stored -# on \\msdn\test -dn: cn=msdn,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: msdn -NtvfsHandler: cifs -ReadOnly: no -_CifsServer: msdn -_CifsUser: administrator -_CifsPassword: penguin -_CifsDomain: winxp -_CifsShare: test - - -############################## -# [VisualC] share -dn: cn=visualc,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: VisualC -Comment: VisualC development -Path: /home/tridge/VisualC -ReadOnly: no -NtvfsHandler: simple - diff --git a/source4/lib/ldb/tests/test-controls.sh b/source4/lib/ldb/tests/test-controls.sh deleted file mode 100755 index 771085ec606..00000000000 --- a/source4/lib/ldb/tests/test-controls.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -if [ -n "$TEST_DATA_PREFIX" ]; then - LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" -else - LDB_URL="tdbtest.ldb" -fi -export LDB_URL - -PATH=bin:$PATH -export PATH - -rm -f $LDB_URL* - -echo "LDB_URL: $LDB_URL" -cat </dev/null 2>&1 || exit 1 - -set diff --git a/source4/lib/ldb/tests/test-default-config.ldif b/source4/lib/ldb/tests/test-default-config.ldif deleted file mode 100644 index 87b7bcd3cc7..00000000000 --- a/source4/lib/ldb/tests/test-default-config.ldif +++ /dev/null @@ -1,17 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=DefaultConfig,cn=Samba -objectclass: globalconfig -Workgroup: WORKGROUP -UnixCharset: UTF8 -Security: user -NetbiosName: blu -GuestAccount: nobody - -############################## -# [_default_] share -dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba -objectclass: fileshare -cn: _default_ -Path: /tmp -ReadOnly: yes diff --git a/source4/lib/ldb/tests/test-extended.sh b/source4/lib/ldb/tests/test-extended.sh deleted file mode 100755 index 14b988e3f94..00000000000 --- a/source4/lib/ldb/tests/test-extended.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -echo "Running extended search tests" - -mv $LDB_URL $LDB_URL.1 - -cat < /dev/null && { - echo "Should have failed to add again - gave $?" - exit 1 -} - -echo "Modifying elements" -$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify.ldif || exit 1 - -echo "Showing modified record" -$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 - -echo "Rename entry with ldbmodify - modrdn" -$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 - -echo "Rename entry with ldbrename" -OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -$VALGRIND ldbrename$EXEEXT "$OLDDN" "$NEWDN" || exit 1 - -echo "Showing renamed record" -$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 - -echo "Starting ldbtest" -$VALGRIND ldbtest$EXEEXT --num-records 100 --num-searches 10 || exit 1 - -if [ $LDB_SPECIALS = 1 ]; then - echo "Adding index" - $VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-index.ldif || exit 1 -fi - -echo "Adding bad attributes - should fail" -$VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-wrong_attributes.ldif && { - echo "Should fhave failed - gave $?" - exit 1 -} - -echo "Testing indexed search" -$VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(|(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 -$VALGRIND ldbsearch$EXEEXT '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 - -# note that the "((" is treated as an attribute not an expression -# this matches the openldap ldapsearch behaviour of looking for a '=' -# to see if the first argument is an expression or not -$VALGRIND ldbsearch$EXEEXT '((' uid || exit 1 -$VALGRIND ldbsearch$EXEEXT '(objectclass=)' uid || exit 1 -$VALGRIND ldbsearch$EXEEXT -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 - -echo "Test wildcard match" -$VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-wildcard.ldif || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=test*multi)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=*test*multi*)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=*test_multi)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=test_multi*)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=test*multi*test*multi)' || exit 1 -$VALGRIND ldbsearch$EXEEXT '(cn=test*multi*test*multi*multi_*)' || exit 1 - -echo "Starting ldbtest indexed" -$VALGRIND ldbtest$EXEEXT --num-records 100 --num-searches 500 || exit 1 - -echo "Testing one level search" -count=`$VALGRIND ldbsearch$EXEEXT -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` -if [ $count != 3 ]; then - echo returned $count records - expected 3 - exit 1 -fi - -echo "Testing binary file attribute value" -$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/photo.ldif || exit 1 -count=`$VALGRIND ldbsearch$EXEEXT '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` -if [ $count != 1 ]; then - echo returned $count records - expected 1 - exit 1 -fi - -echo "*TODO* Testing UTF8 upper lower case searches !!" - -echo "Testing compare" -count=`$VALGRIND ldbsearch$EXEEXT '(cn>=t)' cn | grep '^dn' | wc -l` -if [ $count != 2 ]; then - echo returned $count records - expected 2 - echo "this fails on openLdap ..." -fi - -count=`$VALGRIND ldbsearch$EXEEXT '(cn<=t)' cn | grep '^dn' | wc -l` -if [ $count != 13 ]; then - echo returned $count records - expected 13 - echo "this fails on openLdap ..." -fi - -checkcount() { - count=$1 - scope=$2 - basedn=$3 - expression="$4" - n=`$VALGRIND ldbsearch$EXEEXT -s "$scope" -b "$basedn" "$expression" | grep '^dn' | wc -l` - if [ $n != $count ]; then - echo "Got $n but expected $count for $expression" - bin/ldbsearch "$expression" - exit 1 - fi - echo "OK: $count $expression" -} - -checkcount 0 'base' '' '(uid=uham)' -checkcount 0 'one' '' '(uid=uham)' - -checkcount 1 'base' 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' -checkcount 1 'one' 'ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' -checkcount 1 'one' 'ou=People,o=University of Michigan,c=TEST' '(ou=ldb test)' diff --git a/source4/lib/ldb/tests/test-index.ldif b/source4/lib/ldb/tests/test-index.ldif deleted file mode 100644 index 268173641d1..00000000000 --- a/source4/lib/ldb/tests/test-index.ldif +++ /dev/null @@ -1,7 +0,0 @@ -dn: @INDEXLIST -@IDXATTR: uid -@IDXATTR: objectclass - -dn: @ATTRIBUTES -uid: CASE_INSENSITIVE - diff --git a/source4/lib/ldb/tests/test-ldap.sh b/source4/lib/ldb/tests/test-ldap.sh deleted file mode 100755 index 14cfb5f9793..00000000000 --- a/source4/lib/ldb/tests/test-ldap.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh - -PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH -export PATH -SCHEMA_NEEDED="core nis cosine inetorgperson openldap" - -# setup needed schema files -for f in $SCHEMA_NEEDED; do - if [ ! -r tests/schema/$f.schema ]; then - mkdir -p tests/schema - if [ -r /etc/ldap/schema/$f.schema ]; then - ln -s /etc/ldap/schema/$f.schema tests/schema/$f.schema - continue; - fi - if [ -r /etc/openldap/schema/$f.schema ]; then - ln -s /etc/openldap/schema/$f.schema tests/schema/$f.schema - continue; - fi - - echo "SKIPPING TESTS: you need the following OpenLDAP schema files" - for f in $SCHEMA_NEEDED; do - echo " $f.schema" - done - exit 0 - fi -done - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -LDB_URL=`$LDBDIR/tests/ldapi_url.sh` -export LDB_URL - -PATH=bin:$PATH -export PATH - -LDB_SPECIALS=0 -export LDB_SPECIALS - -if $LDBDIR/tests/init_slapd.sh && - $LDBDIR/tests/start_slapd.sh && - $LDBDIR/tests/test-generic.sh; then - echo "ldap tests passed"; - ret=0 -else - echo "ldap tests failed"; - ret=$? -fi - -#$LDBDIR/tests/kill_slapd.sh - -exit $ret diff --git a/source4/lib/ldb/tests/test-modify-modrdn.ldif b/source4/lib/ldb/tests/test-modify-modrdn.ldif deleted file mode 100644 index efa31494626..00000000000 --- a/source4/lib/ldb/tests/test-modify-modrdn.ldif +++ /dev/null @@ -1,12 +0,0 @@ -dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -changetype: moddn -newrdn: cn=Hampster Ursula -deleteoldrdn: 1 -newsuperior: ou=Alumni Association,ou=People,o=University of Michigan,c=TEST - -dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -changetype: modrdn -newrdn: cn=Ursula Hampster -deleteoldrdn: 1 diff --git a/source4/lib/ldb/tests/test-modify.ldif b/source4/lib/ldb/tests/test-modify.ldif deleted file mode 100644 index e5b9ca40861..00000000000 --- a/source4/lib/ldb/tests/test-modify.ldif +++ /dev/null @@ -1,23 +0,0 @@ -dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -changetype: modify -add: drink -drink: mango lassi -- -add: drink -drink: lemonade -- -delete: pager -- -replace: telephonenumber -telephonenumber: +61 2 6260 6012 -telephonenumber: +61 412 666 929 -- -delete: telephonenumber -telephonenumber: +61 2 6260 6012 -- -delete: telephonenumber -telephonenumber: +61 412 666 929 -- -add: telephonenumber -telephonenumber: +61 412 666 929 diff --git a/source4/lib/ldb/tests/test-schema.sh b/source4/lib/ldb/tests/test-schema.sh deleted file mode 100755 index 97841844db8..00000000000 --- a/source4/lib/ldb/tests/test-schema.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -LDB_URL="tdb://schema.ldb" -export LDB_URL - -rm -f schema.ldb - -echo "LDB_URL: $LDB_URL" - -echo "Adding schema" -$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema.ldif || exit 1 - -echo "Adding few test elements (no failure expected here)" -$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema-add-test.ldif || exit 1 - -echo "Modifying elements (2 failures expected here)" - -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-1.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-2.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-3.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-4.ldif -if [ "$?" = "0" ]; then - echo "test failed!" - exit 1 -fi -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif -if [ "$?" = "0" ]; then - echo "test failed!" - exit 1 -fi - -echo "Showing modified record" -$VALGRIND bin/ldbsearch '(cn=Test)' || exit 1 - diff --git a/source4/lib/ldb/tests/test-soloading.sh b/source4/lib/ldb/tests/test-soloading.sh deleted file mode 100755 index da6d57541e5..00000000000 --- a/source4/lib/ldb/tests/test-soloading.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -if [ -n "$TEST_DATA_PREFIX" ]; then - LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" -else - LDB_URL="tdbtest.ldb" -fi -export LDB_URL - -PATH=bin:$PATH -export PATH - -rm -f $LDB_URL* - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -cat <. -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "ldb_module.h" -#include "tools/cmdline.h" - -static struct ldb_cmdline options; /* needs to be static for older compilers */ - -enum ldb_cmdline_options { CMDLINE_RELAX=1 }; - -static struct poptOption builtin_popt_options[] = { - POPT_AUTOHELP - { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, - { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, - { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, - { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, - { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, - { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, - { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, - { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, - { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, - { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, - { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, - { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, - { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, - { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, - { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, - { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, - { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, - { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, - { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, - { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, - { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, - { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, - { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, - { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, - { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, - { NULL } -}; - -void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) -{ - poptContext pc; - struct poptOption **popt_options = ldb_module_popt_options(ldb); - pc = poptGetContext(cmdname, 0, NULL, *popt_options, - POPT_CONTEXT_KEEP_FIRST); - poptPrintHelp(pc, f, 0); -} - -/* - add a control to the options structure - */ -static bool add_control(TALLOC_CTX *mem_ctx, const char *control) -{ - unsigned int i; - - /* count how many controls we already have */ - for (i=0; options.controls && options.controls[i]; i++) ; - - options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); - if (options.controls == NULL) { - return false; - } - options.controls[i] = control; - options.controls[i+1] = NULL; - return true; -} - -/** - process command line options -*/ -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, - int argc, const char **argv, - void (*usage)(struct ldb_context *)) -{ - struct ldb_cmdline *ret=NULL; - poptContext pc; - int num_options = 0; - int opt; - unsigned int flags = 0; - int rc; - struct poptOption **popt_options; - - /* make the ldb utilities line buffered */ - setlinebuf(stdout); - - ret = talloc_zero(ldb, struct ldb_cmdline); - if (ret == NULL) { - fprintf(stderr, "Out of memory!\n"); - goto failed; - } - - options = *ret; - - /* pull in URL */ - options.url = getenv("LDB_URL"); - - /* and editor (used by ldbedit) */ - options.editor = getenv("VISUAL"); - if (!options.editor) { - options.editor = getenv("EDITOR"); - } - if (!options.editor) { - options.editor = "vi"; - } - - options.scope = LDB_SCOPE_DEFAULT; - - popt_options = ldb_module_popt_options(ldb); - (*popt_options) = builtin_popt_options; - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - pc = poptGetContext(argv[0], argc, argv, *popt_options, - POPT_CONTEXT_KEEP_FIRST); - - while((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case 's': { - const char *arg = poptGetOptArg(pc); - if (strcmp(arg, "base") == 0) { - options.scope = LDB_SCOPE_BASE; - } else if (strcmp(arg, "sub") == 0) { - options.scope = LDB_SCOPE_SUBTREE; - } else if (strcmp(arg, "one") == 0) { - options.scope = LDB_SCOPE_ONELEVEL; - } else { - fprintf(stderr, "Invalid scope '%s'\n", arg); - goto failed; - } - break; - } - - case 'v': - options.verbose++; - break; - - case 'o': - options.options = talloc_realloc(ret, options.options, - const char *, num_options+3); - if (options.options == NULL) { - fprintf(stderr, "Out of memory!\n"); - goto failed; - } - options.options[num_options] = poptGetOptArg(pc); - options.options[num_options+1] = NULL; - num_options++; - break; - - case 'c': { - const char *cs = poptGetOptArg(pc); - const char *p; - - for (p = cs; p != NULL; ) { - const char *t, *c; - - t = strchr(p, ','); - if (t == NULL) { - c = talloc_strdup(options.controls, p); - p = NULL; - } else { - c = talloc_strndup(options.controls, p, t-p); - p = t + 1; - } - if (c == NULL || !add_control(ret, c)) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - } - - break; - } - case 'P': - if (!add_control(ret, "paged_results:1:1024")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'D': - if (!add_control(ret, "show_deleted:1")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'R': - if (!add_control(ret, "show_recycled:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'd': - if (!add_control(ret, "show_deactivated_link:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'r': - if (!add_control(ret, "reveal_internals:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case CMDLINE_RELAX: - if (!add_control(ret, "relax:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'N': - if (!add_control(ret, "search_options:1:2")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'E': - if (!add_control(ret, "extended_dn:1:1")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - default: - fprintf(stderr, "Invalid option %s: %s\n", - poptBadOption(pc, 0), poptStrerror(opt)); - if (usage) usage(ldb); - goto failed; - } - } - - /* setup the remaining options for the main program to use */ - options.argv = poptGetArgs(pc); - if (options.argv) { - options.argv++; - while (options.argv[options.argc]) options.argc++; - } - - *ret = options; - - /* all utils need some option */ - if (ret->url == NULL) { - fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); - if (usage) usage(ldb); - goto failed; - } - - if (strcmp(ret->url, "NONE") == 0) { - return ret; - } - - if (options.nosync) { - flags |= LDB_FLG_NOSYNC; - } - - if (options.show_binary) { - flags |= LDB_FLG_SHOW_BINARY; - } - - if (options.tracing) { - flags |= LDB_FLG_ENABLE_TRACING; - } - - if (options.modules_path != NULL) { - ldb_set_modules_dir(ldb, options.modules_path); - } - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - /* now connect to the ldb */ - if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { - fprintf(stderr, "Failed to connect to %s - %s\n", - ret->url, ldb_errstring(ldb)); - goto failed; - } - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - exit(LDB_ERR_OPERATIONS_ERROR); - return NULL; -} - -/* this function check controls reply and determines if more - * processing is needed setting up the request controls correctly - * - * returns: - * -1 error - * 0 all ok - * 1 all ok, more processing required - */ -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) -{ - unsigned int i, j; - int ret = 0; - - if (reply == NULL || request == NULL) return -1; - - for (i = 0; reply[i]; i++) { - if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { - struct ldb_vlv_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning VLV reply received but no request have been made\n"); - continue; - } - - /* check the result */ - if (rep_control->vlv_result != 0) { - fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); - } else { - fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); - } - - continue; - } - - if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { - struct ldb_asq_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { - struct ldb_paged_control *rep_control, *req_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - ret = 1; - - continue; - } - - if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { - struct ldb_sort_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning Server Sort reply received but no request found\n"); - continue; - } - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { - struct ldb_dirsync_control *rep_control, *req_control; - char *cookie; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); - printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); - - continue; - } - - /* no controls matched, throw a warning */ - fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); - } - - return ret; -} - diff --git a/source4/lib/ldb/tools/cmdline.h b/source4/lib/ldb/tools/cmdline.h deleted file mode 100644 index 416bf51d228..00000000000 --- a/source4/lib/ldb/tools/cmdline.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - ldb database library - command line handling for ldb tools - - Copyright (C) Andrew Tridgell 2005 - - ** 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 . -*/ - -#include - -struct ldb_cmdline { - const char *url; - enum ldb_scope scope; - const char *basedn; - const char *modules_path; - int interactive; - int sorted; - const char *editor; - int verbose; - int recursive; - int all_records; - int nosync; - const char **options; - int argc; - const char **argv; - int num_records; - int num_searches; - const char *sasl_mechanism; - const char **controls; - int show_binary; - int tracing; -}; - -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, - const char **argv, - void (*usage)(struct ldb_context *)); - - -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); -void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); - diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c deleted file mode 100644 index 47fd2618416..00000000000 --- a/source4/lib/ldb/tools/ldbadd.c +++ /dev/null @@ -1,154 +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: ldbadd - * - * Description: utility to add records - modelled on ldapadd - * - * Author: Andrew Tridgell - */ - -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" - -static unsigned int failures; -static struct ldb_cmdline *options; - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbadd \n"); - printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); - ldb_cmdline_help(ldb, "ldbadd", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - - -/* - add records from an opened file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) -{ - struct ldb_ldif *ldif; - int fun_ret = LDB_SUCCESS, ret; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - - while ((ldif = ldb_ldif_read_file(ldb, f))) { - if (ldif->changetype != LDB_CHANGETYPE_ADD && - ldif->changetype != LDB_CHANGETYPE_NONE) { - fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); - break; - } - - ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); - if (ret != LDB_SUCCESS) { - fprintf(stderr, - "ERR: Message canonicalize failed - %s\n", - ldb_strerror(ret)); - failures++; - fun_ret = ret; - ldb_ldif_read_free(ldb, ldif); - continue; - } - - ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); - if (ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: %s : \"%s\" on DN %s\n", - ldb_strerror(ret), ldb_errstring(ldb), - ldb_dn_get_linearized(ldif->msg->dn)); - failures++; - fun_ret = ret; - } else { - (*count)++; - if (options->verbose) { - printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); - } - } - ldb_ldif_read_free(ldb, ldif); - } - - return fun_ret; -} - - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - unsigned int i, count = 0; - int ret = LDB_SUCCESS; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); - return ret; - } - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;iargc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = process_file(ldb, f, &count); - fclose(f); - } - } - - if (count != 0) { - ret = ldb_transaction_commit(ldb); - if (ret != LDB_SUCCESS) { - printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); - return ret; - } - } else { - ldb_transaction_cancel(ldb); - } - - talloc_free(mem_ctx); - - printf("Added %u records with %u failures\n", count, failures); - - return ret; -} diff --git a/source4/lib/ldb/tools/ldbdel.c b/source4/lib/ldb/tools/ldbdel.c deleted file mode 100644 index 8036d09a70d..00000000000 --- a/source4/lib/ldb/tools/ldbdel.c +++ /dev/null @@ -1,135 +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: ldbdel - * - * Description: utility to delete records - modelled on ldapdelete - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" - -static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) -{ - return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); -} - -static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) -{ - int ret; - unsigned int i, total=0; - const char *attrs[] = { NULL }; - struct ldb_result *res; - - ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); - if (ret != LDB_SUCCESS) return ret; - - /* sort the DNs, deepest first */ - TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); - - for (i = 0; i < res->count; i++) { - if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { - total++; - } else { - printf("Failed to delete '%s' - %s\n", - ldb_dn_get_linearized(res->msgs[i]->dn), - ldb_errstring(ldb)); - } - } - - talloc_free(res); - - if (total == 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - printf("Deleted %u records\n", total); - return LDB_SUCCESS; -} - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbdel \n"); - printf("Deletes records from a ldb\n\n"); - ldb_cmdline_help(ldb, "ldbdel", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - struct ldb_control **req_ctrls; - struct ldb_cmdline *options; - struct ldb_context *ldb; - int ret = 0, i; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 1) { - usage(ldb); - } - - req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i=0;iargc;i++) { - struct ldb_dn *dn; - - dn = ldb_dn_new(ldb, ldb, options->argv[i]); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (options->recursive) { - ret = ldb_delete_recursive(ldb, dn,req_ctrls); - } else { - ret = ldb_delete_ctrl(ldb, dn,req_ctrls); - if (ret == LDB_SUCCESS) { - printf("Deleted 1 record\n"); - } - } - if (ret != LDB_SUCCESS) { - printf("delete of '%s' failed - (%s) %s\n", - ldb_dn_get_linearized(dn), - ldb_strerror(ret), - ldb_errstring(ldb)); - } - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c deleted file mode 100644 index aaf6d80352d..00000000000 --- a/source4/lib/ldb/tools/ldbedit.c +++ /dev/null @@ -1,372 +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: ldbedit - * - * Description: utility for ldb database editing - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "system/filesys.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "tools/ldbutil.h" - -static struct ldb_cmdline *options; - -/* - debug routine -*/ -static void ldif_write_msg(struct ldb_context *ldb, - FILE *f, - enum ldb_changetype changetype, - struct ldb_message *msg) -{ - struct ldb_ldif ldif; - ldif.changetype = changetype; - ldif.msg = msg; - ldb_ldif_write_file(ldb, f, &ldif); -} - -/* - modify a database record so msg1 becomes msg2 - returns the number of modified elements -*/ -static int modify_record(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_control **req_ctrls) -{ - int ret; - struct ldb_message *mod; - - if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { - fprintf(stderr, "Failed to calculate message differences\n"); - return -1; - } - - ret = mod->num_elements; - if (ret == 0) { - goto done; - } - - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); - } - - if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to modify %s - %s\n", - ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); - ret = -1; - goto done; - } - -done: - talloc_free(mod); - return ret; -} - -/* - find dn in msgs[] -*/ -static struct ldb_message *msg_find(struct ldb_context *ldb, - struct ldb_message **msgs, - unsigned int count, - struct ldb_dn *dn) -{ - unsigned int i; - for (i=0;idn) == 0) { - return msgs[i]; - } - } - return NULL; -} - -/* - merge the changes in msgs2 into the messages from msgs1 -*/ -static int merge_edits(struct ldb_context *ldb, - struct ldb_message **msgs1, unsigned int count1, - struct ldb_message **msgs2, unsigned int count2) -{ - unsigned int i; - struct ldb_message *msg; - int ret; - unsigned int adds=0, modifies=0, deletes=0; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls == NULL) { - fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); - return -1; - } - - if (ldb_transaction_start(ldb) != LDB_SUCCESS) { - fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); - return -1; - } - - /* do the adds and modifies */ - for (i=0;idn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); - } - if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to add %s - %s\n", - ldb_dn_get_linearized(msgs2[i]->dn), - ldb_errstring(ldb)); - ldb_transaction_cancel(ldb); - return -1; - } - adds++; - } else { - ret = modify_record(ldb, msg, msgs2[i], req_ctrls); - if (ret != -1) { - modifies += (unsigned int) ret; - } else { - return -1; - } - } - } - - /* do the deletes */ - for (i=0;idn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); - } - if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to delete %s - %s\n", - ldb_dn_get_linearized(msgs1[i]->dn), - ldb_errstring(ldb)); - ldb_transaction_cancel(ldb); - return -1; - } - deletes++; - } - } - - if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { - fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); - return -1; - } - - printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); - - return 0; -} - -/* - save a set of messages as ldif to a file -*/ -static int save_ldif(struct ldb_context *ldb, - FILE *f, struct ldb_message **msgs, unsigned int count) -{ - unsigned int i; - - fprintf(f, "# editing %u records\n", count); - - for (i=0;imsg; - } - - /* the feof() test works here, even for the last line of the - * file, as we parse ldif files character by character, and - * feof() is only true if we have failed to read a character - * from the file. So if the last line is bad, we don't get - * feof() set, so we know the record was bad. Only if we - * attempt to go to the next record will we get feof() and - * thus consider that the ldif has ended without errors - */ - if (!feof(f)) { - fprintf(stderr, "Error parsing ldif - aborting\n"); - fclose(f); - unlink(file_template); - return -1; - } - - fclose(f); - unlink(file_template); - - return merge_edits(ldb, msgs1, count1, msgs2, count2); -} - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbedit \n"); - ldb_cmdline_help(ldb, "ldbedit", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_result *result = NULL; - struct ldb_dn *basedn = NULL; - int ret; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - const char * const * attrs = NULL; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct ldb_control **req_ctrls; - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (options->argc > 0 && - strchr(options->argv[0], '=')) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if (basedn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); - if (ret != LDB_SUCCESS) { - printf("search failed - %s\n", ldb_errstring(ldb)); - return ret; - } - - if (result->count == 0) { - printf("no matching records - cannot edit\n"); - talloc_free(mem_ctx); - return LDB_SUCCESS; - } - - ret = do_edit(ldb, result->msgs, result->count, options->editor); - - talloc_free(mem_ctx); - - return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; -} diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c deleted file mode 100644 index 2ca7b62b2c3..00000000000 --- a/source4/lib/ldb/tools/ldbmodify.c +++ /dev/null @@ -1,156 +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: ldbmodify - * - * Description: utility to modify records - modelled on ldapmodify - * - * Author: Andrew Tridgell - */ - -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" - -static unsigned int failures; -static struct ldb_cmdline *options; - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbmodify \n"); - printf("Modifies a ldb based upon ldif change records\n\n"); - ldb_cmdline_help(ldb, "ldbmodify", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -/* - process modifies for one file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) -{ - struct ldb_ldif *ldif; - int fun_ret = LDB_SUCCESS, ret; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - while ((ldif = ldb_ldif_read_file(ldb, f))) { - struct ldb_dn *olddn; - bool deleteoldrdn = false; - struct ldb_dn *newdn; - const char *errstr = NULL; - - switch (ldif->changetype) { - case LDB_CHANGETYPE_NONE: - case LDB_CHANGETYPE_ADD: - ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); - break; - case LDB_CHANGETYPE_DELETE: - ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); - break; - case LDB_CHANGETYPE_MODIFY: - ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); - break; - case LDB_CHANGETYPE_MODRDN: - ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, - NULL, &deleteoldrdn, - NULL, &newdn); - if (ret == LDB_SUCCESS) { - if (deleteoldrdn) { - ret = ldb_rename(ldb, olddn, newdn); - } else { - errstr = "modrdn: deleteoldrdn=0 " - "not supported."; - ret = LDB_ERR_CONSTRAINT_VIOLATION; - } - } - break; - } - if (ret != LDB_SUCCESS) { - if (errstr == NULL) { - errstr = ldb_errstring(ldb); - } - fprintf(stderr, "ERR: (%s) \"%s\" on DN %s\n", - ldb_strerror(ret), - errstr, ldb_dn_get_linearized(ldif->msg->dn)); - failures++; - fun_ret = ret; - } else { - (*count)++; - if (options->verbose) { - printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); - } - } - ldb_ldif_read_free(ldb, ldif); - } - - if (!feof(f)) { - fprintf(stderr, "Failed to parse ldif\n"); - fun_ret = LDB_ERR_OPERATIONS_ERROR; - } - - return fun_ret; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - unsigned int i, count = 0; - int ret = LDB_SUCCESS; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;iargc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = process_file(ldb, f, &count); - fclose(f); - } - } - - talloc_free(mem_ctx); - - printf("Modified %u records with %u failures\n", count, failures); - - return ret; -} diff --git a/source4/lib/ldb/tools/ldbrename.c b/source4/lib/ldb/tools/ldbrename.c deleted file mode 100644 index 9bbd1f06b1a..00000000000 --- a/source4/lib/ldb/tools/ldbrename.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 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: ldbrename - * - * Description: utility to rename records - modelled on ldapmodrdn - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#include "ldb.h" -#include "tools/cmdline.h" - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbrename [] \n"); - printf("Renames records in a ldb\n\n"); - ldb_cmdline_help(ldb, "ldbmodify", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int ret; - struct ldb_cmdline *options; - struct ldb_dn *dn1, *dn2; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 2) { - usage(ldb); - } - - dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); - dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); - if ((dn1 == NULL) || (dn2 == NULL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_rename(ldb, dn1, dn2); - if (ret == LDB_SUCCESS) { - printf("Renamed 1 record\n"); - } else { - printf("rename of '%s' to '%s' failed - %s\n", - options->argv[0], options->argv[1], ldb_errstring(ldb)); - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c deleted file mode 100644 index d10b9650daf..00000000000 --- a/source4/lib/ldb/tools/ldbsearch.c +++ /dev/null @@ -1,317 +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: ldbsearch - * - * Description: utility for ldb search - modelled on ldapsearch - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "tools/cmdline.h" - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbsearch \n"); - ldb_cmdline_help(ldb, "ldbsearch", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -static int do_compare_msg(struct ldb_message **el1, - struct ldb_message **el2, - void *opaque) -{ - return ldb_dn_compare((*el1)->dn, (*el2)->dn); -} - -struct search_context { - struct ldb_context *ldb; - struct ldb_control **req_ctrls; - - int sort; - unsigned int num_stored; - struct ldb_message **store; - unsigned int refs_stored; - char **refs_store; - - unsigned int entries; - unsigned int refs; - - unsigned int pending; - int status; -}; - -static int store_message(struct ldb_message *msg, struct search_context *sctx) { - - sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); - if (!sctx->store) { - fprintf(stderr, "talloc_realloc failed while storing messages\n"); - return -1; - } - - sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); - sctx->num_stored++; - sctx->store[sctx->num_stored] = NULL; - - return 0; -} - -static int store_referral(char *referral, struct search_context *sctx) { - - sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs_stored + 2); - if (!sctx->refs_store) { - fprintf(stderr, "talloc_realloc failed while storing referrals\n"); - return -1; - } - - sctx->refs_store[sctx->refs_stored] = talloc_move(sctx->refs_store, &referral); - sctx->refs_stored++; - sctx->refs_store[sctx->refs_stored] = NULL; - - return 0; -} - -static int display_message(struct ldb_message *msg, struct search_context *sctx) { - struct ldb_ldif ldif; - - sctx->entries++; - printf("# record %d\n", sctx->entries); - - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = msg; - - if (sctx->sort) { - /* - * Ensure attributes are always returned in the same - * order. For testing, this makes comparison of old - * vs. new much easier. - */ - ldb_msg_sort_elements(ldif.msg); - } - - ldb_ldif_write_file(sctx->ldb, stdout, &ldif); - - return 0; -} - -static int display_referral(char *referral, struct search_context *sctx) -{ - - sctx->refs++; - printf("# Referral\nref: %s\n\n", referral); - - return 0; -} - -static int search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct search_context *sctx; - int ret = LDB_SUCCESS; - - sctx = talloc_get_type(req->context, struct search_context); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - if (sctx->sort) { - ret = store_message(ares->message, sctx); - } else { - ret = display_message(ares->message, sctx); - } - break; - - case LDB_REPLY_REFERRAL: - if (sctx->sort) { - ret = store_referral(ares->referral, sctx); - } else { - ret = display_referral(ares->referral, sctx); - } - if (ret) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - break; - - case LDB_REPLY_DONE: - if (ares->controls) { - if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) - sctx->pending = 1; - } - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - if (ret != LDB_SUCCESS) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -static int do_search(struct ldb_context *ldb, - struct ldb_dn *basedn, - struct ldb_cmdline *options, - const char *expression, - const char * const *attrs) -{ - struct ldb_request *req; - struct search_context *sctx; - int ret; - - req = NULL; - - sctx = talloc_zero(ldb, struct search_context); - if (!sctx) return LDB_ERR_OPERATIONS_ERROR; - - sctx->ldb = ldb; - sctx->sort = options->sorted; - sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); - if (options->controls != NULL && sctx->req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (basedn == NULL) { - basedn = ldb_get_default_basedn(ldb); - } - -again: - /* free any previous requests */ - if (req) talloc_free(req); - - ret = ldb_build_search_req(&req, ldb, ldb, - basedn, options->scope, - expression, attrs, - sctx->req_ctrls, - sctx, search_callback, - NULL); - if (ret != LDB_SUCCESS) { - talloc_free(sctx); - printf("allocating request failed: %s\n", ldb_errstring(ldb)); - return ret; - } - - sctx->pending = 0; - - ret = ldb_request(ldb, req); - if (ret != LDB_SUCCESS) { - printf("search failed - %s\n", ldb_errstring(ldb)); - return ret; - } - - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - if (ret != LDB_SUCCESS) { - printf("search error - %s\n", ldb_errstring(ldb)); - return ret; - } - - if (sctx->pending) - goto again; - - if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { - unsigned int i; - - if (sctx->num_stored) { - LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); - } - for (i = 0; i < sctx->num_stored; i++) { - display_message(sctx->store[i], sctx); - } - - for (i = 0; i < sctx->refs_stored; i++) { - display_referral(sctx->refs_store[i], sctx); - } - } - - printf("# returned %u records\n# %u entries\n# %u referrals\n", - sctx->entries + sctx->refs, sctx->entries, sctx->refs); - - talloc_free(sctx); - talloc_free(req); - - return LDB_SUCCESS; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_dn *basedn = NULL; - const char * const * attrs = NULL; - struct ldb_cmdline *options; - int ret = -1; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (!options->interactive && - options->argc > 0 && - strchr(options->argv[0], '=')) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if (basedn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - if (options->interactive) { - char line[1024]; - while (fgets(line, sizeof(line), stdin)) { - ret = do_search(ldb, basedn, options, line, attrs); - } - } else { - ret = do_search(ldb, basedn, options, expression, attrs); - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c deleted file mode 100644 index 4e181af9d55..00000000000 --- a/source4/lib/ldb/tools/ldbtest.c +++ /dev/null @@ -1,434 +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: ldbtest - * - * Description: utility to test ldb - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "tools/cmdline.h" - -static struct timespec tp1,tp2; -static struct ldb_cmdline *options; - -static void _start_timer(void) -{ - if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { - clock_gettime(CLOCK_REALTIME, &tp1); - } -} - -static double _end_timer(void) -{ - if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { - clock_gettime(CLOCK_REALTIME, &tp2); - } - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); -} - -static void add_records(struct ldb_context *ldb, - struct ldb_dn *basedn, - unsigned int count) -{ - struct ldb_message msg; - unsigned int i; - -#if 0 - if (ldb_lock(ldb, "transaction") != 0) { - printf("transaction lock failed\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } -#endif - for (i=0;icount != 1)) { - printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (uid >= nrecords && res->count > 0) { - printf("Found %s !? - %d\n", expr, ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - printf("Testing uid %d/%d - %d \r", i, uid, res->count); - fflush(stdout); - - talloc_free(res); - talloc_free(expr); - } - - printf("\n"); -} - -static void start_test(struct ldb_context *ldb, unsigned int nrecords, - unsigned int nsearches) -{ - struct ldb_dn *basedn; - - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if ( ! ldb_dn_validate(basedn)) { - printf("Invalid base DN format\n"); - exit(LDB_ERR_INVALID_DN_SYNTAX); - } - - printf("Adding %d records\n", nrecords); - add_records(ldb, basedn, nrecords); - - printf("Starting search on uid\n"); - _start_timer(); - search_uid(ldb, basedn, nrecords, nsearches); - printf("uid search took %.2f seconds\n", _end_timer()); - - printf("Modifying records\n"); - modify_records(ldb, basedn, nrecords); - - printf("Deleting records\n"); - delete_records(ldb, basedn, nrecords); -} - - -/* - 2) Store an @indexlist record - - 3) Store a record that contains fields that should be index according -to @index - - 4) disconnection from database - - 5) connect to same database - - 6) search for record added in step 3 using a search key that should -be indexed -*/ -static void start_test_index(struct ldb_context **ldb) -{ - struct ldb_message *msg; - struct ldb_result *res = NULL; - struct ldb_dn *indexlist; - struct ldb_dn *basedn; - int ret; - unsigned int flags = 0; - const char *specials; - - specials = getenv("LDB_SPECIALS"); - if (specials && atoi(specials) == 0) { - printf("LDB_SPECIALS disabled - skipping index test\n"); - return; - } - - if (options->nosync) { - flags |= LDB_FLG_NOSYNC; - } - - printf("Starting index test\n"); - - indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); - - ldb_delete(*ldb, indexlist); - - msg = ldb_msg_new(NULL); - - msg->dn = indexlist; - ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); - - if (ldb_add(*ldb, msg) != 0) { - printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - basedn = ldb_dn_new(*ldb, *ldb, options->basedn); - - memset(msg, 0, sizeof(*msg)); - msg->dn = ldb_dn_copy(msg, basedn); - ldb_dn_add_child_fmt(msg->dn, "cn=test"); - ldb_msg_add_string(msg, "cn", strdup("test")); - ldb_msg_add_string(msg, "sn", strdup("test")); - ldb_msg_add_string(msg, "uid", strdup("test")); - ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); - - if (ldb_add(*ldb, msg) != LDB_SUCCESS) { - printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (talloc_free(*ldb) != 0) { - printf("failed to free/close ldb database"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - (*ldb) = ldb_init(options, NULL); - - ret = ldb_connect(*ldb, options->url, flags, NULL); - if (ret != LDB_SUCCESS) { - printf("failed to connect to %s\n", options->url); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - basedn = ldb_dn_new(*ldb, *ldb, options->basedn); - msg->dn = basedn; - ldb_dn_add_child_fmt(msg->dn, "cn=test"); - - ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); - if (ret != LDB_SUCCESS) { - printf("Search with (uid=test) filter failed!\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if(res->count != 1) { - printf("Should have found 1 record - found %d\n", res->count); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); - - if (ldb_delete(*ldb, msg->dn) != 0 || - ldb_delete(*ldb, indexlist) != 0) { - printf("cleanup failed - %s\n", ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - printf("Finished index test\n"); -} - - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbtest \n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" --num-records nrecords database size to use\n"); - printf(" --num-searches nsearches number of searches to do\n"); - printf("\n"); - printf("tests ldb API\n\n"); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct ldb_context *ldb; - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - talloc_steal(mem_ctx, options); - - if (options->basedn == NULL) { - options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; - } - - srandom(1); - - printf("Testing with num-records=%d and num-searches=%d\n", - options->num_records, options->num_searches); - - start_test(ldb, - (unsigned int) options->num_records, - (unsigned int) options->num_searches); - - start_test_index(&ldb); - - talloc_free(mem_ctx); - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb/tools/ldbutil.c b/source4/lib/ldb/tools/ldbutil.c deleted file mode 100644 index 26f252704c1..00000000000 --- a/source4/lib/ldb/tools/ldbutil.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - ldb database library utility - - Copyright (C) Matthieu Patou 2009 - - ** 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 - * - * Description: Common function used by ldb_add/ldb_modify/ldb_delete - * - * Author: Matthieu Patou - */ - -#include "ldb.h" -#include "ldb_module.h" -#include "ldbutil.h" - - -/* autostarts a transacion if none active */ -static int ldb_do_autotransaction(struct ldb_context *ldb, - struct ldb_request *req) -{ - int ret; - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request(ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - return ldb_transaction_commit(ldb); - } - ldb_transaction_cancel(ldb); - - if (ldb_errstring(ldb) == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); - } - - return ret; -} -/* - Same as ldb_add but accept control -*/ -int ldb_add_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&req, ldb, ldb, - message, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - -/* - same as ldb_delete but accept control -*/ -int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_del_req(&req, ldb, ldb, - dn, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - same as ldb_modify, but accepts controls -*/ -int ldb_modify_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&req, ldb, ldb, - message, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - ldb_search with controls -*/ -int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - struct ldb_control **controls, - const char *exp_fmt, ...) -{ - struct ldb_request *req; - struct ldb_result *res; - char *expression; - va_list ap; - int ret; - - expression = NULL; - *result = NULL; - req = NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (exp_fmt) { - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); - - if (!expression) { - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ret = ldb_build_search_req(&req, ldb, mem_ctx, - base?base:ldb_get_default_basedn(ldb), - scope, - expression, - attrs, - controls, - res, - ldb_search_default_callback, - NULL); - ldb_req_set_location(req, "ldb_search_ctrl"); - - if (ret != LDB_SUCCESS) goto done; - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - res = NULL; - } - - talloc_free(expression); - talloc_free(req); - - *result = res; - return ret; -} diff --git a/source4/lib/ldb/tools/ldbutil.h b/source4/lib/ldb/tools/ldbutil.h deleted file mode 100644 index f8d3f3a2106..00000000000 --- a/source4/lib/ldb/tools/ldbutil.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - ldb database library utility header file - - Copyright (C) Matthieu Patou 2009 - - ** 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 - * - * Description: Common function used by ldb_add/ldb_modify/ldb_delete - * - * Author: Matthieu Patou - */ - -#include "ldb.h" - -int ldb_add_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls); -int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, - struct ldb_control **controls); -int ldb_modify_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls); -int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - struct ldb_control **controls, - const char *exp_fmt, ...); diff --git a/source4/lib/ldb/web/index.html b/source4/lib/ldb/web/index.html deleted file mode 100644 index 7f50cdc63ad..00000000000 --- a/source4/lib/ldb/web/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -ldb - - - -

ldb

- -ldb is a LDAP-like embedded database. It is not at all -LDAP -standards compliant, so if you want a standards compliant database then please -see the excellent OpenLDAP -project.

- -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.

- -ldb is the database engine used in Samba4. - -

Features

- -The main features that separate ldb from other solutions are: - -
    -
  • Safe multi-reader, multi-writer, using byte range locking -
  • LDAP-like API -
  • fast operation -
  • choice of local tdb or remote LDAP backends -
  • integration with talloc -
  • schema-less operation, for trivial setup -
  • modules for extensions (such as schema support) -
  • easy setup of indexes and attribute properties -
  • LDIF for import/export -
  • ldbedit tool for database (via LDIF) editing (reminiscent of 'vipw') -
- -

Documentation

- -Currently ldb is completely lacking in programmer or user -documentation. This is your opportunity to make a contribution! Start -with the public functions declared in ldb.h -and the example code in the tools -directory. Documentation in the same docbook format used by Samba -would be preferred. - -

Discussion and bug reports

- -ldb does not have its own mailing list or bug tracking system. Please -use -the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

Download

- -You can download the latest release here:
- http://samba.org/ftp/pub/ldb - -Alternatively, you can fetch via git. See the following guide:
-Using Git for Samba Development
- -
- -Andrew Tridgell
-ldb AT tridgell.net -
- - - diff --git a/source4/lib/ldb/wscript b/source4/lib/ldb/wscript deleted file mode 100755 index 7de95494c71..00000000000 --- a/source4/lib/ldb/wscript +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'ldb' -VERSION = '1.1.0' - -blddir = 'bin' - -import sys, os - -# find the buildtools directory -srcdir = '.' -while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: - srcdir = '../' + srcdir -sys.path.insert(0, srcdir + '/buildtools/wafsamba') - -import wafsamba, samba_dist, Options - -samba_dist.DIST_DIRS('''source4/lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc - lib/tdb:lib/tdb lib/tdb2:lib/tdb2 lib/tdb_compat:lib/tdb_compat lib/ccan:lib/ccan lib/tevent:lib/tevent lib/popt:lib/popt - buildtools:buildtools''') - - -def set_options(opt): - opt.BUILTIN_DEFAULT('replace') - opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') - opt.RECURSE('lib/tdb_compat') - opt.RECURSE('lib/tevent') - opt.RECURSE('lib/replace') - opt.tool_options('python') # options for disabling pyc or pyo compilation - -def configure(conf): - conf.RECURSE('lib/tdb_compat') - conf.RECURSE('lib/tevent') - conf.RECURSE('lib/popt') - conf.RECURSE('lib/replace') - conf.RECURSE('lib/tdb_compat') - conf.find_program('python', var='PYTHON') - conf.find_program('xsltproc', var='XSLTPROC') - conf.check_tool('python') - conf.check_python_version((2,4,2)) - conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=True) - - # This make #include work. - conf.ADD_EXTRA_INCLUDES('''#lib''') - - # where does the default LIBDIR end up? in conf.env somewhere? - # - conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') - - conf.env.standalone_ldb = conf.IN_LAUNCH_DIR() - - if not conf.env.standalone_ldb: - if conf.CHECK_BUNDLED_SYSTEM('ldb', minversion=VERSION, - onlyif='talloc tdb tevent', - implied_deps='replace talloc tdb tevent'): - conf.define('USING_SYSTEM_LDB', 1) - if conf.CHECK_BUNDLED_SYSTEM('pyldb-util', minversion=VERSION, - onlyif='talloc tdb tevent ldb', - implied_deps='replace talloc tdb tevent ldb'): - conf.define('USING_SYSTEM_PYLDB_UTIL', 1) - - if conf.env.standalone_ldb: - conf.CHECK_XSLTPROC_MANPAGES() - - # we need this for the ldap backend - if conf.CHECK_FUNCS_IN('ber_flush ldap_open ldap_initialize', 'lber ldap', headers='lber.h ldap.h'): - conf.env.ENABLE_LDAP_BACKEND = True - - conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) - - # we don't want any libraries or modules to rely on runtime - # resolution of symbols - if sys.platform != "openbsd4": - conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) - - conf.SAMBA_CONFIG_H() - -def build(bld): - bld.RECURSE('lib/tdb_compat') - bld.RECURSE('lib/tevent') - bld.RECURSE('lib/popt') - bld.RECURSE('lib/replace') - bld.RECURSE('lib/tdb_compat') - - if bld.env.standalone_ldb: - private_library = False - ldb_pc_files='ldb.pc' - pyldb_pc_files='pyldb-util.pc' - else: - private_library = True - ldb_pc_files=None - pyldb_pc_files=None - - LDB_MAP_SRC = bld.SUBDIR('ldb_map', - 'ldb_map.c ldb_map_inbound.c ldb_map_outbound.c') - - 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_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') - - bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', - init_function='ldb_ldap_init', - module_init_name='ldb_init_module', - deps='talloc lber ldap ldb', - enabled=bld.env.ENABLE_LDAP_BACKEND, - internal_module=False, - subsystem='ldb') - - # we're not currently linking against the ldap libs, but ldb.pc.in - # has @LDAP_LIBS@ - bld.env.LDAP_LIBS = '' - - if not 'PACKAGE_VERSION' in bld.env: - bld.env.PACKAGE_VERSION = VERSION - bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' - - if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): - bld.SAMBA_LIBRARY('pyldb-util', - deps='ldb pytalloc-util', - source='pyldb_util.c', - public_headers='pyldb.h', - public_headers_install=not private_library, - vnum=VERSION, - private_library=private_library, - pc_files=pyldb_pc_files, - pyext=True) - - if not bld.CONFIG_SET('USING_SYSTEM_LDB'): - if Options.is_install: - modules_dir = bld.EXPAND_VARIABLES('${LDB_MODULESDIR}') - else: - # when we run from the source directory, we want to use - # the current modules, not the installed ones - modules_dir = os.path.join(os.getcwd(), 'bin/modules/ldb') - - abi_match = '!ldb_*module_ops !ldb_*backend_ops ldb_*' - - bld.SAMBA_LIBRARY('ldb', - COMMON_SRC + ' ' + LDB_MAP_SRC, - deps='tevent LIBLDB_MAIN', - includes='include', - public_headers='include/ldb.h include/ldb_errors.h '\ - 'include/ldb_module.h include/ldb_handlers.h', - public_headers_install=not private_library, - pc_files=ldb_pc_files, - vnum=VERSION, - private_library=private_library, - manpages='man/ldb.3', - abi_directory = 'ABI', - abi_match = abi_match) - - # generate a include/ldb_version.h - t = bld.SAMBA_GENERATOR('ldb_version.h', - rule='echo "#define LDB_VERSION \\"${LDB_VERSION}\\"" > ${TGT}', - target='include/ldb_version.h', - public_headers='include/ldb_version.h', - public_headers_install=not private_library) - t.env.LDB_VERSION = VERSION - bld.add_manual_dependency(bld.path.find_or_declare('include/ldb_version.h'), VERSION) - - - - bld.SAMBA_PYTHON('pyldb', 'pyldb.c', - deps='ldb pyldb-util', - realname='ldb.so', - cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) - - bld.SAMBA_MODULE('ldb_paged_results', - 'modules/paged_results.c', - init_function='ldb_paged_results_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_asq', - 'modules/asq.c', - init_function='ldb_asq_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_server_sort', - 'modules/sort.c', - init_function='ldb_server_sort_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_paged_searches', - 'modules/paged_searches.c', - init_function='ldb_paged_searches_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_rdn_name', - 'modules/rdn_name.c', - init_function='ldb_rdn_name_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_sample', - 'tests/sample_module.c', - init_function='ldb_sample_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_skel', - 'modules/skel.c', - init_function='ldb_skel_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_sqlite3', - 'sqlite3/ldb_sqlite3.c', - init_function='ldb_sqlite3_init', - internal_module=False, - module_init_name='ldb_init_module', - enabled=False, - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_tdb', - bld.SUBDIR('ldb_tdb', - '''ldb_tdb.c ldb_pack.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', - internal_module=False, - deps='tdb_compat ldb', - subsystem='ldb') - - # have a separate subsystem for common/ldb.c, so it can rebuild - # for install with a different -DLDB_MODULESDIR= - bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', - 'common/ldb.c', - deps='tevent tdb_compat', - includes='include', - cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) - - LDB_TOOLS='ldbadd ldbsearch ldbdel ldbmodify ldbedit ldbrename' - for t in LDB_TOOLS.split(): - bld.SAMBA_BINARY(t, 'tools/%s.c' % t, deps='ldb-cmdline ldb', - manpages='man/%s.1' % t) - - # ldbtest doesn't get installed - bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', - install=False) - - bld.SAMBA_LIBRARY('ldb-cmdline', - source='tools/ldbutil.c tools/cmdline.c', - deps='ldb dl popt', - private_library=True) - - -def test(ctx): - '''run ldb testsuite''' - import Utils, samba_utils, shutil - test_prefix = "%s/st" % (Utils.g_module.blddir) - shutil.rmtree(test_prefix, ignore_errors=True) - os.makedirs(test_prefix) - os.environ['TEST_DATA_PREFIX'] = test_prefix - cmd = 'tests/test-tdb.sh' - ret = samba_utils.RUN_COMMAND(cmd) - print("testsuite returned %d" % ret) - # FIXME: Run python testsuite - sys.exit(ret) - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() - -def reconfigure(ctx): - '''reconfigure if config scripts have changed''' - import samba_utils - samba_utils.reconfigure(ctx) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 1ffc8cd74a3..518c28452b4 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -93,7 +93,7 @@ for options in ['-U"$USERNAME%$PASSWORD"']: for t in smb4torture_testsuites("ldap."): plansmbtorturetestsuite(t, "dc", '-U"$USERNAME%$PASSWORD" //$SERVER_IP/_none_') -ldbdir = os.path.join(samba4srcdir, "lib/ldb") +ldbdir = os.path.join(srcdir(), "lib/ldb") # Don't run LDB tests when using system ldb, as we won't have ldbtest installed if os.path.exists(os.path.join(samba4bindir, "ldbtest")): plantestsuite("ldb.base", "none", "%s/tests/test-tdb.sh" % ldbdir, @@ -377,7 +377,7 @@ def plansambapythontestsuite(name, env, path, module, environ={}, extra_args=[]) plantestsuite(name, env, args) -plansambapythontestsuite("ldb.python", "none", "%s/lib/ldb/tests/python/" % samba4srcdir, 'api') +plansambapythontestsuite("ldb.python", "none", "%s/lib/ldb/tests/python/" % srcdir(), 'api') planpythontestsuite("none", "samba.tests.credentials") plantestsuite_idlist("samba.tests.gensec", "dc:local", [subunitrun, "$LISTOPT", '-U"$USERNAME%$PASSWORD"', "samba.tests.gensec"]) planpythontestsuite("none", "samba.tests.registry") diff --git a/wscript b/wscript index a4fb4700872..32c1c80f73a 100755 --- a/wscript +++ b/wscript @@ -23,7 +23,7 @@ def set_options(opt): opt.PRIVATE_EXTENSION_DEFAULT('samba4') opt.RECURSE('lib/replace') opt.RECURSE('dynconfig') - opt.RECURSE('source4/lib/ldb') + opt.RECURSE('lib/ldb') opt.RECURSE('selftest') opt.RECURSE('source4/lib/tls') opt.RECURSE('lib/nss_wrapper') @@ -80,7 +80,7 @@ def configure(conf): raise Utils.WafError('Python version 3.x is not supported by Samba yet') conf.RECURSE('dynconfig') - conf.RECURSE('source4/lib/ldb') + conf.RECURSE('lib/ldb') conf.RECURSE('source4/heimdal_build') conf.RECURSE('source4/lib/tls') conf.RECURSE('source4/ntvfs/sysdep') diff --git a/wscript_build b/wscript_build index aa37c4bbc70..a7718385ffa 100644 --- a/wscript_build +++ b/wscript_build @@ -38,7 +38,7 @@ bld.RECURSE('lib/talloc') bld.RECURSE('lib/tevent') bld.RECURSE('lib/ccan') bld.RECURSE('lib/tdb_compat') -bld.RECURSE('source4/lib/ldb') +bld.RECURSE('lib/ldb') bld.RECURSE('dynconfig') bld.RECURSE('lib/util/charset') bld.RECURSE('source4/scripting/python') @@ -57,7 +57,7 @@ bld.RECURSE('nsswitch') bld.RECURSE('nsswitch/libwbclient') bld.RECURSE('source4/lib/samba3') bld.RECURSE('source4/lib/socket') -bld.RECURSE('source4/lib/ldb-samba') +bld.RECURSE('lib/ldb-samba') bld.RECURSE('source4/lib/tls') bld.RECURSE('source4/lib/registry') bld.RECURSE('source4/lib/messaging') -- cgit