summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
authorbubulle <bubulle@alioth.debian.org>2011-06-07 20:08:36 +0000
committerbubulle <bubulle@alioth.debian.org>2011-06-07 20:08:36 +0000
commit6fe9013ae23927a67fa6b6033e2711cef99b3533 (patch)
tree5018bffeace42912accb0d67ddd3893fd15b61d1 /source4/lib
parent4d16e8d5702fb98dda73c5c0f3404d662ae62df6 (diff)
downloadsamba-6fe9013ae23927a67fa6b6033e2711cef99b3533.tar.gz
Load samba-3.6.0rc2 into branches/samba/upstream.
git-svn-id: svn://svn.debian.org/svn/pkg-samba/branches/samba/upstream@3807 fc4039ab-9d04-0410-8cac-899223bdd6b0
Diffstat (limited to 'source4/lib')
-rw-r--r--source4/lib/basic.mk26
-rw-r--r--source4/lib/cmdline/config.mk21
-rw-r--r--source4/lib/cmdline/popt_common.c30
-rw-r--r--source4/lib/cmdline/popt_credentials.c49
-rw-r--r--source4/lib/cmdline/wscript_build23
-rw-r--r--source4/lib/com/config.mk22
-rw-r--r--source4/lib/com/dcom/main.c6
-rw-r--r--source4/lib/com/main.c2
-rw-r--r--source4/lib/com/pycom.c6
-rw-r--r--source4/lib/com/wscript_build33
-rw-r--r--source4/lib/events/config.mk5
-rw-r--r--source4/lib/events/events.h3
-rw-r--r--source4/lib/events/tevent_s4.c17
-rw-r--r--source4/lib/events/wscript_build9
-rw-r--r--source4/lib/ldb-samba/config.mk11
-rw-r--r--source4/lib/ldb-samba/ldb_ildap.c (renamed from source4/lib/ldb/ldb_ildap/ldb_ildap.c)88
-rw-r--r--source4/lib/ldb-samba/ldb_wrap.c368
-rw-r--r--source4/lib/ldb-samba/ldb_wrap.h (renamed from source4/lib/ldb_wrap.h)31
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.c723
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.h5
-rw-r--r--source4/lib/ldb-samba/pyldb.c270
-rw-r--r--source4/lib/ldb-samba/samba_extensions.c119
-rw-r--r--source4/lib/ldb-samba/wscript_build42
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.10.sigs218
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.12.sigs219
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.15.sigs226
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.16.sigs228
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.17.sigs229
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.18.sigs240
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.19.sigs245
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.20.sigs245
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.22.sigs245
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.23.sigs247
-rw-r--r--source4/lib/ldb/ABI/ldb-0.9.24.sigs248
-rw-r--r--source4/lib/ldb/ABI/ldb-1.0.0.sigs248
-rw-r--r--source4/lib/ldb/ABI/ldb-1.0.1.sigs248
-rw-r--r--source4/lib/ldb/ABI/ldb-1.0.2.sigs250
-rw-r--r--source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs224
-rw-r--r--source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs223
-rw-r--r--source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs224
-rw-r--r--source4/lib/ldb/Makefile51
-rw-r--r--source4/lib/ldb/Makefile.in187
-rw-r--r--source4/lib/ldb/aclocal.m41
-rwxr-xr-xsource4/lib/ldb/autogen.sh16
-rw-r--r--source4/lib/ldb/build_macros.m415
-rw-r--r--source4/lib/ldb/common/attrib_handlers.c96
-rw-r--r--source4/lib/ldb/common/ldb.c284
-rw-r--r--source4/lib/ldb/common/ldb_attributes.c18
-rw-r--r--source4/lib/ldb/common/ldb_controls.c1285
-rw-r--r--source4/lib/ldb/common/ldb_dn.c448
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c21
-rw-r--r--source4/lib/ldb/common/ldb_match.c334
-rw-r--r--source4/lib/ldb/common/ldb_modules.c699
-rw-r--r--source4/lib/ldb/common/ldb_msg.c378
-rw-r--r--source4/lib/ldb/common/ldb_options.c72
-rw-r--r--source4/lib/ldb/common/ldb_parse.c73
-rw-r--r--source4/lib/ldb/common/ldb_utf8.c12
-rwxr-xr-xsource4/lib/ldb/config.guess1561
-rw-r--r--source4/lib/ldb/config.mk139
-rwxr-xr-xsource4/lib/ldb/config.sub1686
-rwxr-xr-xsource4/lib/ldb/configure21
-rw-r--r--source4/lib/ldb/configure.ac102
-rw-r--r--source4/lib/ldb/external/libevents.m47
-rw-r--r--source4/lib/ldb/external/libpopt.m47
-rw-r--r--source4/lib/ldb/external/libtalloc.m48
-rw-r--r--source4/lib/ldb/external/libtdb.m47
-rw-r--r--source4/lib/ldb/external/pkg.m4156
-rw-r--r--source4/lib/ldb/include/dlinklist.h190
-rw-r--r--source4/lib/ldb/include/ldb.h329
-rw-r--r--source4/lib/ldb/include/ldb_errors.h2
-rw-r--r--source4/lib/ldb/include/ldb_handlers.h2
-rw-r--r--source4/lib/ldb/include/ldb_includes.h18
-rw-r--r--source4/lib/ldb/include/ldb_module.h168
-rw-r--r--source4/lib/ldb/include/ldb_private.h30
-rwxr-xr-xsource4/lib/ldb/install-sh238
-rw-r--r--source4/lib/ldb/ldap.m490
-rw-r--r--source4/lib/ldb/ldb.mk81
-rw-r--r--source4/lib/ldb/ldb.pc.in2
-rw-r--r--source4/lib/ldb/ldb_ildap/config.mk13
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c163
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map.c80
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map.h30
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_inbound.c51
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_outbound.c111
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_private.h7
-rw-r--r--source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c77
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c49
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c1670
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_pack.c3
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c66
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c739
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h28
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c18
-rw-r--r--source4/lib/ldb/libldb.m47
-rw-r--r--source4/lib/ldb/man/ad2oLschema.1.xml87
-rw-r--r--source4/lib/ldb/man/ldbadd.1.xml6
-rw-r--r--source4/lib/ldb/man/ldbdel.1.xml6
-rw-r--r--source4/lib/ldb/man/ldbedit.1.xml2
-rw-r--r--source4/lib/ldb/man/ldbmodify.1.xml4
-rw-r--r--source4/lib/ldb/man/ldbrename.1.xml4
-rw-r--r--source4/lib/ldb/man/ldbsearch.1.xml4
-rw-r--r--source4/lib/ldb/man/oLschema2ldif.1.xml79
-rw-r--r--source4/lib/ldb/modules/asq.c26
-rw-r--r--source4/lib/ldb/modules/paged_results.c30
-rw-r--r--source4/lib/ldb/modules/paged_searches.c20
-rw-r--r--source4/lib/ldb/modules/rdn_name.c227
-rw-r--r--source4/lib/ldb/modules/skel.c15
-rw-r--r--source4/lib/ldb/modules/sort.c32
-rw-r--r--source4/lib/ldb/nssldb/ldb-nss.c4
-rw-r--r--source4/lib/ldb/pyldb-util.pc.in13
-rw-r--r--source4/lib/ldb/pyldb.c1224
-rw-r--r--source4/lib/ldb/pyldb.h37
-rw-r--r--source4/lib/ldb/pyldb_util.c119
-rw-r--r--source4/lib/ldb/python.mk6
-rw-r--r--source4/lib/ldb/rules.mk26
-rw-r--r--source4/lib/ldb/sqlite3.m462
-rwxr-xr-xsource4/lib/ldb/standalone.sh28
-rw-r--r--source4/lib/ldb/tests/photo.ldif2
-rwxr-xr-xsource4/lib/ldb/tests/python/api.py225
-rwxr-xr-xsource4/lib/ldb/tests/python/ldap.py1540
-rwxr-xr-xsource4/lib/ldb/tests/python/sec_descriptor.py1615
-rw-r--r--source4/lib/ldb/tests/sample_module.c41
-rwxr-xr-xsource4/lib/ldb/tests/test-controls.sh45
-rwxr-xr-xsource4/lib/ldb/tests/test-generic.sh5
-rwxr-xr-xsource4/lib/ldb/tests/test-schema.sh4
-rwxr-xr-xsource4/lib/ldb/tests/test-tdb.sh2
-rw-r--r--source4/lib/ldb/tests/test.ldif6
-rw-r--r--source4/lib/ldb/tools/cmdline.c198
-rw-r--r--source4/lib/ldb/tools/cmdline.h11
-rw-r--r--source4/lib/ldb/tools/config.mk90
-rw-r--r--source4/lib/ldb/tools/ldbadd.c72
-rw-r--r--source4/lib/ldb/tools/ldbdel.c75
-rw-r--r--source4/lib/ldb/tools/ldbedit.c142
-rw-r--r--source4/lib/ldb/tools/ldbmodify.c49
-rw-r--r--source4/lib/ldb/tools/ldbrename.c28
-rw-r--r--source4/lib/ldb/tools/ldbsearch.c69
-rw-r--r--source4/lib/ldb/tools/ldbtest.c85
-rw-r--r--source4/lib/ldb/tools/ldbutil.c219
-rw-r--r--source4/lib/ldb/tools/ldbutil.h46
-rw-r--r--source4/lib/ldb/web/index.html30
-rwxr-xr-xsource4/lib/ldb/wscript276
-rw-r--r--source4/lib/ldb_wrap.c196
-rw-r--r--source4/lib/messaging/config.mk18
-rw-r--r--source4/lib/messaging/irpc.h83
-rw-r--r--source4/lib/messaging/messaging.c526
-rw-r--r--source4/lib/messaging/messaging.h26
-rw-r--r--source4/lib/messaging/pymessaging.c338
-rw-r--r--source4/lib/messaging/tests/bindings.py57
-rw-r--r--source4/lib/messaging/tests/irpc.c85
-rw-r--r--source4/lib/messaging/tests/messaging.c11
-rw-r--r--source4/lib/messaging/wscript_build15
-rw-r--r--source4/lib/policy/gp_filesys.c647
-rw-r--r--source4/lib/policy/gp_ini.c133
-rw-r--r--source4/lib/policy/gp_ldap.c1038
-rw-r--r--source4/lib/policy/gp_manage.c295
-rw-r--r--source4/lib/policy/policy.h127
-rw-r--r--source4/lib/policy/policy.pc.in12
-rw-r--r--source4/lib/policy/pypolicy.c133
-rw-r--r--source4/lib/policy/tests/python/bindings.py35
-rw-r--r--source4/lib/policy/wscript_build15
-rw-r--r--source4/lib/registry/config.mk110
-rw-r--r--source4/lib/registry/dir.c77
-rw-r--r--source4/lib/registry/hive.c12
-rw-r--r--source4/lib/registry/interface.c20
-rw-r--r--source4/lib/registry/ldb.c517
-rw-r--r--source4/lib/registry/local.c145
-rw-r--r--source4/lib/registry/man/regdiff.1.xml2
-rw-r--r--source4/lib/registry/man/regpatch.1.xml2
-rw-r--r--source4/lib/registry/man/regshell.1.xml2
-rw-r--r--source4/lib/registry/man/regtree.1.xml2
-rw-r--r--source4/lib/registry/patchfile.c94
-rw-r--r--source4/lib/registry/patchfile_dotreg.c269
-rw-r--r--source4/lib/registry/patchfile_preg.c75
-rw-r--r--source4/lib/registry/pyregistry.c151
-rw-r--r--source4/lib/registry/regf.c315
-rw-r--r--source4/lib/registry/regf.idl6
-rw-r--r--source4/lib/registry/registry.h53
-rw-r--r--source4/lib/registry/registry.pc.in4
-rw-r--r--source4/lib/registry/rpc.c71
-rw-r--r--source4/lib/registry/samba.c5
-rw-r--r--source4/lib/registry/tests/bindings.py57
-rw-r--r--source4/lib/registry/tests/diff.c30
-rw-r--r--source4/lib/registry/tests/generic.c72
-rw-r--r--source4/lib/registry/tests/hive.c87
-rw-r--r--source4/lib/registry/tests/registry.c19
-rw-r--r--source4/lib/registry/tools/regdiff.c3
-rw-r--r--source4/lib/registry/tools/regpatch.c2
-rw-r--r--source4/lib/registry/tools/regshell.c44
-rw-r--r--source4/lib/registry/tools/regtree.c16
-rw-r--r--source4/lib/registry/util.c199
-rw-r--r--source4/lib/registry/wscript_build69
-rw-r--r--source4/lib/samba3/config.mk8
-rw-r--r--source4/lib/samba3/wscript_build9
-rw-r--r--source4/lib/smbreadline/readline.m491
-rw-r--r--source4/lib/smbreadline/smbreadline.c171
-rw-r--r--source4/lib/smbreadline/smbreadline.h9
-rw-r--r--source4/lib/socket/access.c1
-rw-r--r--source4/lib/socket/config.m418
-rw-r--r--source4/lib/socket/config.mk43
-rw-r--r--source4/lib/socket/connect_multi.c48
-rw-r--r--source4/lib/socket/interface.c3
-rw-r--r--source4/lib/socket/netif.c3
-rw-r--r--source4/lib/socket/socket.c84
-rw-r--r--source4/lib/socket/socket.h11
-rw-r--r--source4/lib/socket/socket_ip.c3
-rw-r--r--source4/lib/socket/testsuite.c7
-rw-r--r--source4/lib/socket/wscript_build29
-rw-r--r--source4/lib/stream/config.mk4
-rw-r--r--source4/lib/stream/packet.c10
-rw-r--r--source4/lib/stream/packet.h1
-rw-r--r--source4/lib/stream/wscript_build8
-rw-r--r--source4/lib/tdb_wrap.c117
-rw-r--r--source4/lib/tdb_wrap.h38
-rw-r--r--source4/lib/tls/config.m445
-rw-r--r--source4/lib/tls/config.mk5
-rw-r--r--source4/lib/tls/tls.c15
-rw-r--r--source4/lib/tls/tls.h48
-rw-r--r--source4/lib/tls/tls_tstream.c1354
-rw-r--r--source4/lib/tls/tlscert.c15
-rw-r--r--source4/lib/tls/wscript53
-rw-r--r--source4/lib/wmi/config.mk69
-rw-r--r--source4/lib/wmi/tools/wmic.c163
-rw-r--r--source4/lib/wmi/wscript_build26
-rw-r--r--source4/lib/wscript_build7
-rw-r--r--source4/lib/zlib.mk16
225 files changed, 19624 insertions, 14026 deletions
diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk
deleted file mode 100644
index 4b40ed41d4..0000000000
--- a/source4/lib/basic.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-[SUBSYSTEM::LZXPRESS]
-
-LZXPRESS_OBJ_FILES = $(libcompressionsrcdir)/lzxpress.o
-
-[SUBSYSTEM::GENCACHE]
-PRIVATE_DEPENDENCIES = TDB_WRAP
-
-GENCACHE_OBJ_FILES = $(libgencachesrcdir)/gencache.o
-
-# PUBLIC_HEADERS += $(libgencachesrcdir)/gencache.h
-
-[SUBSYSTEM::LDB_WRAP]
-PUBLIC_DEPENDENCIES = LIBLDB
-PRIVATE_DEPENDENCIES = LDBSAMBA UTIL_LDB
-
-LDB_WRAP_OBJ_FILES = $(libsrcdir)/ldb_wrap.o
-PUBLIC_HEADERS += $(libsrcdir)/ldb_wrap.h
-
-[SUBSYSTEM::TDB_WRAP]
-PUBLIC_DEPENDENCIES = LIBTDB
-
-TDB_WRAP_OBJ_FILES = $(libsrcdir)/tdb_wrap.o
-PUBLIC_HEADERS += $(libsrcdir)/tdb_wrap.h
-
-SMBREADLINE_OBJ_LIST = $(SMBREADLINE_OBJ_FILES)
-
diff --git a/source4/lib/cmdline/config.mk b/source4/lib/cmdline/config.mk
deleted file mode 100644
index 4434ff3701..0000000000
--- a/source4/lib/cmdline/config.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-[SUBSYSTEM::LIBCMDLINE_CREDENTIALS]
-PUBLIC_DEPENDENCIES = CREDENTIALS LIBPOPT
-
-LIBCMDLINE_CREDENTIALS_OBJ_FILES = $(libcmdlinesrcdir)/credentials.o
-
-$(eval $(call proto_header_template,$(libcmdlinesrcdir)/credentials.h,$(LIBCMDLINE_CREDENTIALS_OBJ_FILES:.o=.c)))
-
-[SUBSYSTEM::POPT_SAMBA]
-PUBLIC_DEPENDENCIES = LIBPOPT
-
-POPT_SAMBA_OBJ_FILES = $(libcmdlinesrcdir)/popt_common.o
-
-PUBLIC_HEADERS += $(libcmdlinesrcdir)/popt_common.h
-
-[SUBSYSTEM::POPT_CREDENTIALS]
-PUBLIC_DEPENDENCIES = CREDENTIALS LIBCMDLINE_CREDENTIALS LIBPOPT
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL
-
-POPT_CREDENTIALS_OBJ_FILES = $(libcmdlinesrcdir)/popt_credentials.o
-
-$(eval $(call proto_header_template,$(libcmdlinesrcdir)/popt_credentials.h,$(POPT_CREDENTIALS_OBJ_FILES:.o=.c)))
diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c
index 0273c4fe1c..76c6fb23a1 100644
--- a/source4/lib/cmdline/popt_common.c
+++ b/source4/lib/cmdline/popt_common.c
@@ -66,8 +66,8 @@ static void popt_samba_callback(poptContext con,
const char *pname;
if (reason == POPT_CALLBACK_REASON_POST) {
- if (lp_configfile(cmdline_lp_ctx) == NULL) {
- lp_load_default(cmdline_lp_ctx);
+ if (lpcfg_configfile(cmdline_lp_ctx) == NULL) {
+ lpcfg_load_default(cmdline_lp_ctx);
}
/* Hook any 'every Samba program must do this, after
* the smb.conf is setup' functions here */
@@ -83,7 +83,7 @@ static void popt_samba_callback(poptContext con,
pname++;
if (reason == POPT_CALLBACK_REASON_PRE) {
- cmdline_lp_ctx = loadparm_init(talloc_autofree_context());
+ cmdline_lp_ctx = loadparm_init_global(false);
/* Hook for 'almost the first thing to do in a samba program' here */
/* setup for panics */
@@ -108,14 +108,14 @@ static void popt_samba_callback(poptContext con,
break;
case OPT_OPTION:
- if (!lp_set_option(cmdline_lp_ctx, arg)) {
+ if (!lpcfg_set_option(cmdline_lp_ctx, arg)) {
fprintf(stderr, "Error setting option '%s'\n", arg);
exit(1);
}
break;
case 'd':
- lp_set_cmdline(cmdline_lp_ctx, "log level", arg);
+ lpcfg_set_cmdline(cmdline_lp_ctx, "log level", arg);
break;
case OPT_DEBUG_STDERR:
@@ -124,14 +124,14 @@ static void popt_samba_callback(poptContext con,
case 's':
if (arg) {
- lp_load(cmdline_lp_ctx, arg);
+ lpcfg_load(cmdline_lp_ctx, arg);
}
break;
case 'l':
if (arg) {
char *new_logfile = talloc_asprintf(NULL, "%s/log.%s", arg, pname);
- lp_set_cmdline(cmdline_lp_ctx, "log file", new_logfile);
+ lpcfg_set_cmdline(cmdline_lp_ctx, "log file", new_logfile);
talloc_free(new_logfile);
}
break;
@@ -152,36 +152,36 @@ static void popt_common_callback(poptContext con,
switch(opt->val) {
case 'O':
if (arg) {
- lp_set_cmdline(lp_ctx, "socket options", arg);
+ lpcfg_set_cmdline(lp_ctx, "socket options", arg);
}
break;
case 'W':
- lp_set_cmdline(lp_ctx, "workgroup", arg);
+ lpcfg_set_cmdline(lp_ctx, "workgroup", arg);
break;
case 'r':
- lp_set_cmdline(lp_ctx, "realm", arg);
+ lpcfg_set_cmdline(lp_ctx, "realm", arg);
break;
case 'n':
- lp_set_cmdline(lp_ctx, "netbios name", arg);
+ lpcfg_set_cmdline(lp_ctx, "netbios name", arg);
break;
case 'i':
- lp_set_cmdline(lp_ctx, "netbios scope", arg);
+ lpcfg_set_cmdline(lp_ctx, "netbios scope", arg);
break;
case 'm':
- lp_set_cmdline(lp_ctx, "client max protocol", arg);
+ lpcfg_set_cmdline(lp_ctx, "client max protocol", arg);
break;
case 'R':
- lp_set_cmdline(lp_ctx, "name resolve order", arg);
+ lpcfg_set_cmdline(lp_ctx, "name resolve order", arg);
break;
case 'S':
- lp_set_cmdline(lp_ctx, "client signing", arg);
+ lpcfg_set_cmdline(lp_ctx, "client signing", arg);
break;
}
diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c
index 42ecac1eaa..11f4036e3f 100644
--- a/source4/lib/cmdline/popt_credentials.c
+++ b/source4/lib/cmdline/popt_credentials.c
@@ -31,15 +31,15 @@
* -k,--use-kerberos
* -N,--no-pass
* -S,--signing
- * -P --machine-pass
- * --simple-bind-dn
- * --password
+ * -P,--machine-pass
+ * --simple-bind-dn
+ * --password
*/
-
static bool dont_ask;
+static bool machine_account_pending;
-enum opt { OPT_SIMPLE_BIND_DN, OPT_PASSWORD, OPT_KERBEROS };
+enum opt { OPT_SIMPLE_BIND_DN, OPT_PASSWORD, OPT_KERBEROS, OPT_SIGN, OPT_ENCRYPT };
/*
disable asking for a password
@@ -65,7 +65,13 @@ static void popt_common_credentials_callback(poptContext con,
if (!dont_ask) {
cli_credentials_set_cmdline_callbacks(cmdline_credentials);
}
+
+ if (machine_account_pending) {
+ cli_credentials_set_machine_account(cmdline_credentials, cmdline_lp_ctx);
+ }
+
return;
+
}
switch(opt->val) {
@@ -96,7 +102,7 @@ static void popt_common_credentials_callback(poptContext con,
case 'P':
/* Later, after this is all over, get the machine account details from the secrets.ldb */
- cli_credentials_set_machine_account_pending(cmdline_credentials, cmdline_lp_ctx);
+ machine_account_pending = true;
break;
case OPT_KERBEROS:
@@ -105,7 +111,8 @@ static void popt_common_credentials_callback(poptContext con,
/* Force us to only use kerberos */
if (arg) {
if (!set_boolean(arg, &use_kerberos)) {
- fprintf(stderr, "Error parsing -k %s\n", arg);
+ fprintf(stderr, "Error parsing -k %s. Should be "
+ "-k [yes|no]\n", arg);
exit(1);
break;
}
@@ -119,9 +126,33 @@ static void popt_common_credentials_callback(poptContext con,
}
case OPT_SIMPLE_BIND_DN:
+ {
cli_credentials_set_bind_dn(cmdline_credentials, arg);
break;
}
+ case OPT_SIGN:
+ {
+ uint32_t gensec_features;
+
+ gensec_features = cli_credentials_get_gensec_features(cmdline_credentials);
+
+ gensec_features |= GENSEC_FEATURE_SIGN;
+ cli_credentials_set_gensec_features(cmdline_credentials,
+ gensec_features);
+ break;
+ }
+ case OPT_ENCRYPT:
+ {
+ uint32_t gensec_features;
+
+ gensec_features = cli_credentials_get_gensec_features(cmdline_credentials);
+
+ gensec_features |= GENSEC_FEATURE_SEAL;
+ cli_credentials_set_gensec_features(cmdline_credentials,
+ gensec_features);
+ break;
+ }
+ }
}
@@ -134,6 +165,8 @@ struct poptOption popt_common_credentials[] = {
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
{ "machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password (implies -k)" },
{ "simple-bind-dn", 0, POPT_ARG_STRING, NULL, OPT_SIMPLE_BIND_DN, "DN to use for a simple bind" },
- { "kerberos", 'k', POPT_ARG_STRING, NULL, OPT_KERBEROS, "Use Kerberos" },
+ { "kerberos", 'k', POPT_ARG_STRING, NULL, OPT_KERBEROS, "Use Kerberos, -k [yes|no]" },
+ { "sign", 'S', POPT_ARG_NONE, NULL, OPT_SIGN, "Sign connection to prevent modification in transit" },
+ { "encrypt", 'e', POPT_ARG_NONE, NULL, OPT_ENCRYPT, "Encrypt connection for privacy" },
{ NULL }
};
diff --git a/source4/lib/cmdline/wscript_build b/source4/lib/cmdline/wscript_build
new file mode 100644
index 0000000000..c55c808703
--- /dev/null
+++ b/source4/lib/cmdline/wscript_build
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('cmdline-credentials',
+ source='credentials.c',
+ autoproto='credentials.h',
+ public_deps='credentials popt',
+ private_library=True)
+
+bld.SAMBA_SUBSYSTEM('POPT_SAMBA',
+ source='popt_common.c',
+ public_deps='popt',
+ public_headers='popt_common.h:popt.h',
+ header_path='samba',
+ deps='talloc samba-hostconfig'
+ )
+
+bld.SAMBA_SUBSYSTEM('POPT_CREDENTIALS',
+ source='popt_credentials.c',
+ autoproto='popt_credentials.h',
+ public_deps='credentials CREDENTIALS_SECRETS cmdline-credentials popt',
+ deps='samba-util'
+ )
+
diff --git a/source4/lib/com/config.mk b/source4/lib/com/config.mk
deleted file mode 100644
index 73836ef5f8..0000000000
--- a/source4/lib/com/config.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-[SUBSYSTEM::COM]
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG LIBEVENTS LIBNDR
-
-COM_OBJ_FILES = $(addprefix $(comsrcdir)/, tables.o rot.o main.o)
-
-[SUBSYSTEM::DCOM]
-PUBLIC_DEPENDENCIES = COM DCOM_PROXY_DCOM RPC_NDR_REMACT \
- RPC_NDR_OXIDRESOLVER
-
-DCOM_OBJ_FILES = $(addprefix $(comsrcdir)/dcom/, main.o tables.o)
-
-[MODULE::com_simple]
-SUBSYSTEM = COM
-INIT_FUNCTION = com_simple_init
-
-com_simple_OBJ_FILES = $(comsrcdir)/classes/simple.o
-
-[PYTHON::pycom]
-LIBRARY_REALNAME = samba/com.$(SHLIBEXT)
-PRIVATE_DEPENDENCIES = COM
-
-pycom_OBJ_FILES = $(comsrcdir)/pycom.o
diff --git a/source4/lib/com/dcom/main.c b/source4/lib/com/dcom/main.c
index 695bfa7f98..b205cb48a8 100644
--- a/source4/lib/com/dcom/main.c
+++ b/source4/lib/com/dcom/main.c
@@ -171,7 +171,7 @@ static NTSTATUS dcom_connect_host(struct com_context *ctx,
if (server == NULL) {
return dcerpc_pipe_connect(ctx->event_ctx, p, "ncalrpc",
&ndr_table_IRemoteActivation,
- dcom_get_server_credentials(ctx, NULL), ctx->event_ctx, ctx->lp_ctx);
+ dcom_get_server_credentials(ctx, NULL), ctx->event_ctx, ctx->lp_ctx);
}
loc_ctx = talloc_new(ctx);
@@ -182,7 +182,7 @@ static NTSTATUS dcom_connect_host(struct com_context *ctx,
bd->flags |= DCERPC_DEBUG_PRINT_BOTH;
status = dcerpc_pipe_connect_b(ctx->event_ctx, p, bd,
&ndr_table_IRemoteActivation,
- dcom_get_server_credentials(ctx, bd->host), ctx->event_ctx, ctx->lp_ctx);
+ dcom_get_server_credentials(ctx, bd->host), ctx->event_ctx, ctx->lp_ctx);
goto end;
}
@@ -704,7 +704,7 @@ void dcom_proxy_async_call_recv_pipe_send_rpc(struct composite_context *c_pipe)
composite_error(c, NT_STATUS_RPC_NT_CALL_FAILED);
return;
}
-
+/*TODO: FIXME - for now this unused anyway */
req = dcerpc_ndr_request_send(p, &s->d->obj.u_objref.u_standard.std.ipid, s->table, s->opnum, s, s->r);
composite_continue_rpc(c, req, s->continuation, c);
}
diff --git a/source4/lib/com/main.c b/source4/lib/com/main.c
index 062d1360ac..487ed5b712 100644
--- a/source4/lib/com/main.c
+++ b/source4/lib/com/main.c
@@ -52,7 +52,7 @@ WERROR com_create_object(struct com_context *ctx, struct GUID *clsid, int num_if
}
/* Run IClassFactory::CreateInstance() */
- error = IClassFactory_CreateInstance(factory, ctx, NULL, &classfact_iid, &iunk);
+ error = IClassFactory_CreateInstance(factory, ctx, NULL, &classfact_iid, (struct MInterfacePointer *) &iunk);
if (!W_ERROR_IS_OK(error)) {
DEBUG(3, ("Error while calling IClassFactory::CreateInstance : %s\n", win_errstr(error)));
return error;
diff --git a/source4/lib/com/pycom.c b/source4/lib/com/pycom.c
index d5a07580ea..3323ca645e 100644
--- a/source4/lib/com/pycom.c
+++ b/source4/lib/com/pycom.c
@@ -17,16 +17,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
#include <Python.h>
+#include "includes.h"
#include "lib/com/com.h"
#include "librpc/ndr/libndr.h"
#include "libcli/util/pyerrors.h"
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
static struct com_context *py_com_ctx = NULL; /* FIXME: evil global */
static PyObject *py_get_class_object(PyObject *self, PyObject *args)
diff --git a/source4/lib/com/wscript_build b/source4/lib/com/wscript_build
new file mode 100644
index 0000000000..2794d6623b
--- /dev/null
+++ b/source4/lib/com/wscript_build
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+bld.SAMBA_SUBSYSTEM('COM',
+ source='tables.c rot.c main.c',
+ deps='samba-util samba-hostconfig events ndr NDR_DCOM'
+ )
+
+
+bld.SAMBA_SUBSYSTEM('DCOM',
+ source='dcom/main.c dcom/tables.c',
+ public_deps='COM DCOM_PROXY_DCOM RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER',
+ # ORPCTHIS maps to this.*, which hits the "No C++ keywords" define
+ # unless we force off developer mode
+ cflags_end = '-UDEVELOPER',
+ # even with the above hack this still doesn't compile - disable it for now
+ enabled=False
+ )
+
+
+bld.SAMBA_MODULE('com_simple',
+ source='classes/simple.c',
+ deps='talloc',
+ subsystem='COM',
+ init_function='com_simple_init'
+ )
+
+
+bld.SAMBA_PYTHON('pycom',
+ source='pycom.c',
+ deps='COM',
+ realname='samba/com.so',
+ )
+
diff --git a/source4/lib/events/config.mk b/source4/lib/events/config.mk
deleted file mode 100644
index 5c7e1b7210..0000000000
--- a/source4/lib/events/config.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-[SUBSYSTEM::LIBEVENTS]
-PUBLIC_DEPENDENCIES = LIBTEVENT
-CFLAGS = -Ilib/events
-
-LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, tevent_s4.o)
diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h
index 1b2dbde32b..f66698838d 100644
--- a/source4/lib/events/events.h
+++ b/source4/lib/events/events.h
@@ -1,7 +1,8 @@
#ifndef __LIB_EVENTS_H__
#define __LIB_EVENTS_H__
#define TEVENT_COMPAT_DEFINES 1
-#include <../lib/tevent/tevent.h>
+#include <tevent.h>
struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx);
struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx) _DEPRECATED_;
+void s4_event_context_set_default(struct tevent_context *ev);
#endif /* __LIB_EVENTS_H__ */
diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c
index 1898269c2c..469ed72ee7 100644
--- a/source4/lib/events/tevent_s4.c
+++ b/source4/lib/events/tevent_s4.c
@@ -71,20 +71,3 @@ struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
return ev;
}
-/*
- find an event context that is a parent of the given memory context,
- or create a new event context as a child of the given context if
- none is found
-
- This should be used in preference to event_context_init() in places
- where you would prefer to use the existing event context if possible
- (which is most situations)
-*/
-struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx)
-{
- struct tevent_context *ev = talloc_find_parent_bytype(mem_ctx, struct tevent_context);
- if (ev == NULL) {
- ev = tevent_context_init(mem_ctx);
- }
- return ev;
-}
diff --git a/source4/lib/events/wscript_build b/source4/lib/events/wscript_build
new file mode 100644
index 0000000000..d08d5dda0e
--- /dev/null
+++ b/source4/lib/events/wscript_build
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+
+bld.SAMBA_LIBRARY('events',
+ source='tevent_s4.c',
+ deps='samba-util',
+ public_deps='tevent',
+ private_library=True
+ )
diff --git a/source4/lib/ldb-samba/config.mk b/source4/lib/ldb-samba/config.mk
deleted file mode 100644
index ceacf277e4..0000000000
--- a/source4/lib/ldb-samba/config.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-################################################
-# Start SUBSYSTEM LDBSAMBA
-[SUBSYSTEM::LDBSAMBA]
-PUBLIC_DEPENDENCIES = LIBLDB
-PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_DRSBLOBS
-# End SUBSYSTEM LDBSAMBA
-################################################
-
-LDBSAMBA_OBJ_FILES = $(ldb_sambasrcdir)/ldif_handlers.o
-$(eval $(call proto_header_template,$(ldb_sambasrcdir)/ldif_handlers_proto.h,$(LDBSAMBA_OBJ_FILES:.o=.c)))
-
diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb-samba/ldb_ildap.c
index ffde048223..3c28690bd6 100644
--- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c
+++ b/source4/lib/ldb-samba/ldb_ildap.c
@@ -35,16 +35,16 @@
*
* Modifications:
*
- * - description: make the module use asyncronous calls
+ * - description: make the module use asynchronous calls
* date: Feb 2006
* author: Simo Sorce
*/
#include "includes.h"
#include "ldb_module.h"
-#include "dlinklist.h"
+#include "util/dlinklist.h"
-#include "libcli/ldap/ldap.h"
+#include "libcli/ldap/libcli_ldap.h"
#include "libcli/ldap/ldap_client.h"
#include "auth/auth.h"
#include "auth/credentials/credentials.h"
@@ -61,6 +61,10 @@ struct ildb_context {
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;
@@ -223,6 +227,13 @@ static void ildb_callback(struct ldap_request *req)
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);
@@ -322,11 +333,12 @@ static void ildb_callback(struct ldap_request *req)
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:
@@ -337,6 +349,7 @@ static void ildb_callback(struct ldap_request *req)
if (ret != LDB_SUCCESS) {
callback_failed = true;
}
+
break;
default:
@@ -370,9 +383,13 @@ static void ildb_callback(struct ldap_request *req)
}
}
+ /* mark the request as not being in progress */
+ ac->in_ildb_callback = false;
+
if (request_done) {
ildb_request_done(ac, controls, ret);
}
+
return;
}
@@ -387,12 +404,14 @@ static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg)
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_steal(ac, req);
+ ac->ireq = talloc_reparent(ac->ildb->ldap, ac, req);
if (!ac->ireq->conn) {
ldb_set_errstring(ldb, "connection to remote LDAP server dropped?");
@@ -513,6 +532,7 @@ static int ildb_add(struct ildb_context *ac)
for (i = 0; i < n; i++) {
msg->r.AddRequest.attributes[i] = mods[i]->attrib;
}
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
@@ -556,7 +576,7 @@ static int ildb_modify(struct ildb_context *ac)
for (i = 0; i < n; i++) {
msg->r.ModifyRequest.mods[i] = *mods[i];
}
-
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
@@ -580,6 +600,7 @@ static int ildb_delete(struct ildb_context *ac)
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
}
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
@@ -591,6 +612,8 @@ 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) {
@@ -604,10 +627,16 @@ static int ildb_rename(struct ildb_context *ac)
return LDB_ERR_INVALID_DN_SYNTAX;
}
- msg->r.ModifyDNRequest.newrdn =
- talloc_asprintf(msg, "%s=%s",
- ldb_dn_get_rdn_name(req->op.rename.newdn),
- ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn)));
+ 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;
@@ -621,6 +650,7 @@ static int ildb_rename(struct ildb_context *ac)
}
msg->r.ModifyDNRequest.deleteolddn = true;
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
@@ -729,7 +759,7 @@ static int ildb_handle_request(struct ldb_module *module, struct ldb_request *re
break;
default:
/* no other op supported */
- ret = LDB_ERR_OPERATIONS_ERROR;
+ ret = LDB_ERR_PROTOCOL_ERROR;
break;
}
@@ -763,7 +793,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
struct loadparm_context *lp_ctx;
module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops);
- if (!module) return -1;
+ if (!module) return LDB_ERR_OPERATIONS_ERROR;
ildb = talloc(module, struct ildb_private);
if (!ildb) {
@@ -825,25 +855,25 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
}
*_module = module;
- return 0;
+ return LDB_SUCCESS;
failed:
talloc_free(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
-_PUBLIC_ const struct ldb_backend_ops ldb_ldap_backend_ops = {
- .name = "ldap",
- .connect_fn = ildb_connect
-};
-
-_PUBLIC_ const struct ldb_backend_ops ldb_ldapi_backend_ops = {
- .name = "ldapi",
- .connect_fn = ildb_connect
-};
-
-_PUBLIC_ const struct ldb_backend_ops ldb_ldaps_backend_ops = {
- .name = "ldaps",
- .connect_fn = ildb_connect
-};
-
+/*
+ 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
new file mode 100644
index 0000000000..7dcf514e23
--- /dev/null
+++ b/source4/lib/ldb-samba/ldb_wrap.c
@@ -0,0 +1,368 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ 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 <ldb.h>
+#include <ldb_errors.h>
+#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 <tdb.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,
+ talloc_asprintf(ldb,
+ "%s/ldb",
+ lpcfg_modulesdir(lp_ctx)));
+
+ 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,
+ 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, 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 = 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,
+ 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_wrap.h b/source4/lib/ldb-samba/ldb_wrap.h
index f44ff8c599..4d2539fff5 100644
--- a/source4/lib/ldb_wrap.h
+++ b/source4/lib/ldb-samba/ldb_wrap.h
@@ -22,6 +22,8 @@
#ifndef _LDB_WRAP_H_
#define _LDB_WRAP_H_
+#include <talloc.h>
+
struct auth_session_info;
struct ldb_message;
struct ldb_dn;
@@ -37,7 +39,32 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
const char *url,
struct auth_session_info *session_info,
struct cli_credentials *credentials,
- unsigned int flags,
- const char *options[]);
+ 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,
+ 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,
+ 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, int flags);
#endif /* _LDB_WRAP_H_ */
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c
index 43a10450d1..af3c4b46e1 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -2,7 +2,7 @@
ldb database library - ldif handlers for Samba
Copyright (C) Andrew Tridgell 2005
- Copyright (C) Andrew Bartlett 2006-2007
+ 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
@@ -23,25 +23,33 @@
*/
#include "includes.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_module.h"
+#include <ldb.h>
+#include <ldb_module.h>
#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 "<Unable to decode binary data>" 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)
+ ndr_print_fn_t print_fn,
+ bool mask_errors)
{
uint8_t *p;
enum ndr_err_code err;
@@ -50,9 +58,12 @@ static int ldif_write_NDR(struct ldb_context *ldb, void *mem_ctx,
}
p = talloc_size(mem_ctx, struct_size);
err = ndr_pull_struct_blob(in, mem_ctx,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
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, "<Unable to decode binary data>");
out->length = strlen((const char *)out->data);
@@ -79,7 +90,7 @@ static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx,
if (sid == NULL) {
return -1;
}
- ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, sid,
+ 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)) {
@@ -91,7 +102,7 @@ static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx,
/*
convert a NDR formatted blob to a ldif formatted objectSid
*/
-static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
+int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
struct dom_sid *sid;
@@ -101,7 +112,7 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
if (sid == NULL) {
return -1;
}
- ndr_err = ndr_pull_struct_blob_all(in, sid, NULL, sid,
+ 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);
@@ -115,7 +126,7 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
return 0;
}
-static bool ldif_comparision_objectSid_isString(const struct ldb_val *v)
+bool ldif_comparision_objectSid_isString(const struct ldb_val *v)
{
if (v->length < 3) {
return false;
@@ -198,7 +209,7 @@ static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
(const char *)in->data, in->length);
/* Check it looks like a SID */
- ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &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;
@@ -214,16 +225,14 @@ static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx,
{
struct GUID guid;
NTSTATUS status;
- enum ndr_err_code ndr_err;
status = GUID_from_data_blob(in, &guid);
if (!NT_STATUS_IS_OK(status)) {
return -1;
}
- ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, &guid,
- (ndr_push_flags_fn_t)ndr_push_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = GUID_to_ndr_blob(&guid, mem_ctx, out);
+ if (!NT_STATUS_IS_OK(status)) {
return -1;
}
return 0;
@@ -236,10 +245,10 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
struct GUID guid;
- enum ndr_err_code ndr_err;
- ndr_err = ndr_pull_struct_blob_all(in, mem_ctx, NULL, &guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ 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);
@@ -262,7 +271,8 @@ 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;
- enum ndr_err_code ndr_err;
+ NTSTATUS status;
+
if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) {
return 0;
}
@@ -282,9 +292,9 @@ static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx,
(const char *)in->data, in->length);
/* Check it looks like a GUID */
- ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = GUID_from_ndr_blob(out, &guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(out);
return -1;
}
return 0;
@@ -355,11 +365,11 @@ static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx
return -1;
}
- ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd,
+ 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);
@@ -368,7 +378,7 @@ static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx
}
}
- ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, sd,
+ 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)) {
@@ -391,7 +401,8 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct
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);
+ (ndr_print_fn_t)ndr_print_security_descriptor,
+ true);
}
@@ -400,13 +411,13 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct
return -1;
}
/* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
- ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd,
+ 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, NULL);
+ out->data = (uint8_t *)sddl_encode(mem_ctx, sd, samdb_domain_sid_cache_only(ldb));
talloc_free(sd);
if (out->data == NULL) {
return -1;
@@ -416,7 +427,7 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct
}
/*
- canonicalise an objectCategory. We use the short form as the cannoical form:
+ canonicalise an objectCategory. We use the short form as the canonical form:
cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person'
*/
@@ -424,7 +435,7 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c
const struct ldb_val *in, struct ldb_val *out)
{
struct ldb_dn *dn1 = NULL;
- const struct dsdb_schema *schema = dsdb_get_schema(ldb);
+ 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) {
@@ -476,26 +487,21 @@ 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);
+}
- int ret, ret1, ret2;
- struct ldb_val v1_canon, v2_canon;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-
- /* I could try and bail if tmp_ctx was NULL, but what return
- * value would I use?
- *
- * It seems easier to continue on the NULL context
- */
- ret1 = ldif_canonicalise_objectCategory(ldb, tmp_ctx, v1, &v1_canon);
- ret2 = ldif_canonicalise_objectCategory(ldb, tmp_ctx, v2, &v2_canon);
-
- if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
- ret = data_blob_cmp(&v1_canon, &v2_canon);
- } else {
- ret = data_blob_cmp(v1, v2);
- }
- talloc_free(tmp_ctx);
- return ret;
+/*
+ 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);
}
/*
@@ -507,6 +513,7 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
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);
@@ -516,10 +523,29 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
blob = talloc_zero(tmp_ctx, struct prefixMapBlob);
if (blob == NULL) {
- talloc_free(blob);
+ 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);
@@ -539,7 +565,7 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
p[0] = '\0';
}
}
- /* allow a traling seperator */
+ /* allow a trailing separator */
if (line == p) {
break;
}
@@ -563,8 +589,12 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
/* we know there must be at least ":" */
oid++;
- blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.oid
- = talloc_strdup(blob->ctr.dsdb.mappings, 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++;
@@ -577,7 +607,6 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
}
ndr_err = ndr_push_struct_blob(out, mem_ctx,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
blob,
(ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
talloc_free(tmp_ctx);
@@ -599,11 +628,22 @@ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
uint32_t i;
if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) {
- return 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);
-
+ 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);
@@ -611,36 +651,50 @@ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
return -1;
}
ndr_err = ndr_pull_struct_blob_all(in, blob,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
blob,
(ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(blob);
- return -1;
+ goto failed;
}
if (blob->version != PREFIX_MAP_VERSION_DSDB) {
- return -1;
+ goto failed;
}
string = talloc_strdup(mem_ctx, "");
if (string == NULL) {
- return -1;
+ 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,
- blob->ctr.dsdb.mappings[i].oid.oid);
+ partial_oid);
+ talloc_free(discard_const(partial_oid));
if (string == NULL) {
- return -1;
+ 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)
@@ -672,42 +726,67 @@ 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);
+}
- int ret, ret1, ret2;
- struct ldb_val v1_canon, v2_canon;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+/* 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];
- /* I could try and bail if tmp_ctx was NULL, but what return
- * value would I use?
- *
- * It seems easier to continue on the NULL context
- */
- ret1 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v1, &v1_canon);
- ret2 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v2, &v2_canon);
+ /* 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;
- if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
- ret = data_blob_cmp(&v1_canon, &v2_canon);
- } else {
- ret = data_blob_cmp(v1, v2);
+ /* 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;
}
- talloc_free(tmp_ctx);
- return ret;
+ 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)
{
- char *end;
- /* We've to use "strtoll" here to have the intended overflows.
- * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
- int32_t i = (int32_t) strtoll((char *)in->data, &end, 0);
- if (*end != 0) {
- return -1;
+ 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) {
- return -1;
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
out->length = strlen((char *)out->data);
return 0;
@@ -715,12 +794,44 @@ static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
/* 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)
+ const struct ldb_val *v1, const struct ldb_val *v2)
{
- /* We've to use "strtoll" here to have the intended overflows.
- * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
- return (int32_t) strtoll((char *)v1->data, NULL, 0)
- - (int32_t) strtoll((char *)v2->data, NULL, 0);
+ 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;
}
/*
@@ -732,7 +843,8 @@ static int ldif_write_repsFromTo(struct ldb_context *ldb, void *mem_ctx,
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);
+ (ndr_print_fn_t)ndr_print_repsFromToBlob,
+ true);
}
/*
@@ -744,7 +856,8 @@ static int ldif_write_replPropertyMetaData(struct ldb_context *ldb, void *mem_ct
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);
+ (ndr_print_fn_t)ndr_print_replPropertyMetaDataBlob,
+ true);
}
/*
@@ -756,76 +869,358 @@ static int ldif_write_replUpToDateVector(struct ldb_context *ldb, void *mem_ctx,
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_replPropertyMetaDataBlob);
+ (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(mem_ctx, in));
+ *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,
+ "<RMD_FLAGS=%u>%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
+ .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
+ .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
+ .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
+ .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
+ .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
+ .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
+ .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
+ .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
- },
+ .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[] = {
@@ -844,6 +1239,41 @@ static const struct ldb_dn_extended_syntax samba_dn_syntax[] = {
.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
}
};
@@ -854,28 +1284,64 @@ static const struct {
} samba_attributes[] = {
{ "objectSid", LDB_SYNTAX_SAMBA_SID },
{ "securityIdentifier", LDB_SYNTAX_SAMBA_SID },
+ { "tokenGroups", LDB_SYNTAX_SAMBA_SID },
{ "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR },
- { "objectGUID", LDB_SYNTAX_SAMBA_GUID },
- { "invocationId", LDB_SYNTAX_SAMBA_GUID },
- { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID },
- { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID },
- { "parentGUID", LDB_SYNTAX_SAMBA_GUID },
- { "siteGUID", LDB_SYNTAX_SAMBA_GUID },
- { "pKTGUID", LDB_SYNTAX_SAMBA_GUID },
- { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID },
- { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID },
- { "netbootGUID", LDB_SYNTAX_SAMBA_GUID },
+ { "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)
{
- uint32_t j;
+ unsigned int j;
const struct ldb_schema_syntax *s = NULL;
for (j=0; j < ARRAY_SIZE(samba_syntaxes); j++) {
@@ -889,7 +1355,7 @@ const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb
const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context *ldb, const char *name)
{
- uint32_t j;
+ unsigned int j;
const struct ldb_schema_syntax *s = NULL;
for (j=0; j < ARRAY_SIZE(samba_attributes); j++) {
@@ -907,10 +1373,14 @@ const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_c
*/
int ldb_register_samba_handlers(struct ldb_context *ldb)
{
- uint32_t i;
+ 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++) {
- int ret;
const struct ldb_schema_syntax *s = NULL;
s = ldb_samba_syntax_by_name(ldb, samba_attributes[i].syntax);
@@ -920,7 +1390,7 @@ int ldb_register_samba_handlers(struct ldb_context *ldb)
}
if (!s) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
ret = ldb_schema_attribute_add_with_syntax(ldb, samba_attributes[i].name, LDB_ATTR_FLAG_FIXED, s);
@@ -930,13 +1400,16 @@ int ldb_register_samba_handlers(struct ldb_context *ldb)
}
for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) {
- int ret;
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
index 6906c822f9..62903c4a96 100644
--- a/source4/lib/ldb-samba/ldif_handlers.h
+++ b/source4/lib/ldb-samba/ldif_handlers.h
@@ -5,12 +5,15 @@
#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
diff --git a/source4/lib/ldb-samba/pyldb.c b/source4/lib/ldb-samba/pyldb.c
new file mode 100644
index 0000000000..472a4664ea
--- /dev/null
+++ b/source4/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 <jelmer@samba.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <Python.h>
+#include "includes.h"
+#include <ldb.h>
+#include <pyldb.h>
+#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.auth");
+ if (mod_samba_auth == NULL)
+ return NULL;
+
+ PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "AuthSession");
+ 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
new file mode 100644
index 0000000000..63b0f3df91
--- /dev/null
+++ b/source4/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 <http://www.gnu.org/licenses/>.
+*/
+
+
+#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(cmdline_lp_ctx);
+
+ 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
new file mode 100644
index 0000000000..a8d4df2ce0
--- /dev/null
+++ b/source4/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 pyldb-util',
+ 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
new file mode 100644
index 0000000000..012ac65bb7
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.12.sigs b/source4/lib/ldb/ABI/ldb-0.9.12.sigs
new file mode 100644
index 0000000000..2206e790fc
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.15.sigs b/source4/lib/ldb/ABI/ldb-0.9.15.sigs
new file mode 100644
index 0000000000..39d2f3eac4
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.16.sigs b/source4/lib/ldb/ABI/ldb-0.9.16.sigs
new file mode 100644
index 0000000000..610a0a4a75
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.17.sigs b/source4/lib/ldb/ABI/ldb-0.9.17.sigs
new file mode 100644
index 0000000000..d0f56991d2
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.18.sigs b/source4/lib/ldb/ABI/ldb-0.9.18.sigs
new file mode 100644
index 0000000000..15913c9385
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.19.sigs b/source4/lib/ldb/ABI/ldb-0.9.19.sigs
new file mode 100644
index 0000000000..62738709e4
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.20.sigs b/source4/lib/ldb/ABI/ldb-0.9.20.sigs
new file mode 100644
index 0000000000..62738709e4
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.22.sigs b/source4/lib/ldb/ABI/ldb-0.9.22.sigs
new file mode 100644
index 0000000000..b5a69c14a9
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.23.sigs b/source4/lib/ldb/ABI/ldb-0.9.23.sigs
new file mode 100644
index 0000000000..73e5caa896
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-0.9.24.sigs b/source4/lib/ldb/ABI/ldb-0.9.24.sigs
new file mode 100644
index 0000000000..5cb32f7c46
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-1.0.0.sigs b/source4/lib/ldb/ABI/ldb-1.0.0.sigs
new file mode 100644
index 0000000000..5cb32f7c46
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-1.0.1.sigs b/source4/lib/ldb/ABI/ldb-1.0.1.sigs
new file mode 100644
index 0000000000..5cb32f7c46
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-1.0.2.sigs b/source4/lib/ldb/ABI/ldb-1.0.2.sigs
new file mode 100644
index 0000000000..c13ac873d2
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs b/source4/lib/ldb/ABI/ldb-ildap-0.9.12.sigs
new file mode 100644
index 0000000000..4639220759
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs b/source4/lib/ldb/ABI/ldb-samba4-0.9.10.sigs
new file mode 100644
index 0000000000..7f9dbb5297
--- /dev/null
+++ b/source4/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/source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs b/source4/lib/ldb/ABI/ldb-samba4-0.9.11.sigs
new file mode 100644
index 0000000000..4639220759
--- /dev/null
+++ b/source4/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/source4/lib/ldb/Makefile b/source4/lib/ldb/Makefile
new file mode 100644
index 0000000000..a07b4a7164
--- /dev/null
+++ b/source4/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/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in
deleted file mode 100644
index c1f403d550..0000000000
--- a/source4/lib/ldb/Makefile.in
+++ /dev/null
@@ -1,187 +0,0 @@
-#!gmake
-#
-CC = @CC@
-GCOV = @GCOV@
-XSLTPROC = @XSLTPROC@
-DOXYGEN = @DOXYGEN@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-includedir = @includedir@
-libdir = @libdir@
-bindir = @bindir@
-mandir = @mandir@
-VPATH = @srcdir@:@libreplacedir@
-srcdir = @srcdir@
-builddir = @builddir@
-sharedbuilddir = @sharedbuilddir@
-INSTALLCMD = @INSTALL@
-SLAPD = @SLAPD@
-EXTRA_OBJ=@EXTRA_OBJ@
-TESTS=test-tdb.sh @TESTS@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-ldbdir = $(srcdir)
-LIB_PATH_VAR = @LIB_PATH_VAR@
-
-LDB_MODULESDIR = @LDB_MODULESDIR@
-
-TALLOC_LIBS = @TALLOC_LIBS@
-TALLOC_CFLAGS = @TALLOC_CFLAGS@
-TALLOC_OBJ = @TALLOC_OBJ@
-
-TDB_LIBS = @TDB_LIBS@
-TDB_CFLAGS = @TDB_CFLAGS@
-TDB_OBJ = @TDB_OBJ@
-
-TEVENT_LIBS = @TEVENT_LIBS@
-TEVENT_CFLAGS = @TEVENT_CFLAGS@
-TEVENT_OBJ = @TEVENT_OBJ@
-
-POPT_LIBS = @POPT_LIBS@
-POPT_CFLAGS = @POPT_CFLAGS@
-POPT_OBJ = @POPT_OBJ@
-
-LDAP_LIBS = @LDAP_LIBS@
-
-LIBDL = @LIBDL@
-
-SHLIBEXT = @SHLIBEXT@
-
-LD_EXPORT_DYNAMIC = @LD_EXPORT_DYNAMIC@
-SHLD = @SHLD@
-SHLD_FLAGS = @SHLD_FLAGS@
-
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-PICFLAG = @PICFLAG@
-CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \
- $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(TEVENT_CFLAGS) \
- -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"$(SHLIBEXT)\" -DUSE_MMAP=1 \
- -DLDB_MODULESDIR=\"$(LDB_MODULESDIR)\" \
- @CFLAGS@
-
-MDLD = @MDLD@
-MDLD_FLAGS = @MDLD_FLAGS@
-
-OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TEVENT_OBJ) $(TALLOC_OBJ) $(POPT_OBJ) $(LDB_MAP_OBJ) @LIBREPLACEOBJ@ $(EXTRA_OBJ)
-
-headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_module.h
-
-BINS = bin/ldbadd bin/ldbsearch bin/ldbdel bin/ldbmodify bin/ldbedit bin/ldbrename bin/ldbtest
-
-EXAMPLES = examples/ldbreader examples/ldifreader
-
-DIRS = lib bin common ldb_tdb ldb_ldap ldb_sqlite3 modules tools examples
-
-default: all
-
-include $(ldbdir)/rules.mk
-
-nss: nssdir all $(NSS_LIB)
-
-nssdir:
- @mkdir -p $(NSSDIR)
-
-SONAME = libldb.$(SHLIBEXT).0
-SOLIB = libldb.$(SHLIBEXT).$(PACKAGE_VERSION)
-LIBSOLIB = lib/$(SOLIB)
-STATICLIB = lib/libldb.a
-
-lib/$(SONAME): $(LIBSOLIB)
- ln -fs libldb.$(SHLIBEXT).$(PACKAGE_VERSION) $@
-
-lib/libldb.$(SHLIBEXT): $(LIBSOLIB) lib/$(SONAME)
- ln -fs libldb.$(SHLIBEXT).$(PACKAGE_VERSION) $@
-
-lib/libnss_ldb.$(SHLIBEXT).2: $(NSS_OBJ) $(LIBSOLIB)
- $(SHLD) $(SHLD_FLAGS) -o $@ $(NSS_OBJ) $(LDFLAGS) $(LIBSOLIB) @SONAMEFLAG@libnss_ldb.$(SHLIBEXT).2
-
-$(LIBSOLIB): $(OBJS)
- $(SHLD) $(SHLD_FLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS) $(TALLOC_LIBS) $(TDB_LIBS) $(TEVENT_LIBS) $(LIBDL) $(LDAP_LIBS) @SONAMEFLAG@$(SONAME)
- ln -sf libldb.$(SHLIBEXT).$(PACKAGE_VERSION) lib/libldb.$(SHLIBEXT)
-
-all: showflags dirs $(OBJS) $(STATICLIB) $(LIBSOLIB) $(BINS) $(EXAMPLES) manpages \
- @PYTHON_BUILD_TARGET@
-
-shared-build: all
- ${INSTALLCMD} -d $(sharedbuilddir)/lib
- ${INSTALLCMD} -m 644 $(STATICLIB) $(sharedbuilddir)/lib
- ${INSTALLCMD} -m 755 $(LIBSOLIB) $(sharedbuilddir)/lib
- ln -sf $(SOLIB) $(sharedbuilddir)/lib/$(SONAME)
- ln -sf $(SOLIB) $(sharedbuilddir)/lib/libldb.so
- ${INSTALLCMD} -d $(sharedbuilddir)/include
- ${INSTALLCMD} -m 644 $(srcdir)/include/ldb.h $(sharedbuilddir)/include
- ${INSTALLCMD} -m 644 $(srcdir)/include/ldb_errors.h $(sharedbuilddir)/include
- ${INSTALLCMD} -m 644 $(srcdir)/include/ldb_handlers.h $(sharedbuilddir)/include
-
-dirs:
- @mkdir -p $(DIRS)
-
-manpages::
- @$(srcdir)/docs/builddocs.sh "$(XSLTPROC)" "$(srcdir)"
-
-doxygen::
- test -z "$(DOXYGEN)" || (cd $(srcdir) && "$(DOXYGEN)")
-
-clean::
- rm -f *.o */*.o *.gcov */*.gc?? tdbtest.ldb*
- rm -f $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(STATICLIB) $(NSS_LIB) $(LIBSOLIB)
- rm -f $(POPT_OBJ)
- rm -f man/*.1 man/*.3 man/*.html
- rm -f $(EXAMPLES)
- rm -rf apidocs/
- rm -rf tests/schema/
-
-distclean:: clean
- rm -rf bin lib
- rm -f config.log config.status config.cache include/config.h
- rm -f ldb.pc
- rm -f Makefile
-
-realdistclean:: distclean
- rm -f configure include/config.h.in
-
-check:: test @PYTHON_CHECK_TARGET@
-
-check-soloading: sample.$(SHLIBEXT)
- $(LIB_PATH_VAR)=lib LDB_MODULES_PATH=$(builddir) $(srcdir)/tests/test-soloading.sh
-
-test:: all check-soloading
- for t in $(TESTS); do echo STARTING $${t}; $(LIB_PATH_VAR)=lib $(srcdir)/tests/$${t} || exit 1; done
-
-valgrindtest:: all
- for t in $(TESTS); do echo STARTING $${t}; VALGRIND="valgrind -q --db-attach=yes --num-callers=30" $(srcdir)/tests/$${t} || exit 1; done
-
-installcheck:: install test
-
-install:: all installdirs installheaders installlibs installbin installdocs \
- @PYTHON_INSTALL_TARGET@
-
-installdirs::
- mkdir -p $(DESTDIR)$(includedir) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(libdir)/pkgconfig
-
-installheaders:: installdirs
- cp $(headers) $(DESTDIR)$(includedir)
-
-installlibs:: installdirs
- cp $(STATICLIB) $(LIBSOLIB) $(DESTDIR)$(libdir)
- cp ldb.pc $(DESTDIR)$(libdir)/pkgconfig
-
-installbin:: installdirs
- cp $(BINS) $(DESTDIR)$(bindir)
-
-installdocs:: installdirs
- $(srcdir)/docs/installdocs.sh $(DESTDIR)$(mandir)
-
-gcov::
- $(GCOV) -po ldb_sqlite3 $(srcdir)/ldb_sqlite3/*.c 2| tee ldb_sqlite3.report.gcov
- $(GCOV) -po ldb_ldap $(srcdir)/ldb_ldap/*.c 2| tee ldb_ldap.report.gcov
- $(GCOV) -po ldb_tdb $(srcdir)/ldb_tdb/*.c 2| tee ldb_tdb.report.gcov
- $(GCOV) -po common $(srcdir)/common/*.c 2| tee common.report.gcov
- $(GCOV) -po modules $(srcdir)/modules/*.c 2| tee modules.report.gcov
- $(GCOV) -po tools $(srcdir)/tools/*.c 2| tee tools.report.gcov
-
-include $(ldbdir)/ldb.mk
diff --git a/source4/lib/ldb/aclocal.m4 b/source4/lib/ldb/aclocal.m4
deleted file mode 100644
index 5605e476ba..0000000000
--- a/source4/lib/ldb/aclocal.m4
+++ /dev/null
@@ -1 +0,0 @@
-m4_include(libreplace.m4)
diff --git a/source4/lib/ldb/autogen.sh b/source4/lib/ldb/autogen.sh
deleted file mode 100755
index e4d367dc1e..0000000000
--- a/source4/lib/ldb/autogen.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-rm -rf autom4te.cache
-rm -f configure config.h.in
-
-IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace -I ../../../lib/replace"
-IPATHS="$IPATHS -I ./external"
-
-autoheader $IPATHS || exit 1
-autoconf $IPATHS || exit 1
-
-rm -rf autom4te.cache
-
-echo "Now run ./configure and then make."
-exit 0
-
diff --git a/source4/lib/ldb/build_macros.m4 b/source4/lib/ldb/build_macros.m4
deleted file mode 100644
index bb7fad8f7a..0000000000
--- a/source4/lib/ldb/build_macros.m4
+++ /dev/null
@@ -1,15 +0,0 @@
-AC_DEFUN(BUILD_WITH_SHARED_BUILD_DIR,
- [ AC_ARG_WITH([shared-build-dir],
- [AC_HELP_STRING([--with-shared-build-dir=DIR],
- [temporary build directory where libraries are installed [$srcdir/sharedbuild]])])
-
- sharedbuilddir="$srcdir/sharedbuild"
- if test x"$with_shared_build_dir" != x; then
- sharedbuilddir=$with_shared_build_dir
- CFLAGS="$CFLAGS -I$with_shared_build_dir/include"
- CPPFLAGS="$CPPFLAGS -I$with_shared_build_dir/include"
- LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib"
- fi
- AC_SUBST(sharedbuilddir)
- ])
-
diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c
index ba21fcac9b..2f4454c7b4 100644
--- a/source4/lib/ldb/common/attrib_handlers.c
+++ b/source4/lib/ldb/common/attrib_handlers.c
@@ -2,6 +2,7 @@
ldb database library
Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2009
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@@ -54,7 +55,7 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
char *s, *t;
- int l;
+ size_t l;
if (!in || !out || !(in->data)) {
return -1;
@@ -99,6 +100,27 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
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;
+}
/*
@@ -108,14 +130,17 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
- char *end;
- long long i = strtoll((char *)in->data, &end, 0);
- if (*end != 0) {
- return -1;
+ 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", i);
+ out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i);
if (out->data == NULL) {
- return -1;
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
out->length = strlen((char *)out->data);
return 0;
@@ -127,7 +152,11 @@ static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx,
static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *v1, const struct ldb_val *v2)
{
- return strtoll((char *)v1->data, NULL, 0) - strtoll((char *)v2->data, NULL, 0);
+ 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;
}
/*
@@ -240,7 +269,8 @@ utf8str:
* options but to do a binary compare */
talloc_free(b1);
talloc_free(b2);
- if (memcmp(s1, s2, MIN(n1, n2)) == 0) {
+ ret = memcmp(s1, s2, MIN(n1, n2));
+ if (ret == 0) {
if (n1 == n2) return 0;
if (n1 > n2) {
return (int)toupper(s1[n2]);
@@ -248,6 +278,7 @@ utf8str:
return -(int)toupper(s2[n1]);
}
}
+ return ret;
}
u1 = b1;
@@ -337,10 +368,11 @@ static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx,
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, t2;
- t1 = ldb_string_to_time((char *)v1->data);
- t2 = ldb_string_to_time((char *)v2->data);
- return (int)t2 - (int)t1;
+ 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;
}
/*
@@ -349,10 +381,16 @@ static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx,
static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
- time_t t = ldb_string_to_time((char *)in->data);
+ 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) {
- return -1;
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
out->length = strlen((char *)out->data);
return 0;
@@ -420,7 +458,7 @@ static const struct ldb_schema_syntax ldb_standard_syntaxes[] = {
const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb,
const char *syntax)
{
- int i;
+ 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<num_handlers;i++) {
@@ -430,3 +468,29 @@ const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *
}
return NULL;
}
+
+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)
+{
+ int ret, ret1, ret2;
+ struct ldb_val v1_canon, v2_canon;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+
+ /* I could try and bail if tmp_ctx was NULL, but what return
+ * value would I use?
+ *
+ * It seems easier to continue on the NULL context
+ */
+ ret1 = canonicalise_fn(ldb, tmp_ctx, v1, &v1_canon);
+ ret2 = canonicalise_fn(ldb, tmp_ctx, v2, &v2_canon);
+
+ if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
+ ret = ldb_comparison_binary(ldb, mem_ctx, &v1_canon, &v2_canon);
+ } else {
+ ret = ldb_comparison_binary(ldb, mem_ctx, v1, v2);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index e9c924583e..d902482de0 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -34,6 +34,7 @@
#define TEVENT_DEPRECATED 1
#include "ldb_private.h"
+#include "ldb.h"
static int ldb_context_destructor(void *ptr)
{
@@ -91,18 +92,29 @@ 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);
- /* FIXME: Hack a new event context so that CMD line utilities work
- * until we have them all converted */
+ /* 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(talloc_autofree_context());
+ 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 != 0) {
+ if (ret != LDB_SUCCESS) {
talloc_free(ldb);
return NULL;
}
@@ -217,7 +229,7 @@ int ldb_connect(struct ldb_context *ldb, const char *url,
unsigned int flags, const char *options[])
{
int ret;
- const char *url2;
+ char *url2;
/* We seem to need to do this here, or else some utilities don't
* get ldb backends */
@@ -228,12 +240,12 @@ int ldb_connect(struct ldb_context *ldb, const char *url,
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ldb_set_opaque(ldb, "ldb_url", talloc_strdup(ldb, url2));
+ ret = ldb_set_opaque(ldb, "ldb_url", url2);
if (ret != LDB_SUCCESS) {
return ret;
}
- ret = ldb_connect_backend(ldb, url, options, &ldb->modules);
+ ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -285,9 +297,29 @@ void ldb_reset_err_string(struct ldb_context *ldb)
}
}
+
+
+/*
+ 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 { \
@@ -335,6 +367,10 @@ int ldb_transaction_start(struct ldb_context *ldb)
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;
}
@@ -374,8 +410,8 @@ int ldb_transaction_prepare_commit(struct ldb_context *ldb)
if (status != LDB_SUCCESS) {
/* if a module fails the prepare then we need
to call the end transaction for everyone */
- FIRST_OP(ldb, end_transaction);
- module->ops->end_transaction(module);
+ 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,
@@ -383,6 +419,10 @@ int ldb_transaction_prepare_commit(struct ldb_context *ldb)
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;
@@ -432,6 +472,10 @@ int ldb_transaction_commit(struct ldb_context *ldb)
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);
@@ -477,10 +521,27 @@ int ldb_transaction_cancel(struct ldb_context *ldb)
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)
@@ -632,7 +693,7 @@ int ldb_request_get_status(struct ldb_request *req)
static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
{
TALLOC_CTX *tmp_ctx = talloc_new(req);
- int i;
+ unsigned int i;
switch (req->operation) {
case LDB_SEARCH:
@@ -705,10 +766,12 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
ldb_debug_add(ldb, " control: <NONE>\n");
} else {
for (i=0; req->controls && req->controls[i]; i++) {
- 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");
+ 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");
+ }
}
}
@@ -717,6 +780,24 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
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; i<message->num_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
@@ -742,22 +823,72 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *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;
@@ -793,7 +924,7 @@ int ldb_search_default_callback(struct ldb_request *req,
struct ldb_reply *ares)
{
struct ldb_result *res;
- int n;
+ unsigned int n;
res = talloc_get_type(req->context, struct ldb_result);
@@ -851,6 +982,54 @@ int ldb_search_default_callback(struct ldb_request *req,
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;
@@ -877,7 +1056,7 @@ int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
int ldb_build_search_req_ex(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn *base,
enum ldb_scope scope,
struct ldb_parse_tree *tree,
@@ -927,6 +1106,8 @@ int ldb_build_search_req_ex(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -935,7 +1116,7 @@ int ldb_build_search_req_ex(struct ldb_request **ret_req,
int ldb_build_search_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn *base,
enum ldb_scope scope,
const char *expression,
@@ -965,7 +1146,7 @@ int ldb_build_search_req(struct ldb_request **ret_req,
int ldb_build_add_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
const struct ldb_message *message,
struct ldb_control **controls,
void *context,
@@ -998,6 +1179,8 @@ int ldb_build_add_req(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -1007,7 +1190,7 @@ int ldb_build_add_req(struct ldb_request **ret_req,
int ldb_build_mod_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
const struct ldb_message *message,
struct ldb_control **controls,
void *context,
@@ -1040,6 +1223,8 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -1049,7 +1234,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
int ldb_build_del_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn *dn,
struct ldb_control **controls,
void *context,
@@ -1082,6 +1267,8 @@ int ldb_build_del_req(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -1091,7 +1278,7 @@ int ldb_build_del_req(struct ldb_request **ret_req,
int ldb_build_rename_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn *olddn,
struct ldb_dn *newdn,
struct ldb_control **controls,
@@ -1126,6 +1313,8 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -1164,7 +1353,7 @@ int ldb_extended_default_callback(struct ldb_request *req,
int ldb_build_extended_req(struct ldb_request **ret_req,
struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
const char *oid,
void *data,
struct ldb_control **controls,
@@ -1199,6 +1388,8 @@ int ldb_build_extended_req(struct ldb_request **ret_req,
if (parent) {
req->handle->nesting++;
+ req->handle->parent = parent;
+ req->handle->flags = parent->handle->flags;
}
*ret_req = req;
@@ -1291,6 +1482,7 @@ int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
res,
ldb_search_default_callback,
NULL);
+ ldb_req_set_location(req, "ldb_search");
if (ret != LDB_SUCCESS) goto done;
@@ -1334,6 +1526,7 @@ int ldb_add(struct ldb_context *ldb,
NULL,
ldb_op_default_callback,
NULL);
+ ldb_req_set_location(req, "ldb_add");
if (ret != LDB_SUCCESS) return ret;
@@ -1364,6 +1557,7 @@ int ldb_modify(struct ldb_context *ldb,
NULL,
ldb_op_default_callback,
NULL);
+ ldb_req_set_location(req, "ldb_modify");
if (ret != LDB_SUCCESS) return ret;
@@ -1389,6 +1583,7 @@ int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
NULL,
ldb_op_default_callback,
NULL);
+ ldb_req_set_location(req, "ldb_delete");
if (ret != LDB_SUCCESS) return ret;
@@ -1415,6 +1610,7 @@ int ldb_rename(struct ldb_context *ldb,
NULL,
ldb_op_default_callback,
NULL);
+ ldb_req_set_location(req, "ldb_rename");
if (ret != LDB_SUCCESS) return ret;
@@ -1639,3 +1835,47 @@ 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;
+}
+
+/**
+ 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
index 79c5dd69de..21a3e6eb93 100644
--- a/source4/lib/ldb/common/ldb_attributes.c
+++ b/source4/lib/ldb/common/ldb_attributes.c
@@ -49,7 +49,7 @@ int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb,
unsigned flags,
const struct ldb_schema_syntax *syntax)
{
- int i, n;
+ unsigned int i, n;
struct ldb_schema_attribute *a;
if (!syntax) {
@@ -122,7 +122,9 @@ static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
struct ldb_context *ldb,
const char *name)
{
- int i, e, b = 0, r;
+ /* 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 */
@@ -134,8 +136,7 @@ static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
/* do a binary search on the array */
e = ldb->schema.num_attributes - 1;
- while (b <= e) {
-
+ while ((b <= e) && (e != (unsigned int) -1)) {
i = (b + e) / 2;
r = ldb_attr_cmp(name, ldb->schema.attributes[i].name);
@@ -147,7 +148,6 @@ static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
} else {
b = i + 1;
}
-
}
return def;
@@ -179,7 +179,7 @@ const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_conte
void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name)
{
const struct ldb_schema_attribute *a;
- int i;
+ ptrdiff_t i;
a = ldb_schema_attribute_by_name_internal(ldb, name);
if (a == NULL || a->name == NULL) {
@@ -232,7 +232,7 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
{ "ou", LDB_SYNTAX_DIRECTORY_STRING },
{ "objectClass", LDB_SYNTAX_OBJECTCLASS }
};
- int i;
+ unsigned int i;
int ret;
for (i=0;i<ARRAY_SIZE(wellknown);i++) {
@@ -254,7 +254,7 @@ int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
unsigned flags,
const struct ldb_dn_extended_syntax *syntax)
{
- int n;
+ unsigned int n;
struct ldb_dn_extended_syntax *a;
if (!syntax) {
@@ -284,7 +284,7 @@ int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
const char *name)
{
- int i;
+ 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];
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index b38373ec12..5a86bde211 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -37,11 +37,11 @@
/* returns NULL if not found */
struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
{
- int i;
+ unsigned int i;
if (req->controls != NULL) {
for (i = 0; req->controls[i]; i++) {
- if (strcmp(oid, req->controls[i]->oid) == 0) {
+ if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) {
break;
}
}
@@ -56,11 +56,11 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char
/* returns NULL if not found */
struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
{
- int i;
+ unsigned int i;
if (rep->controls != NULL) {
for (i = 0; rep->controls[i]; i++) {
- if (strcmp(oid, rep->controls[i]->oid) == 0) {
+ if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) {
break;
}
}
@@ -71,42 +71,101 @@ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid
return NULL;
}
-/* saves the current controls list into the "saver" and replace the one in req with a new one excluding
-the "exclude" control */
-/* returns 0 on error */
-int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
+/*
+ * 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;
- int i, j;
+ struct ldb_control **lcs, **lcs_old;
+ unsigned int i, j;
+
+ lcs_old = req->controls;
+ if (saver != NULL) {
+ *saver = lcs_old;
+ }
- *saver = req->controls;
- for (i = 0; req->controls[i]; i++);
- if (i == 1) {
+ 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);
+ lcs = talloc_array(req, struct ldb_control *, i + 1);
if (!lcs) {
return 0;
}
- for (i = 0, j = 0; (*saver)[i]; i++) {
- if (exclude == (*saver)[i]) continue;
- lcs[j] = (*saver)[i];
+ 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 = lcs;
+ 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 check_critical_controls(struct ldb_control **controls)
+int ldb_check_critical_controls(struct ldb_control **controls)
{
- int i;
+ unsigned int i;
if (controls == NULL) {
return 0;
@@ -123,23 +182,61 @@ int check_critical_controls(struct ldb_control **controls)
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; i<n; i++) {
+ ctrls[i] = req->controls[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; req->controls && req->controls[n];) {
+ for (n=0; ares->controls && ares->controls[n];) {
/* having two controls of the same OID makes no sense */
- if (strcmp(oid, req->controls[n]->oid) == 0) {
+ if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) {
return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
}
n++;
}
- ctrls = talloc_realloc(req, req->controls,
+ ctrls = talloc_realloc(ares, ares->controls,
struct ldb_control *,
n + 2);
if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
- req->controls = ctrls;
+ ares->controls = ctrls;
ctrls[n] = NULL;
ctrls[n+1] = NULL;
@@ -155,496 +252,786 @@ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool criti
return LDB_SUCCESS;
}
-/* Parse controls from the format used on the command line and in ejs */
+/* 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;
-struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings)
+ 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)
{
- int i;
- struct ldb_control **ctrl;
+ 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 (control_strings == NULL || control_strings[0] == NULL)
+ if (!(ctrl = talloc(mem_ctx, struct ldb_control))) {
+ ldb_oom(ldb);
return NULL;
+ }
- for (i = 0; control_strings[i]; i++);
+ 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):<os(n):cc(n)|attr(s)>[: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;
- ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
+ return ctrl;
+ }
- for (i = 0; control_strings[i]; i++) {
- if (strncmp(control_strings[i], "vlv:", 4) == 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[i][4]);
- 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):<os(n):cc(n)|attr(s)>[: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;
- }
- if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
- ctrl[i]->critical = crit;
- if (!(control = talloc(ctrl[i],
- 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[i]->data = control;
+ if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) {
+ struct ldb_dirsync_control *control;
+ const char *p;
+ char cookie[1024];
+ int crit, flags, max_attrs, ret;
+
+ cookie[0] = '\0';
+ p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]);
+ ret = sscanf(p, "%d:%d:%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;
+ }
- continue;
+ /* 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;
- if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
- struct ldb_dirsync_control *control;
- const char *p;
- char cookie[1024];
- int crit, flags, max_attrs, ret;
-
- cookie[0] = '\0';
- p = &(control_strings[i][8]);
- ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
+ 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;
+ }
- 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");
+ 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;
+ }
- /* 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[i] = talloc(ctrl, struct ldb_control);
- ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
- ctrl[i]->critical = crit;
- control = talloc(ctrl[i], 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[i]->data = control;
+ ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID;
+ ctrl->critical = crit;
+ ctrl->data = talloc_steal(ctrl, control);
+
+ return ctrl;
+ }
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "asq:", 4) == 0) {
- struct ldb_asq_control *control;
- const char *p;
- char attr[256];
- int crit, ret;
+ 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;
- attr[0] = '\0';
- p = &(control_strings[i][4]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
- ctrl[i]->critical = crit;
- control = talloc(ctrl[i], struct ldb_asq_control);
- control->request = 1;
- control->source_attribute = talloc_strdup(control, attr);
- control->src_attr_len = strlen(attr);
- ctrl[i]->data = control;
-
- continue;
- }
-
- if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
- struct ldb_extended_dn_control *control;
- const char *p;
- int crit, type, ret;
-
- p = &(control_strings[i][12]);
- 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;
- }
+ 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[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = talloc_steal(ctrl[i], control);
+ 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;
+ }
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
- struct ldb_sd_flags_control *control;
- const char *p;
- int crit, ret;
- unsigned secinfo_flags;
+ ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][9]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
- ctrl[i]->critical = crit;
- control = talloc(ctrl[i], struct ldb_sd_flags_control);
- control->secinfo_flags = secinfo_flags;
- ctrl[i]->data = control;
-
- continue;
- }
-
- if (strncmp(control_strings[i], "search_options:", 15) == 0) {
- struct ldb_search_options_control *control;
- const char *p;
- int crit, ret;
- unsigned search_options;
-
- p = &(control_strings[i][15]);
- 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;
- }
+ 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[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
- ctrl[i]->critical = crit;
- control = talloc(ctrl[i], struct ldb_search_options_control);
- control->search_options = search_options;
- ctrl[i]->data = control;
+ ctrl->oid = LDB_CONTROL_RELAX_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
- const char *p;
- int crit, ret;
+ ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][13]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
- struct ldb_paged_control *control;
- const char *p;
- int crit, size, ret;
-
- p = &(control_strings[i][14]);
- ret = sscanf(p, "%d:%d", &crit, &size);
+ 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;
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
- ctrl[i]->critical = crit;
- control = talloc(ctrl[i], struct ldb_paged_control);
- control->size = size;
- control->cookie = NULL;
- control->cookie_len = 0;
- ctrl[i]->data = control;
-
- continue;
- }
-
- if (strncmp(control_strings[i], "server_sort:", 12) == 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[i][12]);
- 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[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
- ctrl[i]->critical = crit;
- control = talloc_array(ctrl[i], 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[i]->data = control;
-
- continue;
- }
-
- if (strncmp(control_strings[i], "notification:", 13) == 0) {
- const char *p;
- int crit, ret;
-
- p = &(control_strings[i][13]);
- 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;
- }
+ 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;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
+ }
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
- const char *p;
- int crit, ret;
+ ctrl->oid = LDB_CONTROL_TREE_DELETE_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][13]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
+ }
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "show_deactivated_link:", 22) == 0) {
- const char *p;
- int crit, ret;
+ ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][22]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "show_recycled:", 14) == 0) {
- const char *p;
- int crit, ret;
+ ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][14]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_SHOW_RECYCLED_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
+ }
- continue;
+ 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;
}
- if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
- const char *p;
- int crit, ret;
+ ctrl->oid = talloc_strdup(ctrl, oid);
+ if (!ctrl->oid) {
+ ldb_oom(ldb);
+ return NULL;
+ }
+ ctrl->critical = crit;
+ ctrl->data = NULL;
- p = &(control_strings[i][18]);
- 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;
- }
+ return ctrl;
+ }
- ctrl[i] = talloc(ctrl, struct ldb_control);
- if (!ctrl[i]) {
- ldb_oom(ldb);
- return NULL;
- }
- ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
- ctrl[i]->critical = crit;
- ctrl[i]->data = NULL;
+ 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;
+ }
- continue;
+ 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;
}
- /* no controls matched, throw an error */
- ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
+ 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;
diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c
index 12a513fc42..cd9055da92 100644
--- a/source4/lib/ldb/common/ldb_dn.c
+++ b/source4/lib/ldb/common/ldb_dn.c
@@ -79,8 +79,14 @@ struct ldb_dn {
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(void *mem_ctx,
+struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx,
struct ldb_context *ldb,
const struct ldb_val *strdn)
{
@@ -89,7 +95,7 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
if (! ldb) return NULL;
if (strdn && strdn->data
- && (strlen((const char*)strdn->data) != strdn->length)) {
+ && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
/* The RDN must not contain a character with value 0x0 */
return NULL;
}
@@ -97,7 +103,13 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
dn = talloc_zero(mem_ctx, struct ldb_dn);
LDB_DN_NULL_FAILED(dn);
- dn->ldb = ldb;
+ 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;
@@ -142,17 +154,17 @@ failed:
}
/* strdn may be NULL */
-struct ldb_dn *ldb_dn_new(void *mem_ctx,
+struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
struct ldb_context *ldb,
const char *strdn)
{
struct ldb_val blob;
- blob.data = strdn;
+ 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(void *mem_ctx,
+struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
struct ldb_context *ldb,
const char *new_fmt, ...)
{
@@ -174,18 +186,18 @@ struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
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;
- int l;
+ size_t l;
p = s = src;
d = dst;
while (p - src < len) {
-
- p += strcspn(p, ",=\n+<>#;\\\"");
+ p += strcspn(p, ",=\n\r+<>#;\\\" ");
if (p - src == len) /* found no escapable chars */
break;
@@ -193,14 +205,46 @@ static int ldb_dn_escape_internal(char *dst, const char *src, int len)
/* 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;
- if (*p) { /* it is a normal escapable character */
+ 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++;
- } else { /* we have a zero byte in the string */
- strncpy(d, "\00", 3); /* escape the zero */
- d += 3;
- p++; /* skip the zero */
+ 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 */
}
@@ -213,7 +257,7 @@ static int ldb_dn_escape_internal(char *dst, const char *src, int len)
return (l + (d - dst));
}
-char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
+char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
{
char *dst;
@@ -244,8 +288,8 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
static bool ldb_dn_explode(struct ldb_dn *dn)
{
char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
- bool trim = false;
- bool in_extended = false;
+ bool trim = true;
+ bool in_extended = true;
bool in_ex_name = false;
bool in_ex_value = false;
bool in_attr = false;
@@ -253,9 +297,11 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
bool in_quote = false;
bool is_oid = false;
bool escape = false;
- unsigned x;
- int l, ret;
+ unsigned int x;
+ size_t l;
+ int ret;
char *parse_dn;
+ bool is_index;
if ( ! dn || dn->invalid) return false;
@@ -273,10 +319,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
return false;
}
- /* The RDN size must be less than 255 characters */
- if (strlen(parse_dn) > 255) {
- return false;
- }
+ is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
/* Empty DNs */
if (parse_dn[0] == '\0') {
@@ -288,11 +331,12 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
return true;
}
- /* make sure we free this if alloced previously before replacing */
- talloc_free(dn->components);
+ /* make sure we free this if allocated previously before replacing */
+ LDB_FREE(dn->components);
+ dn->comp_num = 0;
- talloc_free(dn->ext_components);
- dn->ext_components = NULL;
+ 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 */
@@ -300,7 +344,6 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if ( ! dn->components) {
return false;
}
- dn->comp_num = 0;
/* Components data space is allocated here once */
data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
@@ -309,10 +352,6 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
}
p = parse_dn;
- in_extended = true;
- in_ex_name = false;
- in_ex_value = false;
- trim = true;
t = NULL;
d = dt = data;
@@ -383,7 +422,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
&ex_val, &dn->ext_components[dn->ext_comp_num].value);
if (ret != LDB_SUCCESS) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -398,7 +437,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
p++;
continue;
} else {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
}
@@ -418,7 +457,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if (!isascii(*p)) {
/* attr names must be ascii only */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -428,7 +467,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if ( ! isalpha(*p)) {
/* not a digit nor an alpha,
* invalid attribute name */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -447,7 +486,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if (trim && (*p != '=')) {
/* spaces/tabs are not allowed */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -476,19 +515,19 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if (!isascii(*p)) {
/* attr names must be ascii only */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
/* not a digit nor a dot,
* invalid attribute oid */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
} else
if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
/* not ALPHA, DIGIT or HYPHEN */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -578,17 +617,27 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
continue;
- case '=':
- case '\n':
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 '#':
case ';':
- case '\"':
/* a string with not escaped specials is invalid (tested) */
if ( ! escape) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
escape = false;
@@ -615,17 +664,20 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
default:
if (escape) {
- if (sscanf(p, "%02x", &x) != 1) {
- /* invalid escaping sequence */
- dn->invalid = true;
- goto failed;
+ 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;
- p += 2;
- *d++ = (unsigned char)x;
+ escape = false;
l++;
-
if ( t ) t = NULL;
break;
}
@@ -647,7 +699,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
if (in_attr || in_quote) {
/* invalid dn */
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
goto failed;
}
@@ -673,8 +725,11 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
return true;
failed:
+ LDB_FREE(dn->components); /* "data" is implicitly free'd */
dn->comp_num = 0;
- talloc_free(dn->components);
+ LDB_FREE(dn->ext_components);
+ dn->ext_comp_num = 0;
+
return false;
}
@@ -685,7 +740,8 @@ bool ldb_dn_validate(struct ldb_dn *dn)
const char *ldb_dn_get_linearized(struct ldb_dn *dn)
{
- int i, len;
+ unsigned int i;
+ size_t len;
char *d, *n;
if ( ! dn || ( dn->invalid)) return NULL;
@@ -693,7 +749,7 @@ const char *ldb_dn_get_linearized(struct ldb_dn *dn)
if (dn->linearized) return dn->linearized;
if ( ! dn->components) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return NULL;
}
@@ -740,11 +796,18 @@ const char *ldb_dn_get_linearized(struct ldb_dn *dn)
return dn->linearized;
}
-char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
+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;
- int i;
+ char *p = NULL;
+ unsigned int i;
if (!linearized) {
return NULL;
@@ -758,6 +821,13 @@ char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
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;
@@ -766,6 +836,9 @@ char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
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,
@@ -782,11 +855,11 @@ char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
}
if (i == 0) {
- p = talloc_asprintf(mem_ctx, "<%s=%s>",
- name, val.data);
+ p = talloc_asprintf(mem_ctx, "<%s=%s>",
+ name, val.data);
} else {
- p = talloc_asprintf_append(p, ";<%s=%s>",
- name, val.data);
+ p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
+ name, val.data);
}
talloc_free(val.data);
@@ -797,7 +870,7 @@ char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
}
if (dn->ext_comp_num && *linearized) {
- p = talloc_asprintf_append(p, ";%s", linearized);
+ p = talloc_asprintf_append_buffer(p, ";%s", linearized);
}
if (!p) {
@@ -807,9 +880,26 @@ char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
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; i<dn->ext_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(void *mem_ctx, struct ldb_dn *dn)
+char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
{
return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
}
@@ -821,7 +911,8 @@ char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
{
- int i, ret;
+ unsigned int i;
+ int ret;
if ( ! dn || dn->invalid) return false;
@@ -866,7 +957,8 @@ failed:
const char *ldb_dn_get_casefold(struct ldb_dn *dn)
{
- int i, len;
+ unsigned int i;
+ size_t len;
char *d, *n;
if (dn->casefold) return dn->casefold;
@@ -923,7 +1015,7 @@ const char *ldb_dn_get_casefold(struct ldb_dn *dn)
return dn->casefold;
}
-char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
+char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
{
return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
}
@@ -936,7 +1028,7 @@ char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
{
int ret;
- int n_base, n_dn;
+ unsigned int n_base, n_dn;
if ( ! base || base->invalid) return 1;
if ( ! dn || dn->invalid) return -1;
@@ -972,7 +1064,7 @@ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
return (dn->comp_num - base->comp_num);
}
- if (dn->comp_num == 0) {
+ if ((dn->comp_num == 0) || (base->comp_num == 0)) {
if (dn->special && base->special) {
return strcmp(base->linearized, dn->linearized);
} else if (dn->special) {
@@ -987,7 +1079,7 @@ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
n_base = base->comp_num - 1;
n_dn = dn->comp_num - 1;
- while (n_base >= 0) {
+ while (n_base != (unsigned int) -1) {
char *b_name = base->components[n_base].cf_name;
char *dn_name = dn->components[n_dn].cf_name;
@@ -1022,7 +1114,8 @@ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
{
- int i, ret;
+ unsigned int i;
+ int ret;
if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
return -1;
@@ -1093,7 +1186,7 @@ int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
}
static struct ldb_dn_component ldb_dn_copy_component(
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn_component *src)
{
struct ldb_dn_component dst;
@@ -1139,7 +1232,7 @@ static struct ldb_dn_component ldb_dn_copy_component(
}
static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn_ext_component *src)
{
struct ldb_dn_ext_component dst;
@@ -1164,7 +1257,7 @@ static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
return dst;
}
-struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
+struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
{
struct ldb_dn *new_dn;
@@ -1180,7 +1273,7 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
*new_dn = *dn;
if (dn->components) {
- int i;
+ unsigned int i;
new_dn->components =
talloc_zero_array(new_dn,
@@ -1203,7 +1296,7 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
}
if (dn->ext_components) {
- int i;
+ unsigned int i;
new_dn->ext_components =
talloc_zero_array(new_dn,
@@ -1269,7 +1362,7 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
}
if (dn->components) {
- int i;
+ unsigned int i;
if ( ! ldb_dn_validate(base)) {
return false;
@@ -1287,7 +1380,7 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
struct ldb_dn_component,
dn->comp_num + base->comp_num);
if ( ! dn->components) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
@@ -1296,7 +1389,7 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
ldb_dn_copy_component(dn->components,
&base->components[i]);
if (dn->components[dn->comp_num].value.data == NULL) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
}
@@ -1327,7 +1420,7 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
t = talloc_strdup(dn, s);
}
if ( ! t) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
LDB_FREE(dn->linearized);
@@ -1336,12 +1429,10 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
/* Wipe the ext_linearized DN,
* the GUID and SID are almost certainly no longer valid */
- if (dn->ext_linearized) {
- LDB_FREE(dn->ext_linearized);
- }
-
+ LDB_FREE(dn->ext_linearized);
LDB_FREE(dn->ext_components);
dn->ext_comp_num = 0;
+
return true;
}
@@ -1393,7 +1484,12 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
}
if (dn->components) {
- int n, i, j;
+ unsigned int n;
+ unsigned int i, j;
+
+ if (dn->comp_num == 0) {
+ return false;
+ }
if ( ! ldb_dn_validate(child)) {
return false;
@@ -1413,11 +1509,12 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
struct ldb_dn_component,
n);
if ( ! dn->components) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
- for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
+ for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
+ i--, j--) {
dn->components[j] = dn->components[i];
}
@@ -1426,7 +1523,7 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
ldb_dn_copy_component(dn->components,
&child->components[i]);
if (dn->components[i].value.data == NULL) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
}
@@ -1441,6 +1538,9 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
}
if (dn->linearized) {
+ if (dn->linearized[0] == '\0') {
+ return false;
+ }
s = ldb_dn_get_linearized(child);
if ( ! s) {
@@ -1449,7 +1549,7 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
if ( ! t) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return false;
}
LDB_FREE(dn->linearized);
@@ -1459,7 +1559,6 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
/* 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;
@@ -1501,7 +1600,7 @@ bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
{
- int i;
+ unsigned int i;
if ( ! ldb_dn_validate(dn)) {
return false;
@@ -1512,11 +1611,11 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
}
/* free components */
- for (i = num; i > 0; i--) {
- LDB_FREE(dn->components[dn->comp_num - i].name);
- LDB_FREE(dn->components[dn->comp_num - i].value.data);
- LDB_FREE(dn->components[dn->comp_num - i].cf_name);
- LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
+ 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;
@@ -1535,7 +1634,6 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
/* 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;
@@ -1544,7 +1642,7 @@ 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)
{
- int i, j;
+ unsigned int i, j;
if ( ! ldb_dn_validate(dn)) {
return false;
@@ -1580,13 +1678,13 @@ bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
/* 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(void *mem_ctx, struct ldb_dn *dn)
+struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
{
struct ldb_dn *new_dn;
@@ -1600,12 +1698,6 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
return NULL;
}
- /* 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 new_dn;
}
@@ -1618,8 +1710,8 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
the EX format has the last '/' replaced with a newline (\n).
*/
-static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
- int i;
+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" : "/" );
@@ -1631,7 +1723,7 @@ static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
tmpctx = talloc_new(mem_ctx);
/* Walk backwards down the DN, grabbing 'dc' components at first */
- for (i = dn->comp_num - 1 ; i >= 0; i--) {
+ for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
break;
}
@@ -1650,7 +1742,7 @@ static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
}
/* Only domain components? Finish here */
- if (i < 0) {
+ if (i == (unsigned int) -1) {
cracked = talloc_strdup_append_buffer(cracked, format);
talloc_steal(mem_ctx, cracked);
goto done;
@@ -1678,12 +1770,12 @@ done:
}
/* Wrapper functions for the above, for the two different string formats */
-char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
+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(void *mem_ctx, struct ldb_dn *dn) {
+char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
return ldb_dn_canonical(mem_ctx, dn, 1);
}
@@ -1695,6 +1787,14 @@ int ldb_dn_get_comp_num(struct ldb_dn *dn)
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)) {
@@ -1764,7 +1864,7 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num,
dn->components[num].value = v;
if (dn->valid_case) {
- int i;
+ 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);
@@ -1777,16 +1877,16 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num,
/* Wipe the ext_linearized DN,
* the GUID and SID are almost certainly no longer valid */
LDB_FREE(dn->ext_linearized);
-
- dn->ext_comp_num = 0;
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)
{
- int i;
+ unsigned int i;
if ( ! ldb_dn_validate(dn)) {
return NULL;
}
@@ -1802,12 +1902,18 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn,
const char *name, const struct ldb_val *val)
{
struct ldb_dn_ext_component *p;
- int i;
+ 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) {
@@ -1818,10 +1924,9 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn,
talloc_strdup(dn->ext_components, name);
if (!dn->ext_components[i].name ||
!dn->ext_components[i].value.data) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return LDB_ERR_OPERATIONS_ERROR;
}
-
} else {
if (i != (dn->ext_comp_num - 1)) {
memmove(&dn->ext_components[i],
@@ -1836,41 +1941,53 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn,
struct ldb_dn_ext_component,
dn->ext_comp_num);
if (!dn->ext_components) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return LDB_ERR_OPERATIONS_ERROR;
}
- return LDB_SUCCESS;
}
+ 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) {
- dn->invalid = true;
+ ldb_dn_mark_invalid(dn);
return LDB_ERR_OPERATIONS_ERROR;
}
- p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
+ 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) {
- dn->invalid = true;
+ 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)
{
- dn->ext_comp_num = 0;
+ LDB_FREE(dn->ext_linearized);
LDB_FREE(dn->ext_components);
+ dn->ext_comp_num = 0;
}
bool ldb_dn_is_valid(struct ldb_dn *dn)
@@ -1905,3 +2022,80 @@ bool ldb_dn_is_null(struct ldb_dn *dn)
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
index b7ab7300b2..f837012e69 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -41,7 +41,7 @@
/*
*/
-static int ldb_read_data_file(void *mem_ctx, struct ldb_val *value)
+static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value)
{
struct stat statbuf;
char *buf;
@@ -150,7 +150,7 @@ int ldb_base64_decode(char *s)
encode as base64
caller frees
*/
-char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
+char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len)
{
const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
@@ -190,10 +190,6 @@ int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val)
unsigned int i;
uint8_t *p = val->data;
- if (ldb->flags & LDB_FLG_SHOW_BINARY) {
- return 0;
- }
-
if (val->length == 0) {
return 0;
}
@@ -219,7 +215,7 @@ int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val)
static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data,
const char *buf, size_t length, int start_pos)
{
- unsigned int i;
+ size_t i;
int total=0, ret;
for (i=0;i<length;i++) {
@@ -333,11 +329,14 @@ int ldb_ldif_write(struct ldb_context *ldb,
for (j=0;j<msg->elements[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];
}
- if (ret != LDB_SUCCESS || ldb_should_b64_encode(ldb, &v)) {
+ 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;
@@ -373,6 +372,8 @@ int ldb_ldif_write(struct ldb_context *ldb,
ret = fprintf_fn(private_data,"\n");
CHECK_RET;
+ talloc_free(mem_ctx);
+
return total;
}
@@ -447,7 +448,7 @@ static char *next_chunk(struct ldb_context *ldb,
/* simple ldif attribute parser */
-static int next_attr(void *mem_ctx, char **s, const char **attr, struct ldb_val *value)
+static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value)
{
char *p;
int base64_encoded = 0;
@@ -508,7 +509,7 @@ static int next_attr(void *mem_ctx, char **s, const char **attr, struct ldb_val
if (binary_file) {
int len = ldb_read_data_file(mem_ctx, value);
if (len == -1) {
- /* an error occured hile trying to retrieve the file */
+ /* an error occurred while trying to retrieve the file */
return -1;
}
}
diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c
index e6ee0de027..a42cf9449d 100644
--- a/source4/lib/ldb/common/ldb_match.c
+++ b/source4/lib/ldb/common/ldb_match.c
@@ -81,55 +81,94 @@ static int ldb_match_scope(struct ldb_context *ldb,
static int ldb_match_present(struct ldb_context *ldb,
const struct ldb_message *msg,
const struct ldb_parse_tree *tree,
- enum ldb_scope scope)
+ 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) {
- return 1;
+ *matched = true;
+ return LDB_SUCCESS;
}
- if (ldb_msg_find_element(msg, tree->u.present.attr)) {
- return 1;
+ el = ldb_msg_find_element(msg, tree->u.present.attr);
+ if (el == NULL) {
+ *matched = false;
+ return LDB_SUCCESS;
}
- return 0;
+ 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)
+ enum ldb_parse_op comp_op, bool *matched)
{
unsigned int i;
struct ldb_message_element *el;
const struct ldb_schema_attribute *a;
- int ret;
/* FIXME: APPROX comparison not handled yet */
- if (comp_op == LDB_OP_APPROX) return 0;
+ if (comp_op == LDB_OP_APPROX) {
+ return LDB_ERR_INAPPROPRIATE_MATCHING;
+ }
el = ldb_msg_find_element(msg, tree->u.comparison.attr);
if (el == NULL) {
- return 0;
+ *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++) {
- ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
-
- if (ret == 0) {
- return 1;
- }
- if (ret > 0 && comp_op == LDB_OP_GREATER) {
- return 1;
- }
- if (ret < 0 && comp_op == LDB_OP_LESS) {
- return 1;
+ 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;
+ }
}
}
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
}
/*
@@ -138,7 +177,8 @@ static int ldb_match_comparison(struct ldb_context *ldb,
static int ldb_match_equality(struct ldb_context *ldb,
const struct ldb_message *msg,
const struct ldb_parse_tree *tree,
- enum ldb_scope scope)
+ enum ldb_scope scope,
+ bool *matched)
{
unsigned int i;
struct ldb_message_element *el;
@@ -149,39 +189,52 @@ static int ldb_match_equality(struct ldb_context *ldb,
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 0;
+ return LDB_ERR_INVALID_DN_SYNTAX;
}
ret = ldb_dn_compare(msg->dn, valuedn);
talloc_free(valuedn);
- if (ret == 0) return 1;
- return 0;
+ *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) {
- return 0;
+ *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;i<el->num_values;i++) {
- if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
- &el->values[i]) == 0) {
- return 1;
+ 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;
+ }
}
}
- return 0;
+ *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)
+ const struct ldb_val value, bool *matched)
{
const struct ldb_schema_attribute *a;
struct ldb_val val;
@@ -189,12 +242,16 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
struct ldb_val *chunk;
char *p, *g;
uint8_t *save_p = NULL;
- int c = 0;
+ 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 -1;
+ if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) {
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
save_p = val.data;
cnk.data = NULL;
@@ -202,13 +259,13 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
if ( ! tree->u.substring.start_with_wildcard ) {
chunk = tree->u.substring.chunks[c];
- if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;
+ 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 failed;
+ goto mismatch;
}
- if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed;
+ if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch;
val.length -= cnk.length;
val.data += cnk.length;
c++;
@@ -219,11 +276,11 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
while (tree->u.substring.chunks[c]) {
chunk = tree->u.substring.chunks[c];
- if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;
+ 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 failed;
+ 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);
@@ -237,14 +294,17 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
cnk.data = NULL;
}
- if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto failed; /* last chunk have not reached end of string */
+ /* 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);
- return 1;
+ *matched = true;
+ return LDB_SUCCESS;
-failed:
+mismatch:
+ *matched = false;
talloc_free(save_p);
talloc_free(cnk.data);
- return 0;
+ return LDB_SUCCESS;
}
/*
@@ -253,46 +313,71 @@ failed:
static int ldb_match_substring(struct ldb_context *ldb,
const struct ldb_message *msg,
const struct ldb_parse_tree *tree,
- enum ldb_scope scope)
+ 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) {
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
}
for (i = 0; i < el->num_values; i++) {
- if (ldb_wildcard_compare(ldb, tree, el->values[i]) == 1) {
- return 1;
- }
+ int ret;
+ ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
+ if (ret != LDB_SUCCESS) return ret;
+ if (*matched) return LDB_SUCCESS;
}
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
}
/*
bitwise-and comparator
*/
-static int ldb_comparator_and(const struct ldb_val *v1, const struct ldb_val *v2)
+static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2,
+ bool *matched)
{
uint64_t i1, i2;
- i1 = strtoull((char *)v1->data, NULL, 0);
- i2 = strtoull((char *)v2->data, NULL, 0);
- return ((i1 & i2) == i2);
-}
+ char ibuf[100];
+ char *endptr = NULL;
-/*
- bitwise-or comparator
-*/
-static int ldb_comparator_or(const struct ldb_val *v1, const struct ldb_val *v2)
-{
- uint64_t i1, i2;
- i1 = strtoull((char *)v1->data, NULL, 0);
- i2 = strtoull((char *)v2->data, NULL, 0);
- return ((i1 & i2) != 0);
+ 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;
}
@@ -302,30 +387,33 @@ static int ldb_comparator_or(const struct ldb_val *v1, const struct ldb_val *v2)
static int ldb_match_extended(struct ldb_context *ldb,
const struct ldb_message *msg,
const struct ldb_parse_tree *tree,
- enum ldb_scope scope)
+ enum ldb_scope scope, bool *matched)
{
- int i;
+ unsigned int i;
const struct {
const char *oid;
- int (*comparator)(const struct ldb_val *, const struct ldb_val *);
+ int (*comparator)(const char *, const struct ldb_val *, const struct ldb_val *, bool *);
} rules[] = {
- { LDB_OID_COMPARATOR_AND, ldb_comparator_and},
- { LDB_OID_COMPARATOR_OR, ldb_comparator_or}
+ { LDB_OID_COMPARATOR_AND, ldb_comparator_bitmask},
+ { LDB_OID_COMPARATOR_OR, ldb_comparator_bitmask}
};
- int (*comp)(const struct ldb_val *, const struct ldb_val *) = NULL;
+ int (*comp)(const char *,const struct ldb_val *, const struct ldb_val *, bool *) = NULL;
struct ldb_message_element *el;
if (tree->u.extended.dnAttributes) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: dnAttributes extended match not supported yet");
- return -1;
+ /* 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 -1;
+ 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 -1;
+ return LDB_ERR_INAPPROPRIATE_MATCHING;
}
for (i=0;i<ARRAY_SIZE(rules);i++) {
@@ -337,21 +425,24 @@ static int ldb_match_extended(struct ldb_context *ldb,
if (comp == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
tree->u.extended.rule_id);
- return -1;
+ return LDB_ERR_INAPPROPRIATE_MATCHING;
}
/* find the message element */
el = ldb_msg_find_element(msg, tree->u.extended.attr);
if (el == NULL) {
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
}
for (i=0;i<el->num_values;i++) {
- int ret = comp(&el->values[i], &tree->u.extended.value);
- if (ret == -1 || ret == 1) return ret;
+ 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;
}
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
}
/*
@@ -365,53 +456,61 @@ static int ldb_match_extended(struct ldb_context *ldb,
static int ldb_match_message(struct ldb_context *ldb,
const struct ldb_message *msg,
const struct ldb_parse_tree *tree,
- enum ldb_scope scope)
+ enum ldb_scope scope, bool *matched)
{
unsigned int i;
- int v;
+ int ret;
+
+ *matched = false;
switch (tree->operation) {
case LDB_OP_AND:
for (i=0;i<tree->u.list.num_elements;i++) {
- v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope);
- if (!v) return 0;
+ ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
+ if (ret != LDB_SUCCESS) return ret;
+ if (!*matched) return LDB_SUCCESS;
}
- return 1;
+ *matched = true;
+ return LDB_SUCCESS;
case LDB_OP_OR:
for (i=0;i<tree->u.list.num_elements;i++) {
- v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope);
- if (v) return 1;
+ ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
+ if (ret != LDB_SUCCESS) return ret;
+ if (*matched) return LDB_SUCCESS;
}
- return 0;
+ *matched = false;
+ return LDB_SUCCESS;
case LDB_OP_NOT:
- return ! ldb_match_message(ldb, msg, tree->u.isnot.child, scope);
+ 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);
+ return ldb_match_equality(ldb, msg, tree, scope, matched);
case LDB_OP_SUBSTRING:
- return ldb_match_substring(ldb, msg, tree, scope);
+ return ldb_match_substring(ldb, msg, tree, scope, matched);
case LDB_OP_GREATER:
- return ldb_match_comparison(ldb, msg, tree, scope, 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);
+ return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
case LDB_OP_PRESENT:
- return ldb_match_present(ldb, msg, tree, scope);
+ return ldb_match_present(ldb, msg, tree, scope, matched);
case LDB_OP_APPROX:
- return ldb_match_comparison(ldb, msg, tree, scope, 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);
-
+ return ldb_match_extended(ldb, msg, tree, scope, matched);
}
- return 0;
+ return LDB_ERR_INAPPROPRIATE_MATCHING;
}
int ldb_match_msg(struct ldb_context *ldb,
@@ -420,9 +519,52 @@ int ldb_match_msg(struct ldb_context *ldb,
struct ldb_dn *base,
enum ldb_scope scope)
{
+ bool matched;
+ int ret;
+
if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
return 0;
}
- return ldb_match_message(ldb, msg, tree, scope);
+ 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
index ea29a09a2a..b382a91ec8 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -33,22 +33,11 @@
#include "ldb_private.h"
#include "dlinklist.h"
-
-#define LDB_MODULE_PREFIX "modules:"
-#define LDB_MODULE_PREFIX_LEN 8
-
-static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
- const char *symbol);
-
-void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
-{
- talloc_free(ldb->modules_dir);
- ldb->modules_dir = talloc_strdup(ldb, path);
-}
+#include "system/dir.h"
static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string)
{
- int i, len;
+ size_t i, len;
char *trimmed;
trimmed = talloc_strdup(mem_ctx, string);
@@ -79,7 +68,7 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
char **modules = NULL;
const char **m;
char *modstr, *p;
- int i;
+ unsigned int i;
/* spaces not admitted */
modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
@@ -96,6 +85,12 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
}
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) {
@@ -130,29 +125,13 @@ static struct ops_list_entry {
struct ops_list_entry *next;
} *registered_modules = NULL;
-static const struct ldb_builtins {
- const struct ldb_backend_ops *backend_ops;
- const struct ldb_module_ops *module_ops;
-} builtins[];
-
-static ldb_connect_fn ldb_find_backend(const char *url)
+static struct backends_list_entry *ldb_find_backend(const char *url_prefix)
{
struct backends_list_entry *backend;
- int i;
-
- for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
- if (builtins[i].backend_ops == NULL) continue;
-
- if (strncmp(builtins[i].backend_ops->name, url,
- strlen(builtins[i].backend_ops->name)) == 0) {
- return builtins[i].backend_ops->connect_fn;
- }
- }
for (backend = ldb_backends; backend; backend = backend->next) {
- if (strncmp(backend->ops->name, url,
- strlen(backend->ops->name)) == 0) {
- return backend->ops->connect_fn;
+ if (strcmp(backend->ops->name, url_prefix) == 0) {
+ return backend;
}
}
@@ -160,32 +139,34 @@ static ldb_connect_fn ldb_find_backend(const char *url)
}
/*
- register a new ldb backend
+ 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)
+int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override)
{
- struct ldb_backend_ops *backend;
- struct backends_list_entry *entry;
-
- backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);
- if (!backend) return LDB_ERR_OPERATIONS_ERROR;
+ struct backends_list_entry *be;
- entry = talloc(talloc_autofree_context(), struct backends_list_entry);
- if (!entry) {
- talloc_free(backend);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ldb_find_backend(url_prefix)) {
- return LDB_SUCCESS;
+ 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);
}
- /* Maybe check for duplicity here later on? */
-
- backend->name = talloc_strdup(backend, url_prefix);
- backend->connect_fn = connectfn;
- entry->ops = backend;
- DLIST_ADD(ldb_backends, entry);
+ be->ops->name = url_prefix;
+ be->ops->connect_fn = connectfn;
return LDB_SUCCESS;
}
@@ -204,14 +185,14 @@ int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
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_connect_backend(struct ldb_context *ldb,
- const char *url,
- const char *options[],
- struct ldb_module **backend_module)
+int ldb_module_connect_backend(struct ldb_context *ldb,
+ const char *url,
+ const char *options[],
+ struct ldb_module **backend_module)
{
int ret;
char *backend;
- ldb_connect_fn fn;
+ struct backends_list_entry *be;
if (strchr(url, ':') != NULL) {
backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
@@ -220,50 +201,65 @@ int ldb_connect_backend(struct ldb_context *ldb,
backend = talloc_strdup(ldb, "tdb");
}
- fn = ldb_find_backend(backend);
-
- if (fn == NULL) {
- struct ldb_backend_ops *ops;
- char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend);
- if (symbol_name == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ops = ldb_dso_load_symbol(ldb, backend, symbol_name);
- if (ops != NULL) {
- fn = ops->connect_fn;
- }
- talloc_free(symbol_name);
- }
+ be = ldb_find_backend(backend);
talloc_free(backend);
- if (fn == NULL) {
+ if (be == NULL) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to find backend for '%s'", url);
+ "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url);
return LDB_ERR_OTHER;
}
- ret = fn(ldb, url, ldb->flags, options, backend_module);
+ 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'", url);
+ "Failed to connect to '%s' with backend '%s'", url, be->ops->name);
return ret;
}
return ret;
}
-static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
-{
- struct ops_list_entry *e;
- int i;
+static struct ldb_hooks {
+ struct ldb_hooks *next, *prev;
+ ldb_hook_fn hook_fn;
+} *ldb_hooks;
- for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
- if (builtins[i].module_ops == NULL) continue;
+/*
+ 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;
+}
- if (strcmp(builtins[i].module_ops->name, name) == 0)
- return builtins[i].module_ops;
+/*
+ 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)
@@ -276,11 +272,12 @@ static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
int ldb_register_module(const struct ldb_module_ops *ops)
{
- struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
+ struct ops_list_entry *entry;
if (ldb_find_module_ops(ops->name) != NULL)
- return -1;
+ return LDB_ERR_ENTRY_ALREADY_EXISTS;
+ entry = talloc(talloc_autofree_context(), struct ops_list_entry);
if (entry == NULL)
return -1;
@@ -291,47 +288,18 @@ int ldb_register_module(const struct ldb_module_ops *ops)
return 0;
}
-static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
- const char *symbol)
-{
- char *path;
- void *handle;
- void *sym;
-
- if (ldb->modules_dir == NULL)
- return NULL;
-
- path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name,
- SHLIBEXT);
-
- ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path);
-
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror());
- return NULL;
- }
-
- sym = (int (*)(void))dlsym(handle, symbol);
-
- if (sym == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror());
- return NULL;
- }
-
- talloc_free(path);
-
- return sym;
-}
-
-int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
+/*
+ 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;
- int i;
+ unsigned int i;
module = backend;
- for (i = 0; module_list[i] != NULL; i++) {
+ for (i = 0; module_list && module_list[i] != NULL; i++) {
struct ldb_module *current;
const struct ldb_module_ops *ops;
@@ -340,20 +308,11 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
}
ops = ldb_find_module_ops(module_list[i]);
- if (ops == NULL) {
- char *symbol_name = talloc_asprintf(ldb, "ldb_%s_module_ops",
- module_list[i]);
- if (symbol_name == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ops = ldb_dso_load_symbol(ldb, module_list[i], symbol_name);
- talloc_free(symbol_name);
- }
if (ops == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found",
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?",
module_list[i]);
- continue;
+ return LDB_ERR_OPERATIONS_ERROR;
}
current = talloc_zero(ldb, struct ldb_module);
@@ -371,7 +330,10 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
return LDB_SUCCESS;
}
-int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
+/*
+ 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;
@@ -382,7 +344,8 @@ int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
if (module) {
int ret = module->ops->init_context(module);
if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name);
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s",
+ module->ops->name, ldb_strerror(ret));
return ret;
}
}
@@ -392,8 +355,8 @@ int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
int ldb_load_modules(struct ldb_context *ldb, const char *options[])
{
+ const char *modules_string;
const char **modules = NULL;
- int i;
int ret;
TALLOC_CTX *mem_ctx = talloc_new(ldb);
if (!mem_ctx) {
@@ -404,10 +367,9 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
/* check if we have a custom module list passd as ldb option */
if (options) {
- for (i = 0; options[i] != NULL; i++) {
- if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
- modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]);
- }
+ modules_string = ldb_options_find(ldb, options, "modules");
+ if (modules_string) {
+ modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string);
}
}
@@ -453,7 +415,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
}
if (modules != NULL) {
- ret = ldb_load_modules_list(ldb, modules, ldb->modules, &ldb->modules);
+ ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules);
if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);
return ret;
@@ -462,7 +424,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database");
}
- ret = ldb_init_module_chain(ldb, ldb->modules);
+ ret = ldb_module_init_chain(ldb, ldb->modules);
talloc_free(mem_ctx);
return ret;
}
@@ -475,6 +437,10 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
#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 { \
@@ -517,6 +483,11 @@ 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;
@@ -591,7 +562,7 @@ int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
* all our modules, and leaves us one less sharp
* corner for module developers to cut themselves on
*/
- ldb_module_done(request, NULL, NULL, ret);
+ ret = ldb_module_done(request, NULL, NULL, ret);
}
return ret;
}
@@ -600,36 +571,88 @@ int ldb_next_init(struct ldb_module *module)
{
module = module->next;
- return ldb_init_module_chain(module->ldb, module);
+ return ldb_module_init_chain(module->ldb, module);
}
int ldb_next_start_trans(struct ldb_module *module)
{
+ int ret;
FIND_OP(module, start_transaction);
- return module->ops->start_transaction(module);
+ 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);
- return module->ops->end_transaction(module);
+ 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;
}
- return module->ops->prepare_commit(module);
+ 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);
- return module->ops->del_transaction(module);
+ 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)
@@ -646,6 +669,8 @@ struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb)
h->state = LDB_ASYNC_INIT;
h->ldb = ldb;
h->flags = 0;
+ h->location = NULL;
+ h->parent = NULL;
return h;
}
@@ -728,7 +753,7 @@ int ldb_module_send_referral(struct ldb_request *req,
* 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 succesful return
+ * error: LDB_SUCCESS for a successful return
* any other ldb error otherwise
*/
int ldb_module_done(struct ldb_request *req,
@@ -762,12 +787,11 @@ int ldb_module_done(struct ldb_request *req,
ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE);
}
- req->callback(req, ares);
- return error;
+ return req->callback(req, ares);
}
/* to be used *only* in modules init functions.
- * this function i synchronous and will register
+ * 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)
@@ -800,70 +824,319 @@ int ldb_mod_register_control(struct ldb_module *module, const char *oid)
return ret;
}
-#ifndef STATIC_LIBLDB_MODULES
+static int ldb_modules_load_dir(const char *modules_dir, const char *version);
-#ifdef HAVE_LDB_LDAP
-#define LDAP_BACKEND LDB_BACKEND(ldap), LDB_BACKEND(ldapi), LDB_BACKEND(ldaps),
-#else
-#define LDAP_BACKEND
-#endif
-#ifdef HAVE_LDB_SQLITE3
-#define SQLITE3_BACKEND LDB_BACKEND(sqlite3),
-#else
-#define SQLITE3_BACKEND
-#endif
+/*
+ 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);
-#define STATIC_LIBLDB_MODULES \
- LDB_BACKEND(tdb), \
- LDAP_BACKEND \
- SQLITE3_BACKEND \
- LDB_MODULE(rdn_name), \
- LDB_MODULE(paged_results), \
- LDB_MODULE(server_sort), \
- LDB_MODULE(asq), \
- NULL
+ /* 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; i<num_modules; i++) {
+ int ret = ldb_modules_load_path(modlist[i], version);
+ if (ret != LDB_SUCCESS) {
+ fprintf(stderr, "ldb: failed to initialise module %s : %s\n",
+ modlist[i], ldb_strerror(ret));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+
+ return LDB_SUCCESS;
+}
+
+/*
+ load any additional modules from the given directory
+*/
+void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
+{
+ int ret = ldb_modules_load_path(path, LDB_VERSION);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb, "Failed to load modules from: %s\n", path);
+ }
+}
+
+
+/*
+ load all modules static (builtin) modules
+ */
+static int ldb_modules_load_static(const char *version)
+{
+ static bool initialised;
+#define _MODULE_PROTO(init) extern int init(const char *);
+ STATIC_ldb_MODULES_PROTO;
+ const ldb_module_init_fn static_init_functions[] = { STATIC_ldb_MODULES };
+ unsigned i;
+
+ if (initialised) {
+ return LDB_SUCCESS;
+ }
+ initialised = true;
+
+ for (i=0; static_init_functions[i]; i++) {
+ int ret = static_init_functions[i](version);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ return LDB_SUCCESS;
+}
+
/*
- * this is a bit hacked, as STATIC_LIBLDB_MODULES contains ','
- * between the elements and we want to autogenerate the
- * extern struct declarations, so we do some hacks and let the
- * ',' appear in an unused function prototype.
+ load all modules from the given ldb modules path, colon
+ separated.
+
+ modules are loaded recursively for all subdirectories in the paths
*/
-#undef NULL
-#define NULL LDB_MODULE(NULL),
-
-#define LDB_BACKEND(name) \
- int); \
- extern const struct ldb_backend_ops ldb_ ## name ## _backend_ops;\
- extern void ldb_noop ## name (int
-#define LDB_MODULE(name) \
- int); \
- extern const struct ldb_module_ops ldb_ ## name ## _module_ops;\
- extern void ldb_noop ## name (int
-
-extern void ldb_start_noop(int,
-STATIC_LIBLDB_MODULES
-int);
-
-#undef NULL
-#define NULL { \
- .backend_ops = (void *)0, \
- .module_ops = (void *)0 \
-}
-
-#undef LDB_BACKEND
-#define LDB_BACKEND(name) { \
- .backend_ops = &ldb_ ## name ## _backend_ops, \
- .module_ops = (void *)0 \
-}
-#undef LDB_MODULE
-#define LDB_MODULE(name) { \
- .backend_ops = (void *)0, \
- .module_ops = &ldb_ ## name ## _module_ops \
-}
-
-static const struct ldb_builtins builtins[] = {
- STATIC_LIBLDB_MODULES
-};
+int ldb_modules_load(const char *modules_path, const char *version)
+{
+ char *tok, *path, *tok_ptr=NULL;
+ int ret;
+
+ ret = ldb_modules_load_static(version);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ path = talloc_strdup(NULL, modules_path);
+ if (path == NULL) {
+ fprintf(stderr, "ldb: failed to allocate modules_path\n");
+ return LDB_ERR_UNAVAILABLE;
+ }
+
+ for (tok=strtok_r(path, ":", &tok_ptr);
+ tok;
+ tok=strtok_r(NULL, ":", &tok_ptr)) {
+ ret = ldb_modules_load_path(tok, version);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(path);
+ return ret;
+ }
+ }
+ talloc_free(path);
+
+ return LDB_SUCCESS;
+}
+
+
+/*
+ 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)
+{
+ char *ret;
+ int i=0;
+
+ ret = talloc_strdup(mem_ctx, "");
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ while (req && req->handle) {
+ 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
index 702978a361..d1c77f89bc 100644
--- a/source4/lib/ldb/common/ldb_msg.c
+++ b/source4/lib/ldb/common/ldb_msg.c
@@ -36,7 +36,7 @@
/*
create a new ldb_message in a given memory context (NULL for top level)
*/
-struct ldb_message *ldb_msg_new(void *mem_ctx)
+struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx)
{
return talloc_zero(mem_ctx, struct ldb_message);
}
@@ -63,7 +63,7 @@ struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg,
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) {
@@ -92,7 +92,7 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
/*
duplicate a ldb_val structure
*/
-struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v)
+struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v)
{
struct ldb_val v2;
v2.length = v->length;
@@ -114,58 +114,94 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v)
return v2;
}
-/*
- add an empty element to a message
-*/
-int ldb_msg_add_empty( struct ldb_message *msg,
- const char *attr_name,
- int flags,
- struct ldb_message_element **return_el)
+/**
+ * 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;
- els = talloc_realloc(msg, msg->elements,
- struct ldb_message_element, msg->num_elements+1);
+ /*
+ * 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) {
errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
}
- els[msg->num_elements].values = NULL;
- els[msg->num_elements].num_values = 0;
- els[msg->num_elements].flags = flags;
- els[msg->num_elements].name = talloc_strdup(els, attr_name);
- if (!els[msg->num_elements].name) {
- errno = ENOMEM;
- 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) {
+ errno = ENOMEM;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
if (return_el) {
- *return_el = &els[msg->num_elements-1];
+ *return_el = el;
}
return LDB_SUCCESS;
}
-/*
- add an empty element to a message
-*/
+/**
+ * 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;
- if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
+
+ ret = _ldb_msg_add_el(msg, &el_new);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- msg->elements[msg->num_elements-1] = el_copy;
- msg->elements[msg->num_elements-1].flags = flags;
+ 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;
}
@@ -190,7 +226,8 @@ int ldb_msg_add_value(struct ldb_message *msg,
}
}
- vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1);
+ vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
+ el->num_values+1);
if (!vals) {
errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
@@ -237,7 +274,7 @@ int ldb_msg_add_string(struct ldb_message *msg,
val.length = strlen(str);
if (val.length == 0) {
- /* allow empty strings as non-existant attributes */
+ /* allow empty strings as non-existent attributes */
return LDB_SUCCESS;
}
@@ -255,10 +292,33 @@ int ldb_msg_add_steal_string(struct ldb_message *msg,
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,
@@ -282,7 +342,7 @@ int ldb_msg_add_fmt(struct ldb_message *msg,
/*
compare two ldb_message_element structures
- assumes case senistive comparison
+ assumes case sensitive comparison
*/
int ldb_msg_element_compare(struct ldb_message_element *el1,
struct ldb_message_element *el2)
@@ -341,10 +401,19 @@ unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg,
const char *attr_name,
unsigned int default_value)
{
+ unsigned int ret;
const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
if (!v || !v->data) {
return default_value;
}
+
+ /* in LDAP there're only int32_t values */
+ errno = 0;
+ ret = strtol((const char *)v->data, NULL, 0);
+ if (errno == 0) {
+ return ret;
+ }
+
return strtoul((const char *)v->data, NULL, 0);
}
@@ -363,10 +432,19 @@ uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg,
const char *attr_name,
uint64_t default_value)
{
+ uint64_t ret;
const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
if (!v || !v->data) {
return default_value;
}
+
+ /* in LDAP there're only int64_t values */
+ errno = 0;
+ ret = strtoll((const char *)v->data, NULL, 0);
+ if (errno == 0) {
+ return ret;
+ }
+
return strtoull((const char *)v->data, NULL, 0);
}
@@ -410,7 +488,7 @@ const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg,
}
struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
- void *mem_ctx,
+ TALLOC_CTX *mem_ctx,
const struct ldb_message *msg,
const char *attr_name)
{
@@ -434,8 +512,8 @@ struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
*/
void ldb_msg_sort_elements(struct ldb_message *msg)
{
- qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element),
- (comparison_fn_t)ldb_msg_element_compare_name);
+ TYPESAFE_QSORT(msg->elements, msg->num_elements,
+ ldb_msg_element_compare_name);
}
/*
@@ -446,7 +524,7 @@ struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx,
const struct ldb_message *msg)
{
struct ldb_message *msg2;
- int i;
+ unsigned int i;
msg2 = talloc(mem_ctx, struct ldb_message);
if (msg2 == NULL) return NULL;
@@ -476,7 +554,7 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
const struct ldb_message *msg)
{
struct ldb_message *msg2;
- int i, j;
+ unsigned int i, j;
msg2 = ldb_msg_copy_shallow(mem_ctx, msg);
if (msg2 == NULL) return NULL;
@@ -506,36 +584,64 @@ failed:
}
-/*
- canonicalise a message, merging elements of the same name
-*/
+/**
+ * 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 i;
+ int ret;
struct ldb_message *msg2;
- msg2 = ldb_msg_copy(ldb, msg);
- if (msg2 == NULL) return NULL;
+ /*
+ * 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++) {
+ 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->values == NULL) {
- return NULL;
+ 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) *
+ if ((i+1) < msg2->num_elements) {
+ memmove(el2, el2+1, sizeof(struct ldb_message_element) *
(msg2->num_elements - (i+1)));
}
msg2->num_elements--;
@@ -543,35 +649,81 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
}
}
- return msg2;
+ *_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
-*/
+/**
+ * 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;
- struct ldb_message_element *el;
+
+ 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;
- mod = ldb_msg_new(ldb);
+ 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;
- msg2 = ldb_msg_canonicalize(ldb, msg2);
- if (msg2 == NULL) {
- return 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 */
+
+ /* look in msg2 to find elements that need to be added or modified */
for (i=0;i<msg2->num_elements;i++) {
el = ldb_msg_find_element(msg1, msg2->elements[i].name);
@@ -579,32 +731,44 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
continue;
}
- if (ldb_msg_add(mod,
- &msg2->elements[i],
- el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) {
- return NULL;
+ 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;i<msg1->num_elements;i++) {
el = ldb_msg_find_element(msg2, msg1->elements[i].name);
- if (!el) {
- if (ldb_msg_add_empty(mod,
- msg1->elements[i].name,
- LDB_FLAG_MOD_DELETE, NULL) != 0) {
- return NULL;
+ 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;
}
}
}
- return mod;
+ /* 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)
{
- int i, j;
+ unsigned int i, j;
/* basic check on DN */
if (msg->dn == NULL) {
@@ -642,7 +806,8 @@ int ldb_msg_sanity_check(struct ldb_context *ldb,
const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs)
{
const char **ret;
- int i;
+ unsigned int i;
+
for (i=0;attrs && attrs[i];i++) /* noop */ ;
ret = talloc_array(mem_ctx, const char *, i+1);
if (ret == NULL) {
@@ -663,8 +828,9 @@ 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)
{
const char **ret;
- int i;
+ unsigned int i;
bool found = false;
+
for (i=0;attrs && attrs[i];i++) {
if (ldb_attr_cmp(attrs[i], new_attr) == 0) {
found = true;
@@ -691,7 +857,7 @@ const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *att
*/
int ldb_attr_in_list(const char * const *attrs, const char *attr)
{
- int i;
+ unsigned int i;
for (i=0;attrs && attrs[i];i++) {
if (ldb_attr_cmp(attrs[i], attr) == 0) {
return 1;
@@ -724,11 +890,14 @@ int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *r
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;
}
- if (ldb_msg_add(msg, el, 0) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
+ ret = ldb_msg_add(msg, el, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
return ldb_msg_rename_attr(msg, attr, replace);
}
@@ -738,7 +907,7 @@ int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *rep
*/
void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el)
{
- int n = (el - msg->elements);
+ ptrdiff_t n = (el - msg->elements);
if (n >= msg->num_elements) {
/* should we abort() here? */
return;
@@ -755,8 +924,9 @@ void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element
*/
void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
{
- struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
- if (el) {
+ struct ldb_message_element *el;
+
+ while ((el = ldb_msg_find_element(msg, attr)) != NULL) {
ldb_msg_remove_element(msg, el);
}
}
@@ -802,7 +972,7 @@ time_t ldb_string_to_time(const char *s)
if (s == NULL) return 0;
memset(&tm, 0, sizeof(tm));
- if (sscanf(s, "%04u%02u%02u%02u%02u%02u",
+ 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;
@@ -814,6 +984,33 @@ 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)
+{
+ 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)
@@ -854,7 +1051,7 @@ time_t ldb_string_utc_to_time(const char *s)
if (s == NULL) return 0;
memset(&tm, 0, sizeof(tm));
- if (sscanf(s, "%02u%02u%02u%02u%02u%02u",
+ 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;
@@ -873,7 +1070,7 @@ time_t ldb_string_utc_to_time(const char *s)
*/
void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f)
{
- int i;
+ unsigned int i;
for (i = 0; i < result->count; i++) {
struct ldb_ldif ldif;
@@ -884,20 +1081,27 @@ void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *
}
}
-int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value)
+/*
+ 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)
+ if (el == NULL) {
return 0;
+ }
val.data = discard_const_p(uint8_t, value);
val.length = strlen(value);
- if (ldb_msg_find_val(el, &val))
+ 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
new file mode 100644
index 0000000000..f07f393562
--- /dev/null
+++ b/source4/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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * 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
index ba16b57da3..b4eabf8375 100644
--- a/source4/lib/ldb/common/ldb_parse.c
+++ b/source4/lib/ldb/common/ldb_parse.c
@@ -43,6 +43,26 @@
#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:
<filter> ::= '(' <filtercomp> ')'
@@ -59,11 +79,11 @@ a filter is defined by:
decode a RFC2254 binary string representation of a buffer.
Used in LDAP filters.
*/
-struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str)
+struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str)
{
- int i, j;
+ size_t i, j;
struct ldb_val ret;
- int slen = str?strlen(str):0;
+ size_t slen = str?strlen(str):0;
ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1);
ret.length = 0;
@@ -71,8 +91,10 @@ struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str)
for (i=j=0;i<slen;i++) {
if (str[i] == '\\') {
- unsigned c;
- if (sscanf(&str[i+1], "%02X", &c) != 1) {
+ int c;
+
+ c = ldb_parse_hex2char(&str[i+1]);
+ if (c == -1) {
talloc_free(ret.data);
memset(&ret, 0, sizeof(ret));
return ret;
@@ -94,11 +116,11 @@ struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str)
encode a blob as a RFC2254 binary string, escaping any
non-printable or '\' characters
*/
-char *ldb_binary_encode(void *mem_ctx, struct ldb_val val)
+char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val)
{
- int i;
+ size_t i;
char *ret;
- int len = val.length;
+ size_t len = val.length;
unsigned char *buf = val.data;
for (i=0;i<val.length;i++) {
@@ -129,9 +151,12 @@ char *ldb_binary_encode(void *mem_ctx, struct ldb_val val)
non-printable or '\' characters. This routine is suitable for use
in escaping user data in ldap filters.
*/
-char *ldb_binary_encode_string(void *mem_ctx, const char *string)
+char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string)
{
struct ldb_val val;
+ if (string == NULL) {
+ return NULL;
+ }
val.data = discard_const_p(uint8_t, string);
val.length = strlen(string);
return ldb_binary_encode(mem_ctx, val);
@@ -159,10 +184,10 @@ static char *ldb_parse_find_wildcard(char *value)
/* return a NULL terminated list of binary strings representing the value
chunks separated by wildcards that makes the value portion of the filter
*/
-static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string)
+static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *string)
{
struct ldb_val **ret = NULL;
- int val = 0;
+ unsigned int val = 0;
char *wc, *str;
wc = talloc_strdup(mem_ctx, string);
@@ -199,7 +224,7 @@ static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string)
return ret;
}
-static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s);
+static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s);
/*
@@ -253,7 +278,7 @@ failed:
return NULL;
}
-static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char **value, const char **s)
+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;
@@ -351,7 +376,7 @@ static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char *
/*
<simple> ::= <attributetype> <filtertype> <attributevalue>
*/
-static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s)
+static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s)
{
char *attr, *value;
struct ldb_parse_tree *ret;
@@ -466,7 +491,7 @@ static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s)
<or> ::= '|' <filterlist>
<filterlist> ::= <filter> | <filter> <filterlist>
*/
-static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, const char **s)
+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;
@@ -534,7 +559,7 @@ static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, const char **s
/*
<not> ::= '!' <filter>
*/
-static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char **s)
+static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s)
{
struct ldb_parse_tree *ret;
const char *p = *s;
@@ -566,7 +591,7 @@ static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char **s)
parse a filtercomp
<filtercomp> ::= <and> | <or> | <not> | <simple>
*/
-static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char **s)
+static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s)
{
struct ldb_parse_tree *ret;
const char *p = *s;
@@ -603,7 +628,7 @@ static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char **s
/*
<filter> ::= '(' <filtercomp> ')'
*/
-static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s)
+static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s)
{
struct ldb_parse_tree *ret;
const char *p = *s;
@@ -635,7 +660,7 @@ static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s)
expression ::= <simple> | <filter>
*/
-struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s)
+struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s)
{
if (s == NULL || *s == 0) {
s = "(|(objectClass=*)(distinguishedName=*))";
@@ -654,10 +679,10 @@ struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s)
/*
construct a ldap parse filter given a parse tree
*/
-char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree)
+char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree)
{
char *s, *s2, *ret;
- int i;
+ unsigned int i;
if (tree == NULL) {
return NULL;
@@ -773,14 +798,14 @@ char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree)
/*
- replace any occurances of an attribute name in the parse tree with a
+ 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)
{
- int i;
+ unsigned int i;
switch (tree->operation) {
case LDB_OP_AND:
case LDB_OP_OR:
@@ -826,7 +851,7 @@ void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree,
struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx,
const struct ldb_parse_tree *ot)
{
- int i;
+ unsigned int i;
struct ldb_parse_tree *nt;
nt = talloc(mem_ctx, struct ldb_parse_tree);
diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c
index 0a8a89ac1d..55d8f905d3 100644
--- a/source4/lib/ldb/common/ldb_utf8.c
+++ b/source4/lib/ldb/common/ldb_utf8.c
@@ -53,9 +53,9 @@ void ldb_set_utf8_fns(struct ldb_context *ldb,
a simple case folding function
NOTE: does not handle UTF8
*/
-char *ldb_casefold_default(void *context, void *mem_ctx, const char *s, size_t n)
+char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n)
{
- int i;
+ size_t i;
char *ret = talloc_strndup(mem_ctx, s, n);
if (!s) {
errno = ENOMEM;
@@ -72,7 +72,7 @@ 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, void *mem_ctx, const char *s, size_t n)
+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);
}
@@ -84,7 +84,7 @@ char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s, size_t
int ldb_valid_attr_name(const char *s)
{
- int i;
+ size_t i;
if (!s || !s[0])
return 0;
@@ -109,9 +109,9 @@ int ldb_valid_attr_name(const char *s)
return 1;
}
-char *ldb_attr_casefold(void *mem_ctx, const char *s)
+char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s)
{
- int i;
+ size_t i;
char *ret = talloc_strdup(mem_ctx, s);
if (!ret) {
errno = ENOMEM;
diff --git a/source4/lib/ldb/config.guess b/source4/lib/ldb/config.guess
deleted file mode 100755
index da83314608..0000000000
--- a/source4/lib/ldb/config.guess
+++ /dev/null
@@ -1,1561 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-
-timestamp='2009-04-27'
-
-# This file 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[456])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- EM64T | authenticamd | genuineintel)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk
deleted file mode 100644
index 4a1f814baa..0000000000
--- a/source4/lib/ldb/config.mk
+++ /dev/null
@@ -1,139 +0,0 @@
-################################################
-# Start MODULE ldb_asq
-[MODULE::ldb_asq]
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-CFLAGS = -I$(ldbsrcdir)/include
-INIT_FUNCTION = LDB_MODULE(asq)
-SUBSYSTEM = LIBLDB
-
-ldb_asq_OBJ_FILES = $(ldbsrcdir)/modules/asq.o
-# End MODULE ldb_asq
-################################################
-
-################################################
-# Start MODULE ldb_server_sort
-[MODULE::ldb_server_sort]
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-CFLAGS = -I$(ldbsrcdir)/include
-INIT_FUNCTION = LDB_MODULE(server_sort)
-SUBSYSTEM = LIBLDB
-
-# End MODULE ldb_sort
-################################################
-ldb_server_sort_OBJ_FILES = $(ldbsrcdir)/modules/sort.o
-
-################################################
-# Start MODULE ldb_paged_results
-[MODULE::ldb_paged_results]
-INIT_FUNCTION = LDB_MODULE(paged_results)
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-SUBSYSTEM = LIBLDB
-# End MODULE ldb_paged_results
-################################################
-
-ldb_paged_results_OBJ_FILES = $(ldbsrcdir)/modules/paged_results.o
-
-################################################
-# Start MODULE ldb_paged_results
-[MODULE::ldb_paged_searches]
-INIT_FUNCTION = LDB_MODULE(paged_searches)
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-SUBSYSTEM = LIBLDB
-# End MODULE ldb_paged_results
-################################################
-
-ldb_paged_searches_OBJ_FILES = $(ldbsrcdir)/modules/paged_searches.o
-
-################################################
-# Start MODULE ldb_rdn_name
-[MODULE::ldb_rdn_name]
-SUBSYSTEM = LIBLDB
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-INIT_FUNCTION = LDB_MODULE(rdn_name)
-# End MODULE ldb_rdn_name
-################################################
-
-ldb_rdn_name_OBJ_FILES = $(ldbsrcdir)/modules/rdn_name.o
-
-ldb_map_OBJ_FILES = $(addprefix $(ldbsrcdir)/ldb_map/, ldb_map_inbound.o ldb_map_outbound.o ldb_map.o)
-
-$(ldb_map_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/ldb_map
-
-################################################
-# Start MODULE ldb_skel
-[MODULE::ldb_skel]
-SUBSYSTEM = LIBLDB
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
-INIT_FUNCTION = LDB_MODULE(skel)
-# End MODULE ldb_skel
-################################################
-
-ldb_skel_OBJ_FILES = $(ldbsrcdir)/modules/skel.o
-
-################################################
-# Start MODULE ldb_sqlite3
-[MODULE::ldb_sqlite3]
-SUBSYSTEM = LIBLDB
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC SQLITE3 LIBTEVENT
-INIT_FUNCTION = LDB_BACKEND(sqlite3)
-# End MODULE ldb_sqlite3
-################################################
-
-ldb_sqlite3_OBJ_FILES = $(ldbsrcdir)/ldb_sqlite3/ldb_sqlite3.o
-
-################################################
-# Start MODULE ldb_tdb
-[MODULE::ldb_tdb]
-SUBSYSTEM = LIBLDB
-CFLAGS = -I$(ldbsrcdir)/include -I$(ldbsrcdir)/ldb_tdb
-PRIVATE_DEPENDENCIES = \
- LIBTDB LIBTALLOC LIBTEVENT
-INIT_FUNCTION = LDB_BACKEND(tdb)
-# End MODULE ldb_tdb
-################################################
-
-ldb_tdb_OBJ_FILES = $(addprefix $(ldbsrcdir)/ldb_tdb/, ldb_tdb.o ldb_search.o ldb_pack.o ldb_index.o ldb_cache.o ldb_tdb_wrap.o)
-
-
-################################################
-# Start SUBSYSTEM ldb
-[LIBRARY::LIBLDB]
-CFLAGS = -I$(ldbsrcdir)/include
-PUBLIC_DEPENDENCIES = \
- LIBTALLOC LIBTEVENT
-PRIVATE_DEPENDENCIES = \
- SOCKET_WRAPPER
-
-PC_FILES += $(ldbsrcdir)/ldb.pc
-#
-# End SUBSYSTEM ldb
-################################################
-
-LIBLDB_VERSION = 0.0.1
-LIBLDB_SOVERSION = 0
-
-LIBLDB_OBJ_FILES = $(addprefix $(ldbsrcdir)/common/, ldb.o ldb_ldif.o ldb_parse.o ldb_msg.o ldb_utf8.o ldb_debug.o ldb_modules.o ldb_match.o ldb_attributes.o attrib_handlers.o ldb_dn.o ldb_controls.o qsort.o) $(ldb_map_OBJ_FILES)
-
-$(LIBLDB_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
-
-PUBLIC_HEADERS += $(ldbsrcdir)/include/ldb.h $(ldbsrcdir)/include/ldb_errors.h
-
-MANPAGES += $(ldbsrcdir)/man/ldb.3
-
-################################################
-# Start BINARY ldbtest
-[BINARY::ldbtest]
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbtest
-################################################
-
-ldbtest_OBJ_FILES = $(ldbsrcdir)/tools/ldbtest.o
-
-mkinclude tools/config.mk
-mkinclude ldb_ildap/config.mk
diff --git a/source4/lib/ldb/config.sub b/source4/lib/ldb/config.sub
deleted file mode 100755
index a39437d015..0000000000
--- a/source4/lib/ldb/config.sub
+++ /dev/null
@@ -1,1686 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-
-timestamp='2009-04-17'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nios | nios2 \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
- | we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nios-* | nios2-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- tile*)
- basic_machine=tile-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -kopensolaris* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/source4/lib/ldb/configure b/source4/lib/ldb/configure
new file mode 100755
index 0000000000..137a26bcbe
--- /dev/null
+++ b/source4/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/source4/lib/ldb/configure.ac b/source4/lib/ldb/configure.ac
deleted file mode 100644
index a0fab6d786..0000000000
--- a/source4/lib/ldb/configure.ac
+++ /dev/null
@@ -1,102 +0,0 @@
-AC_PREREQ(2.50)
-AC_DEFUN([AC_CHECK_LIB_EXT], [
- AC_CHECK_LIB([$1],[$3],[$4],[$5],[$7])
- ac_cv_lib_ext_$1_$3=$ac_cv_lib_$1_$3
-])
-AC_DEFUN([AC_CHECK_FUNC_EXT], [
- AC_CHECK_FUNC([$1],[$3],[$4])
- ac_cv_func_ext_$1=$ac_cv_func_$1
-])
-AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
-AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
-AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
-AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_INIT(ldb, 0.9.7)
-AC_CONFIG_SRCDIR([common/ldb.c])
-
-AC_LIBREPLACE_ALL_CHECKS
-
-if test "$ac_cv_prog_gcc" = yes; then
- CFLAGS="$CFLAGS -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings"
-fi
-
-WITH_GCOV=0
-AC_ARG_ENABLE(gcov,
- AS_HELP_STRING([--enable-gcov],[enable GCOV code coverage tests]),
- [ WITH_GCOV=1])
-AC_SUBST(WITH_GCOV)
-if test x"$with_gcov_support" = x"yes"; then
- CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs"
- LIBS="$LIBS -lgcov"
-fi
-
-AC_PATH_PROG(XSLTPROC,xsltproc)
-AC_PATH_PROG(DOXYGEN,doxygen)
-AC_PATH_PROG(GCOV,gcov)
-AC_PATH_PROG(SLAPD,slapd)
-AC_CHECK_HEADERS(stdint.h dlfcn.h)
-AC_CONFIG_HEADER(include/config.h)
-
-LDB_MODULESDIR="${libdir}/ldb"
-AC_SUBST(LDB_MODULESDIR)
-
-TESTS=""
-EXTRA_OBJ=""
-
-m4_include(build_macros.m4)
-BUILD_WITH_SHARED_BUILD_DIR
-
-m4_include(pkg.m4)
-m4_include(libpopt.m4)
-m4_include(libtalloc.m4)
-m4_include(libtdb.m4)
-m4_include(libevents.m4)
-
-m4_include(ldap.m4)
-if test x"$with_ldap_support" = x"yes"; then
- CFLAGS="$CFLAGS -DHAVE_LDB_LDAP=1"
- EXTRA_OBJ="$EXTRA_OBJ ldb_ldap/ldb_ldap.o"
- LDAP_LIBS="-llber -lldap"
- AC_SUBST(LDAP_LIBS)
- TESTS="$TESTS test-ldap.sh"
-fi
-
-m4_include(sqlite3.m4)
-if test x"$with_sqlite3_support" = x"yes"; then
- LIBS="$LIBS -lsqlite3"
- CFLAGS="$CFLAGS -DHAVE_LDB_SQLITE3=1"
- EXTRA_OBJ="$EXTRA_OBJ ldb_sqlite3/ldb_sqlite3.o"
- TESTS="$TESTS test-sqlite3.sh"
-fi
-
-AC_SUBST(TESTS)
-AC_SUBST(EXTRA_OBJ)
-
-AC_LD_EXPORT_DYNAMIC
-AC_LD_PICFLAG
-AC_LD_SHLIBEXT
-AC_LD_SONAMEFLAG
-AC_LIBREPLACE_SHLD
-AC_LIBREPLACE_SHLD_FLAGS
-AC_LIBREPLACE_MDLD
-AC_LIBREPLACE_MDLD_FLAGS
-AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR
-
-AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config])
-AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python])
-
-PYTHON_BUILD_TARGET="build-python"
-PYTHON_INSTALL_TARGET="install-python"
-PYTHON_CHECK_TARGET="check-python"
-AC_SUBST(PYTHON_BUILD_TARGET)
-AC_SUBST(PYTHON_INSTALL_TARGET)
-AC_SUBST(PYTHON_CHECK_TARGET)
-
-if test -z "$PYTHON_CONFIG"; then
- PYTHON_BUILD_TARGET=""
- PYTHON_CHECK_TARGET=""
- PYTHON_INSTALL_TARGET=""
-fi
-
-m4_include(libldb.m4)
-AC_OUTPUT(Makefile ldb.pc)
diff --git a/source4/lib/ldb/external/libevents.m4 b/source4/lib/ldb/external/libevents.m4
deleted file mode 100644
index af046f1430..0000000000
--- a/source4/lib/ldb/external/libevents.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-AC_SUBST(TEVENT_OBJ)
-AC_SUBST(TEVENT_CFLAGS)
-AC_SUBST(TEVENT_LIBS)
-
-AC_CHECK_HEADER(tevent.h,
- [AC_CHECK_LIB(tevent, tevent_context_init, [TEVENT_LIBS="-ltevent"], , -ltalloc) ],
- [PKG_CHECK_MODULES(TEVENT, tevent)])
diff --git a/source4/lib/ldb/external/libpopt.m4 b/source4/lib/ldb/external/libpopt.m4
deleted file mode 100644
index c5d12550ab..0000000000
--- a/source4/lib/ldb/external/libpopt.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-POPT_OBJ=""
-AC_SUBST(POPT_OBJ)
-AC_SUBST(POPT_LIBS)
-AC_SUBST(POPT_CFLAGS)
-
-AC_CHECK_HEADERS(popt.h)
-AC_CHECK_LIB(popt, poptGetContext, [ POPT_LIBS="-lpopt" ])
diff --git a/source4/lib/ldb/external/libtalloc.m4 b/source4/lib/ldb/external/libtalloc.m4
deleted file mode 100644
index 8c63fcc041..0000000000
--- a/source4/lib/ldb/external/libtalloc.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-AC_SUBST(TALLOC_OBJ)
-AC_SUBST(TALLOC_CFLAGS)
-AC_SUBST(TALLOC_LIBS)
-
-PKG_CHECK_MODULES(TALLOC, talloc >= 2.0.0,
- [ ],
- [ AC_CHECK_HEADER(talloc.h,
- [ AC_CHECK_LIB(talloc, talloc_init, [TALLOC_LIBS="-ltalloc"])])])
diff --git a/source4/lib/ldb/external/libtdb.m4 b/source4/lib/ldb/external/libtdb.m4
deleted file mode 100644
index 44971e1fa9..0000000000
--- a/source4/lib/ldb/external/libtdb.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-AC_SUBST(TDB_OBJ)
-AC_SUBST(TDB_CFLAGS)
-AC_SUBST(TDB_LIBS)
-
-AC_CHECK_HEADER(tdb.h,
- [AC_CHECK_LIB(tdb, tdb_open, [TDB_LIBS="-ltdb"]) ],
- [PKG_CHECK_MODULES(TDB, tdb >= 1.1.6)])
diff --git a/source4/lib/ldb/external/pkg.m4 b/source4/lib/ldb/external/pkg.m4
deleted file mode 100644
index a8b3d06c81..0000000000
--- a/source4/lib/ldb/external/pkg.m4
+++ /dev/null
@@ -1,156 +0,0 @@
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-#
-# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# PKG_PROG_PKG_CONFIG([MIN-VERSION])
-# ----------------------------------
-AC_DEFUN([PKG_PROG_PKG_CONFIG],
-[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
-AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
- AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
-fi
-if test -n "$PKG_CONFIG"; then
- _pkg_min_version=m4_default([$1], [0.9.0])
- AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- PKG_CONFIG=""
- fi
-
-fi[]dnl
-])# PKG_PROG_PKG_CONFIG
-
-# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-#
-# Check to see whether a particular set of modules exists. Similar
-# to PKG_CHECK_MODULES(), but does not set variables or print errors.
-#
-#
-# Similar to PKG_CHECK_MODULES, make sure that the first instance of
-# this or PKG_CHECK_MODULES is called, or make sure to call
-# PKG_CHECK_EXISTS manually
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_EXISTS],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-if test -n "$PKG_CONFIG" && \
- AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
- m4_ifval([$2], [$2], [:])
-m4_ifvaln([$3], [else
- $3])dnl
-fi])
-
-
-# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-# ---------------------------------------------
-m4_define([_PKG_CONFIG],
-[if test -n "$PKG_CONFIG"; then
- if test -n "$$1"; then
- pkg_cv_[]$1="$$1"
- else
- PKG_CHECK_EXISTS([$3],
- [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
- [pkg_failed=yes])
- fi
-else
- pkg_failed=untried
-fi[]dnl
-])# _PKG_CONFIG
-
-# _PKG_SHORT_ERRORS_SUPPORTED
-# -----------------------------
-AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi[]dnl
-])# _PKG_SHORT_ERRORS_SUPPORTED
-
-
-# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-# [ACTION-IF-NOT-FOUND])
-#
-#
-# Note that if there is a possibility the first call to
-# PKG_CHECK_MODULES might not happen, you should be sure to include an
-# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
-#
-#
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_MODULES],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
-AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
-
-pkg_failed=no
-AC_MSG_CHECKING([for $1])
-
-_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
-_PKG_CONFIG([$1][_LIBS], [libs], [$2])
-
-m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
-and $1[]_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.])
-
-if test $pkg_failed = yes; then
- _PKG_SHORT_ERRORS_SUPPORTED
- if test $_pkg_short_errors_supported = yes; then
- $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
- else
- $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
-
- ifelse([$4], , [AC_MSG_ERROR(dnl
-[Package requirements ($2) were not met:
-
-$$1_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-_PKG_TEXT
-])],
- [AC_MSG_RESULT([no])
- $4])
-elif test $pkg_failed = untried; then
- ifelse([$4], , [AC_MSG_FAILURE(dnl
-[The pkg-config script could not be found or is too old. Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-_PKG_TEXT
-
-To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
- [$4])
-else
- $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
- $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
- AC_MSG_RESULT([yes])
- ifelse([$3], , :, [$3])
-fi[]dnl
-])# PKG_CHECK_MODULES
diff --git a/source4/lib/ldb/include/dlinklist.h b/source4/lib/ldb/include/dlinklist.h
index 62f885dd30..1c577bb6b9 100644
--- a/source4/lib/ldb/include/dlinklist.h
+++ b/source4/lib/ldb/include/dlinklist.h
@@ -1,20 +1,25 @@
/*
Unix SMB/CIFS implementation.
some simple double linked list macros
- Copyright (C) Andrew Tridgell 1998
-
- 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.
+
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ 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 <http://www.gnu.org/licenses/>.
*/
/* To use these macros you must have a structure containing a next and
@@ -23,55 +28,94 @@
#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
-/* hook into the front of the list */
+
+ 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)) { \
- (list) = (p); \
- (p)->next = (p)->prev = NULL; \
+ (p)->prev = (list) = (p); \
+ (p)->next = NULL; \
} else { \
+ (p)->prev = (list)->prev; \
(list)->prev = (p); \
(p)->next = (list); \
- (p)->prev = NULL; \
(list) = (p); \
- }\
+ } \
} while (0)
-/* remove an element from a list - element doesn't have to be in list. */
+/*
+ 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; \
- if (list) (list)->prev = NULL; \
+ } 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) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
+ if ((p) != (list)) (p)->next = (p)->prev = NULL; \
} while (0)
-/* promote an element to the top of the list */
-#define DLIST_PROMOTE(list, p) \
+/*
+ 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 { \
- DLIST_REMOVE(list, p); \
- DLIST_ADD(list, p); \
-} while (0)
+ (result_head) = (p); \
+ while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
+} while(0)
-/* hook into the end of the list - needs the entry type */
-#define DLIST_ADD_END(list, p, type) \
-do { \
- if (!(list)) { \
- (list) = (p); \
- (p)->next = (p)->prev = NULL; \
- } else { \
- type tmp; \
- for (tmp = (list); tmp->next; tmp = tmp->next) ; \
- tmp->next = (p); \
- (p)->next = NULL; \
- (p)->prev = tmp; \
- } \
-} 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() */
@@ -80,34 +124,62 @@ 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; \
+ (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)
-/* demote an element to the end of the list, needs the entry type */
-#define DLIST_DEMOTE(list, p, type) \
+
+/*
+ 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, type); \
+ 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 */
-#define DLIST_CONCATENATE(list1, list2, type) \
+/*
+ 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 { \
- type tmp; \
- for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
- tmp->next = (list2); \
- if (list2) { \
- (list2)->prev = tmp; \
- } \
+ 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
index a083696073..49f8222d49 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -47,9 +47,10 @@
/*! \endcond */
#include <stdbool.h>
-#include "talloc.h"
-#include "tevent.h"
-#include "ldb_errors.h"
+#include <talloc.h>
+#include <tevent.h>
+#include <ldb_version.h>
+#include <ldb_errors.h>
/*
major restrictions as compared to normal LDAP:
@@ -86,6 +87,14 @@ struct ldb_val {
#ifndef PRINTF_ATTRIBUTE
#define PRINTF_ATTRIBUTE(a,b)
#endif
+
+#ifndef _DEPRECATED_
+#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
+#endif
/*! \endcond */
/* opaque ldb_dn structures, see ldb_dn.c for internals */
@@ -102,6 +111,11 @@ struct ldb_dn;
#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.
@@ -126,6 +140,11 @@ struct ldb_dn;
#define LDB_FLAG_MOD_DELETE 3
/**
+ flag bits on an element usable only by the internal implementation
+*/
+#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0
+
+/**
OID for logic AND comaprison.
This is the well known object ID for a logical AND comparitor.
@@ -296,7 +315,7 @@ struct ldb_parse_tree {
};
struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s);
-char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree);
+char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree);
/**
Encode a binary blob
@@ -335,6 +354,10 @@ char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string);
*/
typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *);
typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *);
+struct ldb_schema_attribute;
+typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation,
+ const struct ldb_schema_attribute *a,
+ const struct ldb_val *, const struct ldb_val *, bool *matched);
/*
attribute handler structure
@@ -352,6 +375,7 @@ struct ldb_schema_syntax {
ldb_attr_handler_t ldif_write_fn;
ldb_attr_handler_t canonicalise_fn;
ldb_attr_comparison_t comparison_fn;
+ ldb_attr_operator_t operator_fn;
};
struct ldb_schema_attribute {
@@ -456,6 +480,49 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
/* 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
@@ -465,6 +532,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://www.ietf.org/rfc/rfc2696.txt">RFC 2696</a>.
*/
#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319"
+#define LDB_CONTROL_PAGED_RESULTS_NAME "paged_result"
/**
OID for specifying the returned elements of the ntSecurityDescriptor
@@ -472,6 +540,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_sd_flags_oid.asp">Microsoft documentation of this OID</a>
*/
#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)
@@ -479,6 +548,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_domain_scope_oid.asp">Microsoft documentation of this OID</a>
*/
#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
@@ -486,6 +556,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_search_options_oid.asp">Microsoft documentation of this OID</a>
*/
#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340"
+#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options"
/**
OID for notification
@@ -493,6 +564,15 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_notification_oid.asp">Microsoft documentation of this OID</a>
*/
#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528"
+#define LDB_CONTROL_NOTIFICATION_NAME "notification"
+
+/**
+ OID for performing subtree deletes
+
+ \sa <a href="http://msdn.microsoft.com/en-us/library/aa366991(v=VS.85).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805"
+#define LDB_CONTROL_TREE_DELETE_NAME "tree_delete"
/**
OID for getting deleted objects
@@ -500,6 +580,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_show_deleted_oid.asp">Microsoft documentation of this OID</a>
*/
#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
@@ -507,6 +588,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/en-us/library/dd304621(PROT.13).aspx">Microsoft documentation of this OID</a>
*/
#define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064"
+#define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled"
/**
OID for getting deactivated linked attributes
@@ -514,6 +596,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/en-us/library/dd302781(PROT.13).aspx">Microsoft documentation of this OID</a>
*/
#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065"
+#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link"
/**
OID for extended DN
@@ -521,6 +604,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_extended_dn_oid.asp">Microsoft documentation of this OID</a>
*/
#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.
@@ -535,6 +619,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>.
*/
#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.
@@ -546,6 +631,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>.
*/
#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.
@@ -554,6 +640,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
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.
@@ -562,6 +649,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
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"
/**
@@ -571,6 +659,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
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.
@@ -579,6 +668,7 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
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
@@ -587,23 +677,79 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
\sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_permissive_modify_oid.asp">Microsoft documentation of this OID</a>
*/
#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 <a href="http://msdn.microsoft.com/en-us/library/aa366982(v=VS.85).aspx">Microsoft documentation of this OID</a>
+*/
+#define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619"
/**
- OID for LDAP Extended Operation START_TLS.
+ Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23
- This Extended operation is used to start a new TLS
- channel on top of a clear text channel.
+ \sa <a href="">Microsoft documentation of this OID</a>
*/
-#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037"
+#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341"
+#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 <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>.
+*/
+#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
+#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_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1"
+#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3"
+
+/**
+ OID for LDAP Extended Operation PASSWORD_CHANGE.
+
+ This Extended operation is used to allow user password changes by the user
+ itself.
+*/
+#define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1"
+
/**
+ OID for LDAP Extended Operation FAST_BIND
+
+ This Extended operations is used to perform a fast bind.
*/
#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781"
+/**
+ OID for LDAP Extended Operation START_TLS.
+
+ This Extended operation is used to start a new TLS channel on top of a clear
+ text channel.
+*/
+#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037"
+
+/**
+ OID for LDAP Extended Operation DYNAMIC_REFRESH.
+
+ This Extended operation is used to create and maintain objects which exist
+ only a specific time, e.g. when a certain client or a certain person is
+ logged in. Data refreshes have to be periodically sent in a specific
+ interval. Otherwise the entry is going to be removed.
+*/
+#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1"
+
struct ldb_sd_flags_control {
/*
* request the owner 0x00000001
@@ -735,8 +881,6 @@ struct ldb_extended {
void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */
};
-#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3"
-
enum ldb_sequence_type {
LDB_SEQ_HIGHEST_SEQ,
LDB_SEQ_HIGHEST_TIMESTAMP,
@@ -963,6 +1107,7 @@ int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares)
*/
int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares);
+int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares);
/**
Helper function to build a search request
@@ -1117,6 +1262,18 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data);
/**
+ replace a ldb_control in a ldb_request
+
+ \param req the request struct where to add the control
+ \param oid the object identifier of the control as string
+ \param critical whether the control should be critical or not
+ \param data a talloc pointer to the control specific data
+
+ \return result code (LDB_SUCCESS on success, or a failure code)
+*/
+int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data);
+
+/**
check if a control with the specified "oid" exist and return it
\param req the request struct where to add the control
\param oid the object identifier of the control as string
@@ -1308,6 +1465,12 @@ int ldb_transaction_commit(struct ldb_context *ldb);
*/
int ldb_transaction_cancel(struct ldb_context *ldb);
+/*
+ cancel a transaction with no error if no transaction is pending
+ used when we fork() to clear any parent transactions
+*/
+int ldb_transaction_cancel_noerr(struct ldb_context *ldb);
+
/**
return extended error information from the last call
@@ -1550,10 +1713,10 @@ char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
\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(void *mem_ctx, struct ldb_dn *dn, int mode);
+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);
@@ -1590,7 +1753,7 @@ struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, cons
\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(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
+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
@@ -1619,6 +1782,7 @@ 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);
@@ -1629,6 +1793,7 @@ bool ldb_dn_is_valid(struct ldb_dn *dn);
bool ldb_dn_is_special(struct ldb_dn *dn);
bool ldb_dn_check_special(struct ldb_dn *dn, const char *check);
bool ldb_dn_is_null(struct ldb_dn *dn);
+int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn);
/**
@@ -1712,6 +1877,8 @@ int ldb_msg_add_steal_string(struct ldb_message *msg,
const char *attr_name, char *str);
int ldb_msg_add_string(struct ldb_message *msg,
const char *attr_name, const char *str);
+int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name,
+ struct ldb_dn *dn);
int ldb_msg_add_fmt(struct ldb_message *msg,
const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
@@ -1765,14 +1932,66 @@ struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx,
struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
const struct ldb_message *msg);
+/*
+ * ldb_msg_canonicalize() is now depreciated
+ * Please use ldb_msg_normalize() instead
+ *
+ * NOTE: Returned ldb_message object is allocated
+ * into *ldb's context. Callers are recommended
+ * to steal the returned object into a TALLOC_CTX
+ * with short lifetime.
+ */
struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
- const struct ldb_message *msg);
+ const struct ldb_message *msg) _DEPRECATED_;
+int ldb_msg_normalize(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ const struct ldb_message *msg,
+ struct ldb_message **_msg_out);
+
+/*
+ * ldb_msg_diff() is now depreciated
+ * Please use ldb_msg_difference() instead
+ *
+ * NOTE: Returned ldb_message object is allocated
+ * into *ldb's context. Callers are recommended
+ * to steal the returned object into a TALLOC_CTX
+ * with short lifetime.
+ */
struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
struct ldb_message *msg1,
- struct ldb_message *msg2);
+ struct ldb_message *msg2) _DEPRECATED_;
+
+/**
+ * return a ldb_message representing the differences between msg1 and msg2.
+ * If you then use this in a ldb_modify() call,
+ * it can be used to save edits to a message
+ *
+ * Result message is constructed as follows:
+ * - LDB_FLAG_MOD_ADD - elements found only in msg2
+ * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have
+ * different value in msg1
+ * Value for msg2 element is used
+ * - LDB_FLAG_MOD_DELETE - elements found only in msg2
+ *
+ * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR
+ */
+int ldb_msg_difference(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg1,
+ struct ldb_message *msg2,
+ struct ldb_message **_msg_out);
+
+/**
+ Tries to find a certain string attribute in a message
+
+ \param msg the message to check
+ \param name attribute name
+ \param value attribute value
+ \return 1 on match and 0 otherwise.
+*/
int ldb_msg_check_string_attribute(const struct ldb_message *msg,
const char *name,
const char *value);
@@ -1879,6 +2098,12 @@ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t);
time_t ldb_string_to_time(const char *s);
/**
+ convert a LDAP GeneralizedTime string in ldb_val format to a
+ time_t.
+*/
+int ldb_val_to_time(const struct ldb_val *v, time_t *t);
+
+/**
Convert a time structure to a string
This function converts a time_t structure to an LDAP formatted
@@ -1907,7 +2132,55 @@ 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
@@ -1928,4 +2201,28 @@ unsigned int ldb_get_flags(struct ldb_context *ldb);
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
index 706d82732d..b247fbe09c 100644
--- a/source4/lib/ldb/include/ldb_errors.h
+++ b/source4/lib/ldb/include/ldb_errors.h
@@ -197,7 +197,7 @@
#define LDB_ERR_NO_SUCH_OBJECT 32
/**
- The function referred to an alias which points to a non-existant
+ The function referred to an alias which points to a non-existent
object in the database.
*/
#define LDB_ERR_ALIAS_PROBLEM 33
diff --git a/source4/lib/ldb/include/ldb_handlers.h b/source4/lib/ldb/include/ldb_handlers.h
index 21fbcc33f8..6e71f1fa01 100644
--- a/source4/lib/ldb/include/ldb_handlers.h
+++ b/source4/lib/ldb/include/ldb_handlers.h
@@ -35,8 +35,6 @@ 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 db_handler_fold( struct ldb_context *ldb, void *mem_ctx,
- const struct ldb_val *in, struct ldb_val *out);
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_includes.h b/source4/lib/ldb/include/ldb_includes.h
deleted file mode 100644
index 602bbec32c..0000000000
--- a/source4/lib/ldb/include/ldb_includes.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _LDB_PRIVATE_INCLUDES_H_
-#define _LDB_PRIVATE_INCLUDES_H_
-/*
- a temporary includes file until I work on the ldb build system
-*/
-
-#if (_SAMBA_BUILD_ <= 3)
-/* allow forbidden string functions - should be replaced with _m functions */
-#undef strcasecmp
-#undef strncasecmp
-#define dyn_MODULESDIR dyn_LIBDIR
-#endif
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/time.h"
-
-#endif /*_LDB_PRIVATE_INCLUDES_H_*/
diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h
index ae8c4d50df..db8726b7a3 100644
--- a/source4/lib/ldb/include/ldb_module.h
+++ b/source4/lib/ldb/include/ldb_module.h
@@ -33,11 +33,26 @@
#ifndef _LDB_MODULE_H_
#define _LDB_MODULE_H_
-#include "ldb.h"
+#include <ldb.h>
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
*/
@@ -67,7 +82,11 @@ void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level,
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_oom(ldb) ldb_debug_set(ldb, LDB_DEBUG_FATAL, "ldb out of memory at %s:%d\n", __FILE__, __LINE__)
+#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 */
@@ -98,10 +117,21 @@ 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 */
-struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid);
-int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver);
-int check_critical_controls(struct ldb_control **controls);
+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);
@@ -113,6 +143,16 @@ int ldb_match_msg(struct ldb_context *ldb,
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,
@@ -124,6 +164,7 @@ 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);
@@ -135,6 +176,7 @@ 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);
@@ -151,7 +193,7 @@ struct ldb_backend_ops {
const char *ldb_default_modules_dir(void);
-int ldb_register_backend(const char *url_prefix, ldb_connect_fn);
+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);
@@ -170,5 +212,119 @@ int ldb_module_done(struct ldb_request *req,
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);
+
+/* 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
index 0e0a1a206d..5397b79ec5 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -37,7 +37,9 @@
#ifndef _LDB_PRIVATE_H_
#define _LDB_PRIVATE_H_ 1
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb.h"
#include "ldb_module.h"
@@ -48,6 +50,8 @@ 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;
@@ -55,6 +59,10 @@ struct ldb_handle {
struct ldb_context *ldb;
unsigned flags;
unsigned nesting;
+
+ /* used for debugging */
+ struct ldb_request *parent;
+ const char *location;
};
/* basic module structure */
@@ -112,21 +120,17 @@ struct ldb_context {
unsigned int create_perms;
- char *modules_dir;
-
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 */
-int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[],
- struct ldb_module **backend_module);
-
-
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;
@@ -157,7 +161,7 @@ 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, void *mem_ctx, const char *s, size_t n);
+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);
@@ -165,10 +169,14 @@ void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *
/* 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_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out);
int ldb_load_modules(struct ldb_context *ldb, const char *options[]);
-int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module);
-struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str);
+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/install-sh b/source4/lib/ldb/install-sh
deleted file mode 100755
index 58719246f0..0000000000
--- a/source4/lib/ldb/install-sh
+++ /dev/null
@@ -1,238 +0,0 @@
-#! /bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/source4/lib/ldb/ldap.m4 b/source4/lib/ldb/ldap.m4
deleted file mode 100644
index 417083ed61..0000000000
--- a/source4/lib/ldb/ldap.m4
+++ /dev/null
@@ -1,90 +0,0 @@
-########################################################
-# Compile with LDAP support?
-
-LDAP_LIBS=""
-with_ldap_support=auto
-AC_MSG_CHECKING([for LDAP support])
-
-AC_ARG_WITH(ldap,
-AS_HELP_STRING([--with-ldap],[LDAP backend support (default=yes)]),
-[ case "$withval" in
- yes|no)
- with_ldap_support=$withval
- ;;
- esac ])
-
-AC_MSG_RESULT($with_ldap_support)
-
-if test x"$with_ldap_support" != x"no"; then
-
- ##################################################################
- # first test for ldap.h and lber.h
- # (ldap.h is required for this test)
- AC_CHECK_HEADERS(ldap.h lber.h)
-
- if test x"$ac_cv_header_ldap_h" != x"yes"; then
- if test x"$with_ldap_support" = x"yes"; then
- AC_MSG_ERROR(ldap.h is needed for LDAP support)
- else
- AC_MSG_WARN(ldap.h is needed for LDAP support)
- fi
-
- with_ldap_support=no
- fi
-fi
-
-if test x"$with_ldap_support" != x"no"; then
- ac_save_LIBS=$LIBS
-
- ##################################################################
- # we might need the lber lib on some systems. To avoid link errors
- # this test must be before the libldap test
- AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf)
-
- ########################################################
- # now see if we can find the ldap libs in standard paths
- AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init)
-
- AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS)
-
- ########################################################
- # If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
- # Check found in pam_ldap 145.
- AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS)
-
- LIBS="$LIBS $LDAP_LIBS"
- AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [
- AC_TRY_COMPILE([
- #include <lber.h>
- #include <ldap.h>],
- [ldap_set_rebind_proc(0, 0, 0);],
- [smb_ldap_cv_ldap_set_rebind_proc=3],
- [smb_ldap_cv_ldap_set_rebind_proc=2]
- )
- ])
-
- AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
-
- AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS)
-
- if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then
- AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
- AC_DEFINE(HAVE_LDB_LDAP,1,[Whether ldb_ldap is available])
- with_ldap_support=yes
- AC_MSG_CHECKING(whether LDAP support is used)
- AC_MSG_RESULT(yes)
- SMB_ENABLE(LDAP,YES)
- else
- if test x"$with_ldap_support" = x"yes"; then
- AC_MSG_ERROR(libldap is needed for LDAP support)
- else
- AC_MSG_WARN(libldap is needed for LDAP support)
- fi
-
- LDAP_LIBS=""
- with_ldap_support=no
- fi
- LIBS=$ac_save_LIBS
-fi
-
-SMB_EXT_LIB(LDAP,[${LDAP_LIBS}],[${LDAP_CFLAGS}],[${LDAP_CPPFLAGS}],[${LDAP_LDFLAGS}])
diff --git a/source4/lib/ldb/ldb.mk b/source4/lib/ldb/ldb.mk
deleted file mode 100644
index e87db64574..0000000000
--- a/source4/lib/ldb/ldb.mk
+++ /dev/null
@@ -1,81 +0,0 @@
-LDB_LIB = -Llib -lldb
-
-LIB_FLAGS=$(LDFLAGS) $(LIBS) $(LDB_LIB) $(POPT_LIBS) $(TALLOC_LIBS) \
- $(TDB_LIBS) $(TEVENT_LIBS) $(LDAP_LIBS) $(LIBDL)
-
-LDB_TDB_DIR=ldb_tdb
-LDB_TDB_OBJ=$(LDB_TDB_DIR)/ldb_tdb.o \
- $(LDB_TDB_DIR)/ldb_pack.o $(LDB_TDB_DIR)/ldb_search.o $(LDB_TDB_DIR)/ldb_index.o \
- $(LDB_TDB_DIR)/ldb_cache.o $(LDB_TDB_DIR)/ldb_tdb_wrap.o
-
-LDB_MAP_DIR=ldb_map
-LDB_MAP_OBJ=$(LDB_MAP_DIR)/ldb_map.o $(LDB_MAP_DIR)/ldb_map_inbound.o \
- $(LDB_MAP_DIR)/ldb_map_outbound.o
-
-COMDIR=common
-COMMON_OBJ=$(COMDIR)/ldb.o $(COMDIR)/ldb_ldif.o \
- $(COMDIR)/ldb_parse.o $(COMDIR)/ldb_msg.o $(COMDIR)/ldb_utf8.o \
- $(COMDIR)/ldb_debug.o $(COMDIR)/ldb_modules.o \
- $(COMDIR)/ldb_dn.o $(COMDIR)/ldb_match.o $(COMDIR)/ldb_attributes.o \
- $(COMDIR)/attrib_handlers.o $(COMDIR)/ldb_controls.o $(COMDIR)/qsort.o
-
-MODDIR=modules
-MODULES_OBJ=$(MODDIR)/rdn_name.o ${MODDIR}/asq.o \
- $(MODDIR)/paged_results.o $(MODDIR)/sort.o
-
-NSSDIR=nssldb
-NSS_OBJ= $(NSSDIR)/ldb-nss.o $(NSSDIR)/ldb-pwd.o $(NSSDIR)/ldb-grp.o
-NSS_LIB = lib/libnss_ldb.$(SHLIBEXT).2
-
-lib/libldb.a: $(OBJS)
- ar -rv $@ $(OBJS)
- @-ranlib $@
-
-sample.$(SHLIBEXT): tests/sample_module.o
- $(MDLD) $(MDLD_FLAGS) -o $@ tests/sample_module.o
-
-bin/ldbadd: tools/ldbadd.o tools/cmdline.o
- $(CC) -o bin/ldbadd tools/ldbadd.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbsearch: tools/ldbsearch.o tools/cmdline.o
- $(CC) -o bin/ldbsearch tools/ldbsearch.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbdel: tools/ldbdel.o tools/cmdline.o
- $(CC) -o bin/ldbdel tools/ldbdel.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbmodify: tools/ldbmodify.o tools/cmdline.o
- $(CC) -o bin/ldbmodify tools/ldbmodify.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbedit: tools/ldbedit.o tools/cmdline.o
- $(CC) -o bin/ldbedit tools/ldbedit.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbrename: tools/ldbrename.o tools/cmdline.o
- $(CC) -o bin/ldbrename tools/ldbrename.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-bin/ldbtest: tools/ldbtest.o tools/cmdline.o
- $(CC) -o bin/ldbtest tools/ldbtest.o tools/cmdline.o $(LIB_FLAGS) $(LD_EXPORT_DYNAMIC)
-
-examples/ldbreader: examples/ldbreader.o
- $(CC) -o examples/ldbreader examples/ldbreader.o $(LIB_FLAGS)
-
-examples/ldifreader: examples/ldifreader.o
- $(CC) -o examples/ldifreader examples/ldifreader.o $(LIB_FLAGS)
-
-# Python bindings
-build-python:: ldb.$(SHLIBEXT)
-
-pyldb.o: $(ldbdir)/pyldb.c
- $(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-
-ldb.$(SHLIBEXT): pyldb.o
- $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
-
-install-python:: build-python
- mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
- cp ldb.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
-
-check-python:: build-python lib/$(SONAME)
- $(LIB_PATH_VAR)=lib PYTHONPATH=.:$(ldbdir) $(PYTHON) $(ldbdir)/tests/python/api.py
-
-clean::
- rm -f ldb.$(SHLIBEXT)
diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in
index 01482f6bfb..aeba17a677 100644
--- a/source4/lib/ldb/ldb.pc.in
+++ b/source4/lib/ldb/ldb.pc.in
@@ -9,7 +9,7 @@ Description: An LDAP-like embedded database
Version: @PACKAGE_VERSION@
Requires.private: tdb
Requires: talloc
-Libs: -L${libdir} -lldb
+Libs: @LIB_RPATH@ -L${libdir} -lldb
Libs.private: @LDAP_LIBS@
Cflags: -I${includedir}
Modulesdir: ${modulesdir}
diff --git a/source4/lib/ldb/ldb_ildap/config.mk b/source4/lib/ldb/ldb_ildap/config.mk
deleted file mode 100644
index 6a1ef8164c..0000000000
--- a/source4/lib/ldb/ldb_ildap/config.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-################################################
-# Start MODULE ldb_ildap
-[MODULE::ldb_ildap]
-SUBSYSTEM = LIBLDB
-CFLAGS = -I$(ldbsrcdir)/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBCLI_LDAP CREDENTIALS
-INIT_FUNCTION = LDB_BACKEND(ldapi),LDB_BACKEND(ldaps),LDB_BACKEND(ldap)
-ALIASES = ldapi ldaps ldap
-# End MODULE ldb_ildap
-################################################
-
-ldb_ildap_OBJ_FILES = $(ldbsrcdir)/ldb_ildap/ldb_ildap.o
-
diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
index 52c16101bb..7e6ac903c8 100644
--- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c
+++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
@@ -33,13 +33,16 @@
*
* Modifications:
*
- * - description: make the module use asyncronous calls
+ * - description: make the module use asynchronous calls
* date: Feb 2006
* author: Simo Sorce
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
+#include "ldb_private.h"
#define LDAP_DEPRECATED 1
#include <ldap.h>
@@ -117,7 +120,7 @@ static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg,
if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
goto failed;
}
- mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
+ 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;
@@ -253,14 +256,14 @@ static int lldb_search(struct lldb_context *lldb_ac)
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);
+ 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));
@@ -282,7 +285,7 @@ static int lldb_add(struct lldb_context *lldb_ac)
char *dn;
int ret;
- ldb_module_get_ctx(module);
+ ldb = ldb_module_get_ctx(module);
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -321,7 +324,7 @@ static int lldb_modify(struct lldb_context *lldb_ac)
char *dn;
int ret;
- ldb_module_get_ctx(module);
+ ldb = ldb_module_get_ctx(module);
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -359,7 +362,7 @@ static int lldb_delete(struct lldb_context *lldb_ac)
char *dnstr;
int ret;
- ldb_module_get_ctx(module);
+ ldb = ldb_module_get_ctx(module);
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -386,12 +389,14 @@ static int lldb_rename(struct lldb_context *lldb_ac)
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 *newrdn;
char *parentdn;
int ret;
- ldb_module_get_ctx(module);
+ ldb = ldb_module_get_ctx(module);
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -400,9 +405,15 @@ static int lldb_rename(struct lldb_context *lldb_ac)
return LDB_ERR_OPERATIONS_ERROR;
}
- newrdn = talloc_asprintf(lldb_ac, "%s=%s",
- ldb_dn_get_rdn_name(req->op.rename.newdn),
- ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn))));
+ 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;
}
@@ -444,7 +455,7 @@ static int lldb_del_trans(struct ldb_module *module)
return LDB_SUCCESS;
}
-void lldb_request_done(struct lldb_context *ac,
+static void lldb_request_done(struct lldb_context *ac,
struct ldb_control **ctrls, int error)
{
struct ldb_request *req;
@@ -483,8 +494,8 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
bool callback_failed;
bool request_done;
bool lret;
+ unsigned int i;
int ret;
- int i;
ldb = ldb_module_get_ctx(ac->module);
@@ -502,20 +513,24 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
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);
@@ -539,7 +554,8 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
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 {
@@ -549,15 +565,16 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
case LDAP_RES_SEARCH_REFERENCE:
- if (ldap_parse_result(lldb->ldap, result, &ret,
- &matcheddnp, &errmsgp,
- &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) {
+ 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;
- }
- if (ret != LDB_SUCCESS) {
break;
}
if (referralsp == NULL) {
+ ldb_asprintf_errstring(ldb, "empty ldap referrals list");
ret = LDB_ERR_PROTOCOL_ERROR;
break;
}
@@ -567,6 +584,8 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
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;
}
@@ -585,6 +604,8 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
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;
}
@@ -597,6 +618,7 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
break;
default:
+ ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type);
ret = LDB_ERR_PROTOCOL_ERROR;
break;
}
@@ -798,7 +820,7 @@ static int lldb_handle_request(struct ldb_module *module, struct ldb_request *re
break;
default:
/* no other op supported */
- ret = LDB_ERR_OPERATIONS_ERROR;
+ ret = LDB_ERR_PROTOCOL_ERROR;
break;
}
@@ -845,6 +867,48 @@ static int lldb_destructor(struct lldb_private *lldb)
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
*/
@@ -860,7 +924,7 @@ static int lldb_connect(struct ldb_context *ldb,
int ret;
module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops);
- if (!module) return -1;
+ if (!module) return LDB_ERR_OPERATIONS_ERROR;
lldb = talloc_zero(module, struct lldb_private);
if (!lldb) {
@@ -886,24 +950,33 @@ static int lldb_connect(struct ldb_context *ldb,
}
*_module = module;
- return 0;
+
+ ret = lldb_bind(module, options);
+ if (ret != LDB_SUCCESS) {
+ goto failed;
+ }
+
+
+ return LDB_SUCCESS;
failed:
talloc_free(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
-const struct ldb_backend_ops ldb_ldap_backend_ops = {
- .name = "ldap",
- .connect_fn = lldb_connect
-};
-
-const struct ldb_backend_ops ldb_ldapi_backend_ops = {
- .name = "ldapi",
- .connect_fn = lldb_connect
-};
-
-const struct ldb_backend_ops ldb_ldaps_backend_ops = {
- .name = "ldaps",
- .connect_fn = lldb_connect
-};
+/*
+ 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
index 68e9d3f392..d35e5c604f 100644
--- a/source4/lib/ldb/ldb_map/ldb_map.c
+++ b/source4/lib/ldb/ldb_map/ldb_map.c
@@ -35,7 +35,9 @@
* Author: Jelmer Vernooij, Martin Kuehl
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_map.h"
#include "ldb_map_private.h"
@@ -256,7 +258,7 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque
/* 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)
{
- int i;
+ 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) {
@@ -270,7 +272,7 @@ static const struct ldb_map_objectclass *map_objectclass_find_local(const struct
/* 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)
{
- int i;
+ 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) {
@@ -284,7 +286,7 @@ static const struct ldb_map_objectclass *map_objectclass_find_remote(const struc
/* 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)
{
- int i;
+ 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) {
@@ -305,7 +307,7 @@ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_contex
{
const struct ldb_map_attribute *map;
const struct ldb_map_attribute *wildcard = NULL;
- int i, j;
+ unsigned int i, j;
for (i = 0; data->attribute_maps[i].local_name; i++) {
map = &data->attribute_maps[i];
@@ -314,23 +316,23 @@ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_contex
}
switch (map->type) {
- case MAP_IGNORE:
+ case LDB_MAP_IGNORE:
break;
- case MAP_KEEP:
+ case LDB_MAP_KEEP:
if (ldb_attr_cmp(map->local_name, name) == 0) {
return map;
}
break;
- case MAP_RENAME:
- case MAP_CONVERT:
+ case LDB_MAP_RENAME:
+ case LDB_MAP_CONVERT:
if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) {
return map;
}
break;
- case MAP_GENERATE:
+ 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;
@@ -356,7 +358,7 @@ bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr)
if (map == NULL) {
return false;
}
- if (map->type == MAP_IGNORE) {
+ if (map->type == LDB_MAP_IGNORE) {
return false;
}
@@ -371,11 +373,11 @@ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *ma
}
switch (map->type) {
- case MAP_KEEP:
+ case LDB_MAP_KEEP:
return talloc_strdup(mem_ctx, attr);
- case MAP_RENAME:
- case MAP_CONVERT:
+ case LDB_MAP_RENAME:
+ case LDB_MAP_CONVERT:
return talloc_strdup(mem_ctx, map->u.rename.remote_name);
default:
@@ -390,7 +392,7 @@ const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *m
return talloc_strdup(mem_ctx, attr);
}
- if (map->type == MAP_KEEP) {
+ if (map->type == LDB_MAP_KEEP) {
return talloc_strdup(mem_ctx, attr);
}
@@ -402,7 +404,7 @@ const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *m
int map_attrs_merge(struct ldb_module *module, void *mem_ctx,
const char ***attrs, const char * const *more_attrs)
{
- int i, j, k;
+ unsigned int i, j, k;
for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ;
for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ;
@@ -429,7 +431,7 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx,
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 == MAP_CONVERT) && (map->u.convert.convert_local)) {
+ if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) {
return map->u.convert.convert_local(module, mem_ctx, val);
}
@@ -440,7 +442,7 @@ struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx,
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 == MAP_CONVERT) && (map->u.convert.convert_remote)) {
+ if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) {
return map->u.convert.convert_remote(module, mem_ctx, val);
}
@@ -493,20 +495,20 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
/* Unknown attribute - leave this RDN as is and hope the best... */
if (map == NULL) {
- map_type = MAP_KEEP;
+ map_type = LDB_MAP_KEEP;
} else {
map_type = map->type;
}
switch (map_type) {
- case MAP_IGNORE:
- case MAP_GENERATE:
+ case LDB_MAP_IGNORE:
+ case LDB_MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "MAP_IGNORE/MAP_GENERATE attribute '%s' "
+ "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' "
"used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
- case MAP_CONVERT:
+ 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' "
@@ -514,8 +516,8 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
goto failed;
}
/* fall through */
- case MAP_KEEP:
- case MAP_RENAME:
+ 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;
@@ -568,20 +570,20 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
/* Unknown attribute - leave this RDN as is and hope the best... */
if (map == NULL) {
- map_type = MAP_KEEP;
+ map_type = LDB_MAP_KEEP;
} else {
map_type = map->type;
}
switch (map_type) {
- case MAP_IGNORE:
- case MAP_GENERATE:
+ case LDB_MAP_IGNORE:
+ case LDB_MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "MAP_IGNORE/MAP_GENERATE attribute '%s' "
+ "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' "
"used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
- case MAP_CONVERT:
+ 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' "
@@ -589,8 +591,8 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
goto failed;
}
/* fall through */
- case MAP_KEEP:
- case MAP_RENAME:
+ 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;
@@ -714,7 +716,7 @@ static void map_objectclass_generate_remote(struct ldb_module *module, const cha
struct ldb_message_element *el, *oc;
struct ldb_val val;
bool found_extensibleObject = false;
- int i;
+ unsigned int i;
ldb = ldb_module_get_ctx(module);
@@ -789,7 +791,7 @@ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_mod
struct ldb_context *ldb;
struct ldb_message_element *el, *oc;
struct ldb_val val;
- int i;
+ unsigned int i;
ldb = ldb_module_get_ctx(module);
@@ -842,7 +844,7 @@ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_mod
static const struct ldb_map_attribute objectclass_convert_map = {
.local_name = "objectClass",
- .type = MAP_CONVERT,
+ .type = LDB_MAP_CONVERT,
.u = {
.convert = {
.remote_name = "objectClass",
@@ -891,6 +893,7 @@ struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *d
NULL,
context, callback,
ac->req);
+ LDB_REQ_SET_LOCATION(req);
if (ret != LDB_SUCCESS) {
return NULL;
}
@@ -938,6 +941,7 @@ struct ldb_request *map_build_fixup_req(struct map_context *ac,
ac, msg, NULL,
context, callback,
ac->req);
+ LDB_REQ_SET_LOCATION(req);
if (ret != LDB_SUCCESS) {
goto failed;
}
@@ -957,7 +961,7 @@ failed:
static const struct ldb_map_attribute builtin_attribute_maps[] = {
{
.local_name = "dn",
- .type = MAP_CONVERT,
+ .type = LDB_MAP_CONVERT,
.u = {
.convert = {
.remote_name = "dn",
@@ -973,7 +977,7 @@ static const struct ldb_map_attribute builtin_attribute_maps[] = {
static const struct ldb_map_attribute objectclass_attribute_map = {
.local_name = "objectClass",
- .type = MAP_GENERATE,
+ .type = LDB_MAP_GENERATE,
.convert_operator = map_objectclass_convert_operator,
.u = {
.generate = {
@@ -1043,7 +1047,7 @@ static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data
const struct ldb_map_objectclass *ocls,
const char * const *wildcard_attributes)
{
- int i, j, last;
+ unsigned int i, j, last;
last = 0;
/* Count specified attribute maps */
diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h
index 3c1fe80895..5db3e02a08 100644
--- a/source4/lib/ldb/ldb_map/ldb_map.h
+++ b/source4/lib/ldb/ldb_map/ldb_map.h
@@ -59,11 +59,11 @@ struct ldb_map_attribute {
const char *local_name; /* local name */
enum ldb_map_attr_type {
- MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */
- MAP_KEEP, /* Keep as is. Same name locally and remotely. */
- MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */
- MAP_CONVERT, /* Rename + convert data */
- MAP_GENERATE /* Use generate function for generating new name/data.
+ 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;
@@ -157,17 +157,17 @@ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attr
const char *add_objectclass,
const char *name);
-int map_add(struct ldb_module *module, struct ldb_request *req);
-int map_search(struct ldb_module *module, struct ldb_request *req);
-int map_rename(struct ldb_module *module, struct ldb_request *req);
-int map_delete(struct ldb_module *module, struct ldb_request *req);
-int map_modify(struct ldb_module *module, struct ldb_request *req);
+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 = map_add, \
- .modify = map_modify, \
- .del = map_delete, \
- .rename = map_rename, \
- .search = map_search,
+ .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
index 89037419fb..b61037222a 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c
+++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c
@@ -24,7 +24,9 @@
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_map.h"
#include "ldb_map_private.h"
@@ -36,7 +38,7 @@
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;
- int i;
+ unsigned int i;
el = talloc_zero(mem_ctx, struct ldb_message_element);
if (el == NULL) {
@@ -79,10 +81,10 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
}
switch (map->type) {
- case MAP_IGNORE:
+ case LDB_MAP_IGNORE:
goto local;
- case MAP_CONVERT:
+ case LDB_MAP_CONVERT:
if (map->u.convert.convert_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
@@ -91,12 +93,12 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
goto local;
}
/* fall through */
- case MAP_KEEP:
- case MAP_RENAME:
+ case LDB_MAP_KEEP:
+ case LDB_MAP_RENAME:
el = ldb_msg_el_map_local(module, remote, map, old);
break;
- case MAP_GENERATE:
+ case LDB_MAP_GENERATE:
if (map->u.generate.generate_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
@@ -141,7 +143,7 @@ static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_mes
{
const struct ldb_map_context *data = map_get_context(module);
bool ret;
- int i;
+ unsigned int i;
for (i = 0; i < msg->num_elements; i++) {
ret = map_attr_check_remote(data, msg->elements[i].name);
@@ -159,7 +161,8 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca
{
/* const char * const names[]; */
struct ldb_context *ldb;
- int i, ret;
+ unsigned int i;
+ int ret;
ldb = ldb_module_get_ctx(module);
@@ -356,13 +359,12 @@ static int map_op_remote_callback(struct ldb_request *req,
/* Add a record. */
-int map_add(struct ldb_module *module, struct ldb_request *req)
+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;
- const char *dn;
int ret;
ldb = ldb_module_get_ctx(module);
@@ -414,6 +416,7 @@ int map_add(struct ldb_module *module, struct ldb_request *req)
req->controls,
ac, map_op_remote_callback,
req);
+ LDB_REQ_SET_LOCATION(ac->remote_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -426,8 +429,9 @@ int map_add(struct ldb_module *module, struct ldb_request *req)
/* Store remote DN in 'IS_MAPPED' */
/* TODO: use GUIDs here instead */
- dn = ldb_dn_alloc_linearized(ac->local_msg, remote_msg->dn);
- if (ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn) != 0) {
+ ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED,
+ remote_msg->dn);
+ if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -450,6 +454,7 @@ static int map_add_do_local(struct map_context *ac)
ac,
map_op_local_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(local_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -461,7 +466,7 @@ static int map_add_do_local(struct map_context *ac)
*****************************************************************************/
/* Modify a record. */
-int map_modify(struct ldb_module *module, struct ldb_request *req)
+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;
@@ -521,6 +526,7 @@ int map_modify(struct ldb_module *module, struct ldb_request *req)
req->controls,
ac, map_op_remote_callback,
req);
+ LDB_REQ_SET_LOCATION(ac->remote_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -545,7 +551,6 @@ static int map_modify_do_local(struct map_context *ac)
{
struct ldb_request *local_req;
struct ldb_context *ldb;
- char *dn;
int ret;
ldb = ldb_module_get_ctx(ac->module);
@@ -558,9 +563,9 @@ static int map_modify_do_local(struct map_context *ac)
LDB_FLAG_MOD_ADD, NULL) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
- dn = ldb_dn_alloc_linearized(ac->local_msg,
- ac->remote_req->op.mod.message->dn);
- if (ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn) != 0) {
+ 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;
}
@@ -571,6 +576,7 @@ static int map_modify_do_local(struct map_context *ac)
ac,
map_op_local_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(local_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -582,6 +588,7 @@ static int map_modify_do_local(struct map_context *ac)
ac,
map_op_local_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(local_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -595,7 +602,7 @@ static int map_modify_do_local(struct map_context *ac)
*****************************************************************************/
/* Delete a record. */
-int map_delete(struct ldb_module *module, struct ldb_request *req)
+int ldb_map_delete(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_request *search_req;
struct ldb_context *ldb;
@@ -628,6 +635,7 @@ int map_delete(struct ldb_module *module, struct ldb_request *req)
ac,
map_op_remote_callback,
req);
+ LDB_REQ_SET_LOCATION(ac->remote_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -670,6 +678,7 @@ static int map_delete_do_local(struct map_context *ac)
ac,
map_op_local_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(local_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -681,7 +690,7 @@ static int map_delete_do_local(struct map_context *ac)
*****************************************************************************/
/* Rename a record. */
-int map_rename(struct ldb_module *module, struct ldb_request *req)
+int ldb_map_rename(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_request *search_req;
struct ldb_context *ldb;
@@ -721,6 +730,7 @@ int map_rename(struct ldb_module *module, struct ldb_request *req)
req->controls,
ac, map_op_remote_callback,
req);
+ LDB_REQ_SET_LOCATION(ac->remote_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -764,6 +774,7 @@ static int map_rename_do_local(struct map_context *ac)
ac,
map_rename_local_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(local_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
index 6a8e796ca4..2c517a625d 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c
+++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
@@ -25,7 +25,9 @@
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_map.h"
#include "ldb_map_private.h"
@@ -38,7 +40,7 @@ static const char **map_attrs_select_local(struct ldb_module *module, void *mem_
{
const struct ldb_map_context *data = map_get_context(module);
const char **result;
- int i, last;
+ unsigned int i, last;
if (attrs == NULL)
return NULL;
@@ -81,7 +83,7 @@ static const char **map_attrs_collect_remote(struct ldb_module *module, void *me
const char **result;
const struct ldb_map_attribute *map;
const char *name=NULL;
- int i, j, last;
+ unsigned int i, j, last;
int ret;
last = 0;
@@ -124,19 +126,19 @@ static const char **map_attrs_collect_remote(struct ldb_module *module, void *me
}
switch (map->type) {
- case MAP_IGNORE:
+ case LDB_MAP_IGNORE:
continue;
- case MAP_KEEP:
+ case LDB_MAP_KEEP:
name = attrs[i];
goto named;
- case MAP_RENAME:
- case MAP_CONVERT:
+ case LDB_MAP_RENAME:
+ case LDB_MAP_CONVERT:
name = map->u.rename.remote_name;
goto named;
- case MAP_GENERATE:
+ 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);
@@ -219,8 +221,10 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
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;
- int i;
+ unsigned int i;
el = talloc_zero(mem_ctx, struct ldb_message_element);
if (el == NULL) {
@@ -235,7 +239,19 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
return NULL;
}
- el->name = talloc_strdup(el, attr_name);
+ 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);
@@ -281,26 +297,26 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
}
switch (map->type) {
- case MAP_IGNORE:
+ case LDB_MAP_IGNORE:
break;
- case MAP_CONVERT:
+ case LDB_MAP_CONVERT:
remote_name = map->u.convert.remote_name;
break;
- case MAP_KEEP:
+ case LDB_MAP_KEEP:
remote_name = attr_name;
break;
- case MAP_RENAME:
+ case LDB_MAP_RENAME:
remote_name = map->u.rename.remote_name;
break;
- case MAP_GENERATE:
+ case LDB_MAP_GENERATE:
break;
}
switch (map->type) {
- case MAP_IGNORE:
+ case LDB_MAP_IGNORE:
return LDB_SUCCESS;
- case MAP_CONVERT:
+ case LDB_MAP_CONVERT:
if (map->u.convert.convert_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
@@ -309,8 +325,8 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
return LDB_SUCCESS;
}
/* fall through */
- case MAP_KEEP:
- case MAP_RENAME:
+ 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);
@@ -319,7 +335,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
}
break;
- case MAP_GENERATE:
+ case LDB_MAP_GENERATE:
if (map->u.generate.generate_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
@@ -350,10 +366,11 @@ static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_messa
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;
- int i, ret;
+ unsigned int i;
+ int ret;
/* Perhaps we have a mapping for "*" */
- if (map && map->type == MAP_KEEP) {
+ 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++) {
@@ -392,7 +409,8 @@ static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_messa
/* 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)
{
- int i, ret;
+ unsigned int i;
+ int ret;
for (i = 0; i < msg2->num_elements; i++) {
ret = ldb_msg_replace(msg1, &msg2->elements[i]);
@@ -408,7 +426,8 @@ static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *ms
static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local,
struct ldb_message *remote)
{
- int i, ret;
+ unsigned int i;
+ int ret;
const char * const *attrs = ac->all_attrs;
if (!attrs) {
ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);
@@ -520,7 +539,8 @@ static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *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;
- int i, ret;
+ unsigned int i;
+ int ret;
if (tree == NULL) {
return 0;
@@ -547,8 +567,6 @@ static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx
*attrs = new_attrs;
return 0;
}
-
- return -1;
}
static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree);
@@ -588,7 +606,8 @@ static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx
/* 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)
{
- int i, j, ret=0;
+ unsigned int i, j;
+ int ret=0;
/* Prepare new tree */
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
@@ -711,7 +730,8 @@ static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_c
/* 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)
{
- int i, j, ret=0;
+ unsigned int i, j;
+ int ret=0;
/* Prepare new tree */
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
@@ -772,7 +792,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
}
**new = *tree;
- if (map->type == MAP_KEEP) {
+ if (map->type == LDB_MAP_KEEP) {
/* Nothing to do here */
return 0;
}
@@ -814,7 +834,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
return 0;
}
- if (map->type == MAP_RENAME) {
+ if (map->type == LDB_MAP_RENAME) {
/* Nothing more to do here, the attribute has been renamed */
return 0;
}
@@ -897,7 +917,7 @@ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx,
return map->convert_operator(module, mem_ctx, new, tree);
}
- if (map->type == MAP_GENERATE) {
+ if (map->type == LDB_MAP_GENERATE) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Skipping attribute '%s': "
"'convert_operator' not set",
@@ -1051,15 +1071,20 @@ 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;
- int i;
+ unsigned int i;
+ int ret;
+ bool matched;
ldb = ldb_module_get_ctx(ac->module);
/* Merged result doesn't match original query, skip */
- if (!ldb_match_msg(ldb, ares->message,
- ac->req->op.search.tree,
- ac->req->op.search.base,
- ac->req->op.search.scope)) {
+ 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",
@@ -1089,7 +1114,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares)
}
/* Search a record. */
-int map_search(struct ldb_module *module, struct ldb_request *req)
+int ldb_map_search(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_parse_tree *remote_tree;
struct ldb_parse_tree *local_tree;
@@ -1185,6 +1210,7 @@ int map_search(struct ldb_module *module, struct ldb_request *req)
req->controls,
ac, map_remote_search_callback,
req);
+ LDB_REQ_SET_LOCATION(remote_req);
if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1261,7 +1287,7 @@ static int map_remote_search_callback(struct ldb_request *req,
return ret;
}
- talloc_free(ares);
+ ac->remote_done_ares = talloc_steal(ac, ares);
ret = map_search_local(ac);
if (ret != LDB_SUCCESS) {
@@ -1333,6 +1359,7 @@ int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *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 */
@@ -1371,9 +1398,9 @@ int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares)
/* ok we are done with all search, finally it is time to
* finish operations for this module */
return ldb_module_done(ac->req,
- ac->r_current->remote->controls,
- ac->r_current->remote->response,
- ac->r_current->remote->error);
+ 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
index 612d215ae9..7faaa99708 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_private.h
+++ b/source4/lib/ldb/ldb_map/ldb_map_private.h
@@ -1,4 +1,6 @@
-#include "ldb_includes.h"
+#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"));
@@ -37,6 +39,9 @@ struct map_context {
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
diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
index d0573d389e..e5b43fd0c9 100644
--- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
+++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
@@ -255,7 +255,7 @@ static char *parsetree_to_sql(struct ldb_module *module,
char *child, *tmp;
char *ret = NULL;
char *attr;
- int i;
+ unsigned int i;
ldb = ldb_module_get_ctx(module);
@@ -557,7 +557,7 @@ query_int(const struct lsqlite3_private * lsqlite3,
}
/*
- * This is a bad hack to support ldap style comparisons whithin sqlite.
+ * 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")
@@ -667,7 +667,8 @@ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char
struct lsql_context *ac;
struct ldb_message *msg;
long long eid;
- int i, ret;
+ unsigned int i;
+ int ret;
ac = talloc_get_type(result, struct lsql_context);
ldb = ldb_module_get_ctx(ac->module);
@@ -686,14 +687,21 @@ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char
/* call the async callback for the last entry
* except the first time */
if (ac->current_eid != 0) {
- msg = ldb_msg_canonicalize(ldb, msg);
- if (!msg) return SQLITE_ABORT;
+ 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 */
@@ -959,8 +967,10 @@ int lsql_search(struct lsql_context *ctx)
/* complete the last message if any */
if (ctx->ares) {
- ctx->ares->message = ldb_msg_canonicalize(ldb, ctx->ares->message);
- if (ctx->ares->message == NULL) {
+ ret = ldb_msg_normalize(ldb, ctx->ares,
+ ctx->ares->message,
+ &ctx->ares->message);
+ if (ret != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -986,7 +996,7 @@ static int lsql_add(struct lsql_context *ctx)
char *dn, *ndn;
char *errmsg;
char *query;
- int i;
+ unsigned int i;
int ret;
ldb = ldb_module_get_ctx(module);
@@ -1043,7 +1053,7 @@ static int lsql_add(struct lsql_context *ctx)
const struct ldb_message_element *el = &msg->elements[i];
const struct ldb_schema_attribute *a;
char *attr;
- int j;
+ unsigned int j;
/* Get a case-folded copy of the attribute name */
attr = ldb_attr_casefold(ctx, el->name);
@@ -1053,6 +1063,12 @@ static int lsql_add(struct lsql_context *ctx)
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;
@@ -1097,9 +1113,9 @@ static int lsql_modify(struct lsql_context *ctx)
struct lsqlite3_private *lsqlite3;
struct ldb_context *ldb;
struct ldb_message *msg = req->op.mod.message;
- long long eid;
+ long long eid;
char *errmsg;
- int i;
+ unsigned int i;
int ret;
ldb = ldb_module_get_ctx(module);
@@ -1123,7 +1139,7 @@ static int lsql_modify(struct lsql_context *ctx)
int flags = el->flags & LDB_FLAG_MOD_MASK;
char *attr;
char *mod;
- int j;
+ unsigned int j;
/* Get a case-folded copy of the attribute name */
attr = ldb_attr_casefold(ctx, el->name);
@@ -1137,6 +1153,13 @@ static int lsql_modify(struct lsql_context *ctx)
case LDB_FLAG_MOD_REPLACE:
+ for (j=0; j<el->num_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 "
@@ -1159,7 +1182,13 @@ static int lsql_modify(struct lsql_context *ctx)
/* MISSING break is INTENTIONAL */
case LDB_FLAG_MOD_ADD:
-#warning "We should throw an error if no value is provided!"
+
+ 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;
@@ -1491,7 +1520,7 @@ static void lsql_callback(struct tevent_context *ev,
*/
default:
/* no other op supported */
- ret = LDB_ERR_UNWILLING_TO_PERFORM;
+ ret = LDB_ERR_PROTOCOL_ERROR;
}
if (!ctx->callback_failed) {
@@ -1509,7 +1538,7 @@ static int lsql_handle_request(struct ldb_module *module, struct ldb_request *re
struct tevent_timer *te;
struct timeval tv;
- if (check_critical_controls(req->controls)) {
+ if (ldb_check_critical_controls(req->controls)) {
return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
}
@@ -1845,10 +1874,11 @@ static int lsqlite3_connect(struct ldb_context *ldb,
{
struct ldb_module *module;
struct lsqlite3_private *lsqlite3;
- int i, ret;
+ unsigned int i;
+ int ret;
module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops);
- if (!module) return -1;
+ if (!module) return LDB_ERR_OPERATIONS_ERROR;
lsqlite3 = talloc(module, struct lsqlite3_private);
if (!lsqlite3) {
@@ -1892,17 +1922,18 @@ static int lsqlite3_connect(struct ldb_context *ldb,
}
*_module = module;
- return 0;
+ return LDB_SUCCESS;
failed:
if (lsqlite3 && lsqlite3->sqlite != NULL) {
(void) sqlite3_close(lsqlite3->sqlite);
}
talloc_free(lsqlite3);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
-const struct ldb_backend_ops ldb_sqlite3_backend_ops = {
- .name = "sqlite3",
- .connect_fn = lsqlite3_connect
-};
+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_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index 2c399686ea..697f7427a4 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -60,7 +60,7 @@ static void ltdb_attributes_unload(struct ldb_module *module)
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
struct ldb_message *msg;
- int i;
+ unsigned int i;
ldb = ldb_module_get_ctx(module);
@@ -83,10 +83,10 @@ static void ltdb_attributes_unload(struct ldb_module *module)
*/
static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v)
{
- int i;
+ unsigned int i;
unsigned value = 0;
for (i=0;i<el->num_values;i++) {
- int j;
+ 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) {
@@ -112,14 +112,15 @@ static int ltdb_attributes_load(struct ldb_module *module)
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
struct ldb_message *msg = ltdb->cache->attributes;
struct ldb_dn *dn;
- int i, r;
+ 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 LDB_SUCCESS;
+ return 0;
}
dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES);
@@ -202,7 +203,7 @@ static int ltdb_baseinfo_init(struct ldb_module *module)
ltdb->sequence_number = atof(initial_sequence_number);
- msg = talloc(ltdb, struct ldb_message);
+ msg = ldb_msg_new(ltdb);
if (msg == NULL) {
goto failed;
}
@@ -286,18 +287,18 @@ int ltdb_cache_load(struct ldb_module *module)
if (ltdb->cache == NULL) {
ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
if (ltdb->cache == NULL) goto failed;
- ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
- ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
+ 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 = talloc(ltdb->cache, struct ldb_message);
+ baseinfo = ldb_msg_new(ltdb->cache);
if (baseinfo == NULL) goto failed;
- baseinfo_dn = ldb_dn_new(module, ldb, LTDB_BASEINFO);
+ baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO);
if (baseinfo_dn == NULL) goto failed;
r= ltdb_search_dn1(module, baseinfo_dn, baseinfo);
@@ -326,7 +327,7 @@ int ltdb_cache_load(struct ldb_module *module)
ltdb->sequence_number = seq;
/* Read an interpret database options */
- options = talloc(ltdb->cache, struct ldb_message);
+ options = ldb_msg_new(ltdb->cache);
if (options == NULL) goto failed;
options_dn = ldb_dn_new(options, ldb, LTDB_OPTIONS);
@@ -347,16 +348,17 @@ int ltdb_cache_load(struct ldb_module *module)
talloc_free(ltdb->cache->last_attribute.name);
memset(&ltdb->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
- ltdb_attributes_unload(module);
-
talloc_free(ltdb->cache->indexlist);
+ ltdb_attributes_unload(module); /* calls internally "talloc_free" */
- ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
- ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
+ 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;
@@ -366,6 +368,13 @@ int ltdb_cache_load(struct ldb_module *module)
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;
}
@@ -373,14 +382,12 @@ int ltdb_cache_load(struct ldb_module *module)
done:
talloc_free(options);
talloc_free(baseinfo);
- talloc_free(baseinfo_dn);
talloc_free(indexlist_dn);
return 0;
failed:
talloc_free(options);
talloc_free(baseinfo);
- talloc_free(baseinfo_dn);
talloc_free(indexlist_dn);
return -1;
}
@@ -404,7 +411,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
ldb = ldb_module_get_ctx(module);
- msg = talloc(ltdb, struct ldb_message);
+ msg = ldb_msg_new(ltdb);
if (msg == NULL) {
errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
@@ -412,6 +419,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1);
if (!s) {
+ talloc_free(msg);
errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -448,13 +456,14 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
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);
+ ret = ltdb_modify_internal(module, msg, NULL);
talloc_free(msg);
@@ -471,7 +480,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
int ltdb_check_at_attributes_values(const struct ldb_val *value)
{
- int i;
+ 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)) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index b959471d16..02e4acbbde 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -1,7 +1,7 @@
/*
ldb database library
- Copyright (C) Andrew Tridgell 2004
+ 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
@@ -32,398 +32,354 @@
*/
#include "ldb_tdb.h"
-#include "dlinklist.h"
-/*
- the idxptr code is a bit unusual. The way it works is to replace
- @IDX elements in records during a transaction with @IDXPTR
- elements. The @IDXPTR elements don't contain the actual index entry
- values, but contain a pointer to a linked list of values.
-
- This means we are storing pointers in a database, which is normally
- not allowed, but in this case we are storing them only for the
- duration of a transaction, and re-writing them into the normal @IDX
- format at the end of the transaction. That means no other processes
- are ever exposed to the @IDXPTR values.
-
- The advantage is that the linked list doesn't cause huge
- fragmentation during a transaction. Without the @IDXPTR method we
- often ended up with a ldb that was between 10x and 100x larger then
- it needs to be due to massive fragmentation caused by re-writing
- @INDEX records many times during indexing.
- */
-struct ldb_index_pointer {
- struct ldb_index_pointer *next, *prev;
- struct ldb_val value;
+struct dn_list {
+ unsigned int count;
+ struct ldb_val *dn;
};
struct ltdb_idxptr {
- int num_dns;
- const char **dn_list;
- bool repack;
+ struct tdb_context *itdb;
+ int error;
};
-/*
- add to the list of DNs that need to be fixed on transaction end
- */
-static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message *msg)
+/* 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)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- ltdb->idxptr->dn_list = talloc_realloc(ltdb->idxptr, ltdb->idxptr->dn_list,
- const char *, ltdb->idxptr->num_dns+1);
- if (ltdb->idxptr->dn_list == NULL) {
- ltdb->idxptr->num_dns = 0;
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] =
- talloc_strdup(ltdb->idxptr->dn_list, ldb_dn_get_linearized(msg->dn));
- if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ltdb->idxptr->num_dns++;
+ 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;
}
-/* free an idxptr record */
-static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el)
+/* 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)
{
- struct ldb_val val;
- struct ldb_index_pointer *ptr;
-
- if (el->num_values != 1) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (v1->length > v2->length && v1->data[v2->length] != 0) {
+ return -1;
}
-
- val = el->values[0];
- if (val.length != sizeof(void *)) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (v1->length < v2->length && v2->data[v1->length] != 0) {
+ return 1;
}
+ return strncmp((char *)v1->data, (char *)v2->data, v1->length);
+}
- ptr = *(struct ldb_index_pointer **)val.data;
- if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- while (ptr) {
- struct ldb_index_pointer *tmp = ptr;
- DLIST_REMOVE(ptr, ptr);
- talloc_free(tmp);
+/*
+ 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; i<list->count; i++) {
+ if (dn_list_cmp(&list->dn[i], v) == 0) return i;
}
+ return -1;
+}
- return LDB_SUCCESS;
+/*
+ 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;
+}
-/* convert from the IDXPTR format to a ldb_message_element format */
-static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message_element *el)
+/*
+ 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_val val;
- struct ldb_index_pointer *ptr, *tmp;
- int i;
- struct ldb_val *val2;
+ 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;
- if (el->num_values != 1) {
- return LDB_ERR_OPERATIONS_ERROR;
+ 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;
}
- val = el->values[0];
- if (val.length != sizeof(void *)) {
- 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(ltdb->idxptr->itdb, key);
+ if (rec.dptr == NULL) {
+ goto normal_index;
}
- ptr = *(struct ldb_index_pointer **)val.data;
- if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
+ /* 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);
- /* count the length of the list */
- for (i=0, tmp = ptr; tmp; tmp=tmp->next) {
- i++;
- }
+ *list = *list2;
+ return LDB_SUCCESS;
- /* allocate the new values array */
- val2 = talloc_realloc(NULL, el->values, struct ldb_val, i);
- if (val2 == NULL) {
+normal_index:
+ msg = ldb_msg_new(list);
+ if (msg == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- el->values = val2;
- el->num_values = i;
- /* populate the values array */
- for (i=0, tmp = ptr; tmp; tmp=tmp->next, i++) {
- el->values[i].length = tmp->value.length;
- /* we need to over-allocate here as there are still some places
- in ldb that rely on null termination. */
- el->values[i].data = talloc_size(el->values, tmp->value.length+1);
- if (el->values[i].data == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- memcpy(el->values[i].data, tmp->value.data, tmp->value.length);
- el->values[i].data[tmp->value.length] = 0;
+ ret = ltdb_search_dn1(module, dn, msg);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return ret;
}
- /* update the name */
- el->name = LTDB_IDX;
+ /* TODO: check indexing version number */
- return LDB_SUCCESS;
+ 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;
}
-/* convert to the IDXPTR format from a ldb_message_element format */
-static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_element *el)
+/*
+ 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_index_pointer *ptr, *tmp;
- int i;
- struct ldb_val *val2;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
-
- ptr = NULL;
+ struct ldb_message *msg;
+ int ret;
- for (i=0;i<el->num_values;i++) {
- tmp = talloc(ltdb->idxptr, struct ldb_index_pointer);
- if (tmp == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- tmp->value = el->values[i];
- tmp->value.data = talloc_memdup(tmp, tmp->value.data, tmp->value.length);
- if (tmp->value.data == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (list->count == 0) {
+ ret = ltdb_delete_noindex(module, dn);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ return LDB_SUCCESS;
}
- DLIST_ADD(ptr, tmp);
+ return ret;
}
- /* allocate the new values array */
- val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1);
- if (val2 == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
+ msg = ldb_msg_new(module);
+ if (!msg) {
+ return ldb_module_oom(module);
}
- el->values = val2;
- el->num_values = 1;
-
- el->values[0].data = talloc_memdup(el->values, &ptr, sizeof(ptr));
- el->values[0].length = sizeof(ptr);
- /* update the name */
- el->name = LTDB_IDXPTR;
+ ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return ldb_module_oom(module);
+ }
- return LDB_SUCCESS;
-}
+ 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;
+ }
-/* enable the idxptr mode when transactions start */
-int ltdb_index_transaction_start(struct ldb_module *module)
-{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- ltdb->idxptr = talloc_zero(module, struct ltdb_idxptr);
- return LDB_SUCCESS;
+ ret = ltdb_store(module, msg, TDB_REPLACE);
+ talloc_free(msg);
+ return ret;
}
/*
- a wrapper around ltdb_search_dn1() which translates pointer based index records
- and maps them into normal ldb message structures
+ save a dn_list into the database, in either @IDX or internal format
*/
-static int ltdb_search_dn1_index(struct ldb_module *module,
- struct ldb_dn *dn, struct ldb_message *msg)
+static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
+ struct dn_list *list)
{
- int ret, i;
- ret = ltdb_search_dn1(module, dn, msg);
- if (ret != LDB_SUCCESS) {
- return ret;
+ 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 this isn't a @INDEX record then don't munge it */
- if (strncmp(ldb_dn_get_linearized(msg->dn), LTDB_INDEX ":", strlen(LTDB_INDEX) + 1) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (ltdb->idxptr->itdb == NULL) {
+ ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0);
+ if (ltdb->idxptr->itdb == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
- for (i=0;i<msg->num_elements;i++) {
- struct ldb_message_element *el = &msg->elements[i];
- if (strcmp(el->name, LTDB_IDXPTR) == 0) {
- ret = ltdb_convert_from_idxptr(module, el);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
+ key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
+ key.dsize = strlen((char *)key.dptr);
+
+ rec = tdb_fetch(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;
}
- return ret;
-}
+ 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 == -1) {
+ return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
+ }
+ return LDB_SUCCESS;
+}
/*
- fixup the idxptr for one DN
+ traverse function for storing the in-memory index entries on disk
*/
-static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn)
+static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
- struct ldb_context *ldb;
+ 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_message *msg = ldb_msg_new(module);
- int ret;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct ldb_val v;
+ struct dn_list *list;
- ldb = ldb_module_get_ctx(module);
+ 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_new(msg, ldb, strdn);
- if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) {
- ret = ltdb_store(module, msg, TDB_REPLACE);
+ 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;
}
- talloc_free(msg);
- return ret;
+
+ 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)
{
- int i;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
-
- /* fix all the DNs that we have modified */
- if (ltdb->idxptr) {
- for (i=0;i<ltdb->idxptr->num_dns;i++) {
- ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list[i]);
- }
+ 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);
- if (ltdb->idxptr->repack) {
- tdb_repack(ltdb->tdb);
+ 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 LDB_SUCCESS;
+ return ret;
}
/* cleanup the idxptr mode when transaction cancels */
int ltdb_index_transaction_cancel(struct ldb_module *module)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ 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;
}
-
-/* a wrapper around ltdb_store() for the index code which
- stores in IDXPTR format when idxptr mode is enabled
-
- WARNING: This modifies the msg which is passed in
-*/
-int ltdb_store_idxptr(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);
- int ret;
-
- if (ltdb->idxptr) {
- int i;
- struct ldb_message *msg2 = ldb_msg_new(module);
-
- /* free any old pointer */
- ret = ltdb_search_dn1(module, msg->dn, msg2);
- if (ret == 0) {
- for (i=0;i<msg2->num_elements;i++) {
- struct ldb_message_element *el = &msg2->elements[i];
- if (strcmp(el->name, LTDB_IDXPTR) == 0) {
- ret = ltdb_free_idxptr(module, el);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- }
- }
- }
- talloc_free(msg2);
-
- for (i=0;i<msg->num_elements;i++) {
- struct ldb_message_element *el = &msg->elements[i];
- if (strcmp(el->name, LTDB_IDX) == 0) {
- ret = ltdb_convert_to_idxptr(module, el);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- }
- }
-
- if (ltdb_idxptr_add(module, msg) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- ret = ltdb_store(module, msg, flgs);
- return ret;
-}
-
-
-/*
- find an element in a list, using the given comparison function and
- assuming that the list is already sorted using comp_fn
-
- return -1 if not found, or the index of the first occurance of needle if found
-*/
-static int ldb_list_find(const void *needle,
- const void *base, size_t nmemb, size_t size,
- comparison_fn_t comp_fn)
-{
- const char *base_p = (const char *)base;
- size_t min_i, max_i, test_i;
-
- if (nmemb == 0) {
- return -1;
- }
-
- min_i = 0;
- max_i = nmemb-1;
-
- while (min_i < max_i) {
- int r;
-
- test_i = (min_i + max_i) / 2;
- /* the following cast looks strange, but is
- correct. The key to understanding it is that base_p
- is a pointer to an array of pointers, so we have to
- dereference it after casting to void **. The strange
- const in the middle gives us the right type of pointer
- after the dereference (tridge) */
- r = comp_fn(needle, *(void * const *)(base_p + (size * test_i)));
- if (r == 0) {
- /* scan back for first element */
- while (test_i > 0 &&
- comp_fn(needle, *(void * const *)(base_p + (size * (test_i-1)))) == 0) {
- test_i--;
- }
- return test_i;
- }
- if (r < 0) {
- if (test_i == 0) {
- return -1;
- }
- max_i = test_i - 1;
- }
- if (r > 0) {
- min_i = test_i + 1;
- }
- }
-
- if (comp_fn(needle, *(void * const *)(base_p + (size * min_i))) == 0) {
- return min_i;
- }
-
- return -1;
-}
-
-struct dn_list {
- unsigned int count;
- char **dn;
-};
-
/*
return the dn key to be used for an index
- caller frees
+ 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,
@@ -457,7 +413,10 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
}
if (ldb_should_b64_encode(ldb, &v)) {
char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
- if (!vstr) return NULL;
+ 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 {
@@ -475,41 +434,40 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
/*
see if a attribute value is in the list of indexed attributes
*/
-static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr,
- unsigned int *v_idx, const char *key)
+static bool ltdb_is_indexed(const struct ldb_message *index_list, const char *attr)
{
- unsigned int i, j;
- for (i=0;i<msg->num_elements;i++) {
- if (ldb_attr_cmp(msg->elements[i].name, key) == 0) {
- const struct ldb_message_element *el = &msg->elements[i];
-
- if (attr == NULL) {
- /* in this case we are just looking to see if key is present,
- we are not spearching for a specific index */
- return 0;
- }
+ unsigned int i;
+ struct ldb_message_element *el;
- for (j=0;j<el->num_values;j++) {
- if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) {
- if (v_idx) {
- *v_idx = j;
- }
- return i;
- }
- }
+ 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; i<el->num_values; i++) {
+ if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) {
+ return true;
}
}
- return -1;
+ return false;
}
-/* used in sorting dn lists */
-static int list_cmp(const char **s1, const char **s2)
-{
- return strcmp(*s1, *s2);
-}
+/*
+ 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 or
+ 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,
@@ -519,8 +477,6 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
struct ldb_context *ldb;
struct ldb_dn *dn;
int ret;
- unsigned int i, j;
- struct ldb_message *msg;
ldb = ldb_module_get_ctx(module);
@@ -529,7 +485,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
/* if the attribute isn't in the list of indexed attributes then
this node needs a full search */
- if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) {
+ if (!ltdb_is_indexed(index_list, tree->u.equality.attr)) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -538,54 +494,13 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
if (!dn) return LDB_ERR_OPERATIONS_ERROR;
- msg = talloc(list, struct ldb_message);
- if (msg == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = ltdb_search_dn1_index(module, dn, msg);
+ ret = ltdb_dn_list_load(module, dn, list);
talloc_free(dn);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- for (i=0;i<msg->num_elements;i++) {
- struct ldb_message_element *el;
-
- if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
- continue;
- }
-
- el = &msg->elements[i];
-
- list->dn = talloc_array(list, char *, el->num_values);
- if (!list->dn) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- for (j=0;j<el->num_values;j++) {
- list->dn[list->count] =
- talloc_strdup(list->dn, (char *)el->values[j].data);
- if (!list->dn[list->count]) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- list->count++;
- }
- }
-
- talloc_free(msg);
-
- if (list->count > 1) {
- qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp);
- }
-
- return LDB_SUCCESS;
+ return ret;
}
-static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
+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
@@ -595,20 +510,13 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
const struct ldb_message *index_list,
struct dn_list *list)
{
- struct ldb_context *ldb;
- ldb = ldb_module_get_ctx(module);
-
if (ldb_attr_dn(tree->u.equality.attr) == 0) {
- list->dn = talloc_array(list, char *, 1);
+ list->dn = talloc_array(list, struct ldb_val, 1);
if (list->dn == NULL) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data);
- if (list->dn[0] == NULL) {
- ldb_oom(ldb);
+ ldb_module_oom(module);
return LDB_ERR_OPERATIONS_ERROR;
}
+ list->dn[0] = tree->u.equality.value;
list->count = 1;
return LDB_SUCCESS;
}
@@ -619,89 +527,109 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
/*
list intersection
list = list & list2
- relies on the lists being sorted
*/
-static int list_intersect(struct ldb_context *ldb,
- struct dn_list *list, const struct dn_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 || list2->count == 0) {
+ if (list->count == 0) {
/* 0 & X == 0 */
- return LDB_ERR_NO_SUCH_OBJECT;
+ return true;
+ }
+ if (list2->count == 0) {
+ /* X & 0 == 0 */
+ list->count = 0;
+ list->dn = NULL;
+ return true;
}
- list3 = talloc(ldb, struct dn_list);
+ /* 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 LDB_ERR_OPERATIONS_ERROR;
+ return false;
}
- list3->dn = talloc_array(list3, char *, list->count);
+ list3->dn = talloc_array(list3, struct ldb_val, list->count);
if (!list3->dn) {
talloc_free(list3);
- return LDB_ERR_OPERATIONS_ERROR;
+ return false;
}
list3->count = 0;
for (i=0;i<list->count;i++) {
- if (ldb_list_find(list->dn[i], list2->dn, list2->count,
- sizeof(char *), (comparison_fn_t)strcmp) != -1) {
- list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]);
+ if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) {
+ list3->dn[list3->count] = list->dn[i];
list3->count++;
- } else {
- talloc_free(list->dn[i]);
}
}
- talloc_free(list->dn);
- list->dn = talloc_move(list, &list3->dn);
+ list->dn = talloc_steal(list, list3->dn);
list->count = list3->count;
talloc_free(list3);
- return LDB_ERR_NO_SUCH_OBJECT;
+ return true;
}
/*
list union
list = list | list2
- relies on the lists being sorted
*/
-static int list_union(struct ldb_context *ldb,
- struct dn_list *list, const struct dn_list *list2)
+static bool list_union(struct ldb_context *ldb,
+ struct dn_list *list, const struct dn_list *list2)
{
- unsigned int i;
- char **d;
- unsigned int count = list->count;
+ struct ldb_val *dn3;
- if (list->count == 0 && list2->count == 0) {
- /* 0 | 0 == 0 */
- return LDB_ERR_NO_SUCH_OBJECT;
+ if (list2->count == 0) {
+ /* X | 0 == X */
+ return true;
}
- d = talloc_realloc(list, list->dn, char *, list->count + list2->count);
- if (!d) {
- return LDB_ERR_OPERATIONS_ERROR;
+ 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;
}
- list->dn = d;
- for (i=0;i<list2->count;i++) {
- if (ldb_list_find(list2->dn[i], list->dn, count,
- sizeof(char *), (comparison_fn_t)strcmp) == -1) {
- list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]);
- if (!list->dn[list->count]) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- list->count++;
- }
+ dn3 = talloc_array(list, struct ldb_val, list->count + list2->count);
+ if (!dn3) {
+ ldb_oom(ldb);
+ return false;
}
- if (list->count != count) {
- qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp);
- }
+ /* 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 LDB_ERR_NO_SUCH_OBJECT;
+ return true;
}
static int ltdb_index_dn(struct ldb_module *module,
@@ -711,7 +639,7 @@ static int ltdb_index_dn(struct ldb_module *module,
/*
- OR two index results
+ process an OR list (a union)
*/
static int ltdb_index_dn_or(struct ldb_module *module,
const struct ldb_parse_tree *tree,
@@ -720,60 +648,46 @@ static int ltdb_index_dn_or(struct ldb_module *module,
{
struct ldb_context *ldb;
unsigned int i;
- int ret;
ldb = ldb_module_get_ctx(module);
- ret = LDB_ERR_OPERATIONS_ERROR;
list->dn = NULL;
list->count = 0;
- for (i=0;i<tree->u.list.num_elements;i++) {
+ for (i=0; i<tree->u.list.num_elements; i++) {
struct dn_list *list2;
- int v;
+ int ret;
- list2 = talloc(module, struct dn_list);
+ list2 = talloc_zero(list, struct dn_list);
if (list2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
+ ret = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
- if (v == LDB_ERR_NO_SUCH_OBJECT) {
- /* 0 || X == X */
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- ret = v;
- }
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ /* X || 0 == X */
talloc_free(list2);
continue;
}
- if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) {
- /* 1 || X == 1 */
- talloc_free(list->dn);
+ if (ret != LDB_SUCCESS) {
+ /* X || * == * */
talloc_free(list2);
- return v;
+ return ret;
}
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- ret = LDB_SUCCESS;
- list->dn = talloc_move(list, &list2->dn);
- list->count = list2->count;
- } else {
- if (list_union(ldb, list, list2) == -1) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ret = LDB_SUCCESS;
+ if (!list_union(ldb, list, list2)) {
+ talloc_free(list2);
+ return LDB_ERR_OPERATIONS_ERROR;
}
- talloc_free(list2);
}
if (list->count == 0) {
return LDB_ERR_NO_SUCH_OBJECT;
}
- return ret;
+ return LDB_SUCCESS;
}
@@ -809,7 +723,7 @@ static bool ltdb_index_unique(struct ldb_context *ldb,
}
/*
- AND two index results
+ process an AND expression (intersection)
*/
static int ltdb_index_dn_and(struct ldb_module *module,
const struct ldb_parse_tree *tree,
@@ -818,175 +732,130 @@ static int ltdb_index_dn_and(struct ldb_module *module,
{
struct ldb_context *ldb;
unsigned int i;
- int ret, pass;
+ bool found;
ldb = ldb_module_get_ctx(module);
- ret = LDB_ERR_OPERATIONS_ERROR;
list->dn = NULL;
list->count = 0;
- for (pass=0;pass<=1;pass++) {
- /* in the first pass we only look for unique simple
- equality tests, in the hope of avoiding having to look
- at any others */
- bool only_unique = pass==0?true:false;
-
- for (i=0;i<tree->u.list.num_elements;i++) {
- struct dn_list *list2;
- int v;
- bool is_unique = false;
- const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
-
- if (subtree->operation == LDB_OP_EQUALITY &&
- ltdb_index_unique(ldb, subtree->u.equality.attr)) {
- is_unique = true;
- }
- if (is_unique != only_unique) continue;
-
- list2 = talloc(module, struct dn_list);
- if (list2 == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- v = ltdb_index_dn(module, subtree, index_list, list2);
+ /* 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; i<tree->u.list.num_elements; i++) {
+ const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
+ int ret;
- if (v == LDB_ERR_NO_SUCH_OBJECT) {
- /* 0 && X == 0 */
- talloc_free(list->dn);
- talloc_free(list2);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
-
- if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(list2);
- continue;
- }
-
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- ret = LDB_SUCCESS;
- talloc_free(list->dn);
- list->dn = talloc_move(list, &list2->dn);
- list->count = list2->count;
- } else {
- if (list_intersect(ldb, list, list2) == -1) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
+ 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; i<tree->u.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) {
- talloc_free(list->dn);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
+ if (list->count == 0) {
+ list->dn = NULL;
+ return LDB_ERR_NO_SUCH_OBJECT;
+ }
- if (list->count == 1) {
- /* it isn't worth loading the next part of the tree */
- return ret;
- }
+ if (list->count < 2) {
+ /* it isn't worth loading the next part of the tree */
+ return LDB_SUCCESS;
}
}
- return ret;
+
+ if (!found) {
+ /* none of the attributes were indexed */
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return LDB_SUCCESS;
}
/*
- AND index results and ONE level special index
+ 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 dn_list *list2;
- struct ldb_message *msg;
struct ldb_dn *key;
struct ldb_val val;
- unsigned int i, j;
int ret;
ldb = ldb_module_get_ctx(module);
- list2 = talloc_zero(module, struct dn_list);
- if (list2 == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* the attribute is indexed. Pull the list of DNs that match the
- search criterion */
+ /* 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) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- msg = talloc(list2, struct ldb_message);
- if (msg == NULL) {
- talloc_free(list2);
+ ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_index(module, key, msg);
+ ret = ltdb_dn_list_load(module, key, list);
talloc_free(key);
if (ret != LDB_SUCCESS) {
return ret;
}
- for (i = 0; i < msg->num_elements; i++) {
- struct ldb_message_element *el;
-
- if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
- continue;
- }
-
- el = &msg->elements[i];
-
- list2->dn = talloc_array(list2, char *, el->num_values);
- if (!list2->dn) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- for (j = 0; j < el->num_values; j++) {
- list2->dn[list2->count] = talloc_strdup(list2->dn, (char *)el->values[j].data);
- if (!list2->dn[list2->count]) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- list2->count++;
- }
- }
-
- if (list2->count == 0) {
- talloc_free(list2);
+ if (list->count == 0) {
return LDB_ERR_NO_SUCH_OBJECT;
}
- if (list2->count > 1) {
- qsort(list2->dn, list2->count, sizeof(char *), (comparison_fn_t) list_cmp);
- }
-
- if (list->count > 0) {
- if (list_intersect(ldb, list, list2) == -1) {
- talloc_free(list2);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (list->count == 0) {
- talloc_free(list->dn);
- talloc_free(list2);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
- } else {
- list->dn = talloc_move(list, &list2->dn);
- list->count = list2->count;
- }
-
- talloc_free(list2);
-
return LDB_SUCCESS;
}
@@ -1049,13 +918,14 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
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_new(msg, ldb, dn_list->dn[i]);
+ dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]);
if (dn == NULL) {
talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
@@ -1075,8 +945,13 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
return LDB_ERR_OPERATIONS_ERROR;
}
- if (!ldb_match_msg(ldb, msg,
- ac->tree, ac->base, ac->scope)) {
+ 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;
}
@@ -1091,6 +966,9 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
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;
}
@@ -1102,223 +980,193 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
}
/*
+ 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; i<list->count; 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 ldb_context *ldb;
- void *data = ldb_module_get_private(ac->module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private);
struct dn_list *dn_list;
- int ret, idxattr, idxone;
-
- ldb = ldb_module_get_ctx(ac->module);
-
- idxattr = idxone = 0;
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXATTR);
- if (ret == 0 ) {
- idxattr = 1;
- }
-
- /* We do one level indexing only if requested */
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
- if (ret == 0 ) {
- idxone = 1;
- }
+ int ret;
- if ((ac->scope == LDB_SCOPE_ONELEVEL && (idxattr+idxone == 0)) ||
- (ac->scope == LDB_SCOPE_SUBTREE && idxattr == 0)) {
- /* no indexes? must do full search */
+ /* 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;
}
- ret = LDB_ERR_OPERATIONS_ERROR;
-
dn_list = talloc_zero(ac, struct dn_list);
if (dn_list == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_module_oom(ac->module);
}
- if (ac->scope == LDB_SCOPE_BASE) {
- /* with BASE searches only one DN can match */
- dn_list->dn = talloc_array(dn_list, char *, 1);
+ switch (ac->scope) {
+ case LDB_SCOPE_BASE:
+ dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
if (dn_list->dn == NULL) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(dn_list);
+ return ldb_module_oom(ac->module);
}
- dn_list->dn[0] = ldb_dn_alloc_linearized(dn_list, ac->base);
- if (dn_list->dn[0] == NULL) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ 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;
- ret = LDB_SUCCESS;
- }
+ break;
- if (ac->scope != LDB_SCOPE_BASE && idxattr == 1) {
- ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list);
- }
-
- if (ret == LDB_ERR_OPERATIONS_ERROR &&
- ac->scope == LDB_SCOPE_ONELEVEL && idxone == 1) {
+ 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;
- if (ret == LDB_SUCCESS) {
- /* we've got a candidate list - now filter by the full tree
- and extract the needed attributes */
- ret = ltdb_index_filter(dn_list, ac, match_count);
+ 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 a index element where this is the first indexed DN for this value
-*/
-static int ltdb_index_add1_new(struct ldb_context *ldb,
- struct ldb_message *msg,
- const char *dn)
-{
- struct ldb_message_element *el;
-
- /* add another entry */
- el = talloc_realloc(msg, msg->elements,
- struct ldb_message_element, msg->num_elements+1);
- if (!el) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- msg->elements = el;
- msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX);
- if (!msg->elements[msg->num_elements].name) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- msg->elements[msg->num_elements].num_values = 0;
- msg->elements[msg->num_elements].values = talloc(msg->elements, struct ldb_val);
- if (!msg->elements[msg->num_elements].values) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- msg->elements[msg->num_elements].values[0].length = strlen(dn);
- msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn);
- msg->elements[msg->num_elements].num_values = 1;
- msg->num_elements++;
-
- return LDB_SUCCESS;
-}
-
-
-/*
- add a index element where this is not the first indexed DN for this
- value
-*/
-static int ltdb_index_add1_add(struct ldb_context *ldb,
- struct ldb_message *msg,
- int idx,
- const char *dn,
- const struct ldb_schema_attribute *a)
-{
- struct ldb_val *v2;
- unsigned int i;
-
- /* for multi-valued attributes we can end up with repeats */
- for (i=0;i<msg->elements[idx].num_values;i++) {
- if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) {
- return LDB_SUCCESS;
- }
- }
-
- if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
- return LDB_ERR_ENTRY_ALREADY_EXISTS;
- }
-
- v2 = talloc_realloc(msg->elements, msg->elements[idx].values,
- struct ldb_val,
- msg->elements[idx].num_values+1);
- if (!v2) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- msg->elements[idx].values = v2;
-
- msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn);
- msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn);
- msg->elements[idx].num_values++;
-
- return LDB_SUCCESS;
-}
-
-/*
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_message *msg;
struct ldb_dn *dn_key;
int ret;
- unsigned int i;
const struct ldb_schema_attribute *a;
+ struct dn_list *list;
+ unsigned alloc_len;
ldb = ldb_module_get_ctx(module);
- msg = talloc(module, struct ldb_message);
- if (msg == NULL) {
- errno = ENOMEM;
+ 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(msg);
+ talloc_free(list);
return LDB_ERR_OPERATIONS_ERROR;
}
- talloc_steal(msg, dn_key);
+ talloc_steal(list, dn_key);
- ret = ltdb_search_dn1_index(module, dn_key, msg);
+ ret = ltdb_dn_list_load(module, dn_key, list);
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(msg);
+ talloc_free(list);
return ret;
}
- if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- msg->dn = dn_key;
- msg->num_elements = 0;
- msg->elements = NULL;
+ if (ltdb_dn_list_find_str(list, dn) != -1) {
+ talloc_free(list);
+ return LDB_SUCCESS;
}
- for (i=0;i<msg->num_elements;i++) {
- if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) {
- break;
- }
+ 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;
}
- if (i == msg->num_elements) {
- ret = ltdb_index_add1_new(ldb, msg, dn);
- } else {
- ret = ltdb_index_add1_add(ldb, msg, i, dn, a);
+ /* 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++;
- if (ret == LDB_SUCCESS) {
- ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
- }
+ ret = ltdb_dn_list_store(module, dn_key, list);
- talloc_free(msg);
+ talloc_free(list);
return ret;
}
-static int ltdb_index_add0(struct ldb_module *module, const char *dn,
- struct ldb_message_element *elements, int num_el)
+/*
+ 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)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- int ret;
- unsigned int i, j;
+ 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;
@@ -1330,56 +1178,138 @@ static int ltdb_index_add0(struct ldb_module *module, const char *dn,
}
for (i = 0; i < num_el; i++) {
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name,
- NULL, LTDB_IDXATTR);
- if (ret == -1) {
+ int ret;
+ if (!ltdb_is_indexed(ltdb->cache->indexlist, elements[i].name)) {
continue;
}
- for (j = 0; j < elements[i].num_values; j++) {
- ret = ltdb_index_add1(module, dn, &elements[i], j);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
+ 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;
}
+
/*
- add the index entries for a new record
+ insert a one level index for a message
*/
-int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg)
+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;
}
- ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
+ 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, const char *dn,
- struct ldb_message_element *el, int v_idx)
+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_message *msg;
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);
- if (dn[0] == '@') {
+ dn_str = ldb_dn_get_linearized(dn);
+ if (dn_str == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (dn_str[0] == '@') {
return LDB_SUCCESS;
}
@@ -1388,18 +1318,13 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
return LDB_ERR_OPERATIONS_ERROR;
}
- msg = talloc(dn_key, struct ldb_message);
- if (msg == NULL) {
+ list = talloc_zero(dn_key, struct dn_list);
+ if (list == NULL) {
talloc_free(dn_key);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_index(module, dn_key, msg);
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(dn_key);
- return ret;
- }
-
+ 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 */
@@ -1407,35 +1332,26 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
return LDB_SUCCESS;
}
- i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX);
- if (i == -1) {
- struct ldb_ldif ldif;
- char *ldif_string;
- ldif.changetype = LDB_CHANGETYPE_NONE;
- ldif.msg = msg;
- ldif_string = ldb_ldif_write_string(ldb, NULL, &ldif);
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "ERROR: dn %s not found in %s", dn,
- ldif_string);
- talloc_free(ldif_string);
- /* it ain't there. hmmm */
+ if (ret != LDB_SUCCESS) {
talloc_free(dn_key);
- return LDB_SUCCESS;
+ return ret;
}
- if (j != msg->elements[i].num_values - 1) {
- memmove(&msg->elements[i].values[j],
- &msg->elements[i].values[j+1],
- (msg->elements[i].num_values-(j+1)) *
- sizeof(msg->elements[i].values[0]));
+ i = ltdb_dn_list_find_str(list, dn_str);
+ if (i == -1) {
+ /* nothing to delete */
+ talloc_free(dn_key);
+ return LDB_SUCCESS;
}
- msg->elements[i].num_values--;
- if (msg->elements[i].num_values == 0) {
- ret = ltdb_delete_noindex(module, dn_key);
- } else {
- ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
+ 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);
@@ -1443,43 +1359,38 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
}
/*
- delete the index entries for a record
+ delete the index entries for a element
return -1 on failure
*/
-int ltdb_index_del(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)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
+ const char *dn_str;
int ret;
- const char *dn;
- unsigned int i, j;
+ unsigned int i;
- /* find the list of indexed fields */
- if (ltdb->cache->indexlist->num_elements == 0) {
+ if (!ltdb->cache->attribute_indexes) {
/* no indexed fields */
return LDB_SUCCESS;
}
- if (ldb_dn_is_special(msg->dn)) {
- return LDB_SUCCESS;
+ dn_str = ldb_dn_get_linearized(dn);
+ if (dn_str == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- dn = ldb_dn_get_linearized(msg->dn);
- if (dn == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (dn_str[0] == '@') {
+ return LDB_SUCCESS;
}
- for (i = 0; i < msg->num_elements; i++) {
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
- NULL, LTDB_IDXATTR);
- if (ret == -1) {
- continue;
- }
- for (j = 0; j < msg->elements[i].num_values; j++) {
- ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
+ 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;
}
}
@@ -1487,59 +1398,37 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
}
/*
- handle special index for one level searches
+ delete the index entries for a record
+ return -1 on failure
*/
-int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add)
+int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- struct ldb_message_element el;
- struct ldb_val val;
- struct ldb_dn *pdn;
- const char *dn;
+ 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;
}
- /* We index for ONE Level only if requested */
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
- if (ret != 0) {
- 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;
+ ret = ltdb_index_onelevel(module, msg, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn));
- if (val.data == NULL) {
- talloc_free(pdn);
- return LDB_ERR_OPERATIONS_ERROR;
+ if (!ltdb->cache->attribute_indexes) {
+ /* no indexed fields */
+ return LDB_SUCCESS;
}
- 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, dn, &el, 0);
+ 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;
+ }
}
- talloc_free(pdn);
-
- return ret;
+ return LDB_SUCCESS;
}
@@ -1548,20 +1437,52 @@ int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int
*/
static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
{
- const char *dn = "DN=" LTDB_INDEX ":";
- if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) {
- return tdb_delete(tdb, key);
+ 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 ldb_module *module = (struct ldb_module *)state;
+ 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;
@@ -1574,7 +1495,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
return 0;
}
- msg = talloc(module, struct ldb_message);
+ msg = ldb_msg_new(module);
if (msg == NULL) {
return -1;
}
@@ -1582,7 +1503,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
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));
+ ldb_dn_get_linearized(msg->dn));
talloc_free(msg);
return -1;
}
@@ -1593,7 +1514,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
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));
+ ldb_dn_get_linearized(msg->dn));
talloc_free(msg);
return 0;
}
@@ -1609,18 +1530,24 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
dn = ldb_dn_get_linearized(msg->dn);
}
- ret = ltdb_index_one(module, msg, 1);
- if (ret == LDB_SUCCESS) {
- ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
- } else {
+ 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));
+ "Adding special ONE LEVEL index failed (%s)!",
+ ldb_dn_get_linearized(msg->dn));
+ talloc_free(msg);
+ return -1;
}
- talloc_free(msg);
+ ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements);
+
+ if (ret != LDB_SUCCESS) {
+ ctx->error = ret;
+ talloc_free(msg);
+ return -1;
+ }
- if (ret != LDB_SUCCESS) return -1;
+ talloc_free(msg);
return 0;
}
@@ -1630,16 +1557,18 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
*/
int ltdb_reindex(struct ldb_module *module)
{
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+ 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 */
- ret = tdb_traverse(ltdb->tdb, delete_index, NULL);
+ /* 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 == -1) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1649,14 +1578,21 @@ int ltdb_reindex(struct ldb_module *module)
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, module);
+ ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
if (ret == -1) {
+ 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 (ltdb->idxptr) {
- ltdb->idxptr->repack = true;
+ 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
index e7aeb47e72..8ab07cd347 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -59,8 +59,6 @@ static int attribute_storable_values(const struct ldb_message_element *el)
{
if (el->num_values == 0) return 0;
- if (ldb_attr_cmp(el->name, "dn") == 0) return 0;
-
if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0;
return el->num_values;
@@ -208,7 +206,6 @@ int ltdb_unpack_data(struct ldb_module *module,
}
if (message->num_elements == 0) {
- message->elements = NULL;
return 0;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index a6647ccd50..a49751de15 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -78,6 +78,7 @@ static int msg_add_element(struct ldb_message *ret,
}
elnew->num_values = el->num_values;
+ elnew->flags = el->flags;
ret->num_elements++;
@@ -97,6 +98,7 @@ static int msg_add_distinguished_name(struct ldb_message *msg)
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);
@@ -145,7 +147,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
const char * const *attrs)
{
struct ldb_message *ret;
- int i;
+ unsigned int i;
ret = talloc(mem_ctx, struct ldb_message);
if (!ret) {
@@ -325,7 +327,10 @@ int ltdb_add_attr_results(struct ldb_module *module,
*/
int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs)
{
- int i, keep_all = 0;
+ unsigned int i;
+ int keep_all = 0;
+ struct ldb_message_element *el2;
+ uint32_t num_elements;
if (attrs) {
/* check for special attrs */
@@ -352,22 +357,38 @@ int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs)
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++) {
- int j, found;
+ unsigned int j;
+ int found = 0;
- for (j = 0, found = 0; attrs[j]; j++) {
+ for (j = 0; attrs[j]; j++) {
if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) {
found = 1;
break;
}
}
- if (!found) {
- ldb_msg_remove_attr(msg, msg->elements[i].name);
- i--;
+ 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;
}
@@ -380,6 +401,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
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);
@@ -411,8 +433,13 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
}
/* see if it matches the given expression */
- if (!ldb_match_msg(ldb, msg,
- ac->tree, ac->base, ac->scope)) {
+ 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;
}
@@ -551,13 +578,19 @@ int ltdb_search(struct ltdb_context *ctx)
* callback error */
if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
/* Not indexed, so we need to do a full scan */
-#if 0
- /* useful for debugging when slow performance
- * is caused by unindexed searches */
- char *expression = ldb_filter_from_tree(ctx, ctx->tree);
- printf("FULL SEARCH: %s\n", expression);
- talloc_free(expression);
-#endif
+ 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
@@ -567,6 +600,7 @@ int ltdb_search(struct ltdb_context *ctx)
* full search or we may return
* duplicate entries
*/
+ ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
ret = ltdb_search_full(ctx);
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 55acb6132d..2f7f222086 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1,10 +1,10 @@
/*
ldb database library
- Copyright (C) Andrew Tridgell 2004
- Copyright (C) Stefan Metzmacher 2004
- Copyright (C) Simo Sorce 2006-2008
-
+ 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
@@ -36,13 +36,17 @@
*
* Modifications:
*
- * - description: make the module use asyncronous calls
+ * - 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"
@@ -51,7 +55,7 @@
/*
map a tdb error code to a ldb error code
*/
-static int ltdb_err_map(enum TDB_ERROR tdb_code)
+int ltdb_err_map(enum TDB_ERROR tdb_code)
{
switch (tdb_code) {
case TDB_SUCCESS:
@@ -73,6 +77,8 @@ static int ltdb_err_map(enum TDB_ERROR tdb_code)
return LDB_ERR_NO_SUCH_OBJECT;
case TDB_ERR_RDONLY:
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+ default:
+ break;
}
return LDB_ERR_OTHER;
}
@@ -84,10 +90,16 @@ 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);
- if (ltdb->in_transaction == 0) {
- return tdb_lockall_read(ltdb->tdb);
+ int ret = 0;
+
+ if (ltdb->in_transaction == 0 &&
+ ltdb->read_lock_count == 0) {
+ ret = tdb_lockall_read(ltdb->tdb);
}
- return 0;
+ if (ret == 0) {
+ ltdb->read_lock_count++;
+ }
+ return ret;
}
/*
@@ -97,9 +109,10 @@ 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) {
+ if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) {
return tdb_unlockall_read(ltdb->tdb);
}
+ ltdb->read_lock_count--;
return 0;
}
@@ -162,19 +175,21 @@ failed:
currently only @ATTRIBUTES is checked
*/
static int ltdb_check_special_dn(struct ldb_module *module,
- const struct ldb_message *msg)
+ const struct ldb_message *msg)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
- int i, j;
+ unsigned int i, j;
if (! ldb_dn_is_special(msg->dn) ||
! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
- return 0;
+ 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");
@@ -183,7 +198,7 @@ static int ltdb_check_special_dn(struct ldb_module *module,
}
}
- return 0;
+ return LDB_SUCCESS;
}
@@ -194,6 +209,14 @@ static int ltdb_check_special_dn(struct ldb_module *module,
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) ||
@@ -201,12 +224,20 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
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;
}
@@ -218,10 +249,10 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
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;
+ int ret = LDB_SUCCESS;
tdb_key = ltdb_key(module, msg->dn);
- if (!tdb_key.dptr) {
+ if (tdb_key.dptr == NULL) {
return LDB_ERR_OTHER;
}
@@ -237,11 +268,6 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
goto done;
}
- ret = ltdb_index_add(module, msg);
- if (ret != LDB_SUCCESS) {
- tdb_delete(ltdb->tdb, tdb_key);
- }
-
done:
talloc_free(tdb_key.dptr);
talloc_free(tdb_data.dptr);
@@ -250,60 +276,74 @@ done:
}
+/*
+ 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, i;
-
- ret = ltdb_check_special_dn(module, msg);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- if (ltdb_cache_load(module) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ int ret = LDB_SUCCESS;
+ unsigned int i;
for (i=0;i<msg->num_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)",
+ 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 (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
- ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
- 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_ERR_ENTRY_ALREADY_EXISTS) {
- ldb_asprintf_errstring(ldb,
- "Entry %s already exists",
- ldb_dn_get_linearized(msg->dn));
+ 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;
}
- if (ret == LDB_SUCCESS) {
- ret = ltdb_index_one(module, msg, 1);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- ret = ltdb_modified(module, msg->dn);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
+ ret = ltdb_index_add_new(module, msg);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
+ ret = ltdb_modified(module, msg->dn);
+
return ret;
}
@@ -314,16 +354,22 @@ static int ltdb_add(struct ltdb_context *ctx)
{
struct ldb_module *module = ctx->module;
struct ldb_request *req = ctx->req;
- int tret;
+ 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);
- tret = ltdb_add_internal(module, req->op.add.message);
- if (tret != LDB_SUCCESS) {
- return tret;
+ if (ltdb_cache_load(module) != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- return LDB_SUCCESS;
+ ret = ltdb_add_internal(module, req->op.add.message);
+
+ return ret;
}
/*
@@ -355,9 +401,9 @@ int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
{
struct ldb_message *msg;
- int ret;
+ int ret = LDB_SUCCESS;
- msg = talloc(module, struct ldb_message);
+ msg = ldb_msg_new(module);
if (msg == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -375,14 +421,8 @@ static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
goto done;
}
- /* remove one level attribute */
- ret = ltdb_index_one(module, msg, 0);
- if (ret != LDB_SUCCESS) {
- goto done;
- }
-
/* remove any indexed attributes */
- ret = ltdb_index_del(module, msg);
+ ret = ltdb_index_delete(module, msg);
if (ret != LDB_SUCCESS) {
goto done;
}
@@ -404,7 +444,7 @@ static int ltdb_delete(struct ltdb_context *ctx)
{
struct ldb_module *module = ctx->module;
struct ldb_request *req = ctx->req;
- int tret;
+ int ret = LDB_SUCCESS;
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -412,12 +452,9 @@ static int ltdb_delete(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
- tret = ltdb_delete_internal(module, req->op.del.dn);
- if (tret != LDB_SUCCESS) {
- return tret;
- }
+ ret = ltdb_delete_internal(module, req->op.del.dn);
- return LDB_SUCCESS;
+ return ret;
}
/*
@@ -446,13 +483,18 @@ static int find_element(const struct ldb_message *msg, const char *name)
returns 0 on success, -1 on failure (and sets errno)
*/
-static int msg_add_element(struct ldb_context *ldb,
- struct ldb_message *msg,
- struct ldb_message_element *el)
+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) {
@@ -466,21 +508,18 @@ static int msg_add_element(struct ldb_context *ldb,
e2->name = el->name;
e2->flags = el->flags;
- e2->values = NULL;
- if (el->num_values != 0) {
- e2->values = talloc_array(msg->elements,
- struct ldb_val, el->num_values);
- if (!e2->values) {
- errno = ENOMEM;
- return -1;
- }
+ e2->values = talloc_array(msg->elements,
+ struct ldb_val, el->num_values);
+ if (!e2->values) {
+ errno = ENOMEM;
+ return -1;
}
for (i=0;i<el->num_values;i++) {
e2->values[i] = el->values[i];
}
e2->num_values = el->num_values;
- msg->num_elements++;
+ ++msg->num_elements;
return 0;
}
@@ -492,42 +531,36 @@ static int msg_delete_attribute(struct ldb_module *module,
struct ldb_context *ldb,
struct ldb_message *msg, const char *name)
{
- const char *dn;
- unsigned int i, j;
+ unsigned int i;
+ int ret;
+ struct ldb_message_element *el;
- dn = ldb_dn_get_linearized(msg->dn);
- if (dn == NULL) {
- return -1;
+ el = ldb_msg_find_element(msg, name);
+ if (el == NULL) {
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
+ i = el - msg->elements;
- for (i=0;i<msg->num_elements;i++) {
- if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
- for (j=0;j<msg->elements[i].num_values;j++) {
- ltdb_index_del_value(module, dn,
- &msg->elements[i], j);
- }
- talloc_free(msg->elements[i].values);
- if (msg->num_elements > (i+1)) {
- memmove(&msg->elements[i],
- &msg->elements[i+1],
- sizeof(struct ldb_message_element)*
- (msg->num_elements - (i+1)));
- }
- msg->num_elements--;
- i--;
- msg->elements = talloc_realloc(msg, msg->elements,
- struct ldb_message_element,
- msg->num_elements);
- }
+ ret = ltdb_index_del_element(module, msg->dn, el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- return 0;
+ 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 0 on success, -1 on failure
+ return LDB Error on failure
*/
static int msg_delete_element(struct ldb_module *module,
struct ldb_message *msg,
@@ -536,37 +569,55 @@ static int msg_delete_element(struct ldb_module *module,
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
unsigned int i;
- int found;
+ int found, ret;
struct ldb_message_element *el;
const struct ldb_schema_attribute *a;
found = find_element(msg, name);
if (found == -1) {
- return -1;
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
- el = &msg->elements[found];
+ i = (unsigned int) found;
+ el = &(msg->elements[i]);
a = ldb_schema_attribute_by_name(ldb, el->name);
for (i=0;i<el->num_values;i++) {
- if (a->syntax->comparison_fn(ldb, ldb,
- &el->values[i], val) == 0) {
+ 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 (i<el->num_values-1) {
memmove(&el->values[i], &el->values[i+1],
sizeof(el->values[i])*
(el->num_values-(i+1)));
}
el->num_values--;
- if (el->num_values == 0) {
- return msg_delete_attribute(module, ldb,
- msg, name);
- }
- return 0;
+
+ /* per definition we find in a canonicalised message an
+ attribute value only once. So we are finished here */
+ return LDB_SUCCESS;
}
}
- return -1;
+ /* Not found */
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
@@ -576,17 +627,26 @@ static int msg_delete_element(struct ldb_module *module,
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)
+ 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 i, j;
- int ret, idx;
+ 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) {
@@ -599,192 +659,268 @@ int ltdb_modify_internal(struct ldb_module *module,
return ltdb_err_map(tdb_error(ltdb->tdb));
}
- msg2 = talloc(tdb_key.dptr, struct ldb_message);
+ msg2 = ldb_msg_new(tdb_key.dptr);
if (msg2 == NULL) {
- talloc_free(tdb_key.dptr);
- return LDB_ERR_OTHER;
+ 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 failed;
+ goto done;
}
if (!msg2->dn) {
msg2->dn = msg->dn;
}
- for (i=0;i<msg->num_elements;i++) {
- struct ldb_message_element *el = &msg->elements[i];
- struct ldb_message_element *el2;
+ for (i=0; i<msg->num_elements; i++) {
+ struct ldb_message_element *el = &msg->elements[i], *el2;
struct ldb_val *vals;
- const char *dn;
const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
- switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
+ const char *dn;
+ switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
case LDB_FLAG_MOD_ADD:
-
- /* add this element to the message. fail if it
- already exists */
- idx = find_element(msg2, el->name);
if (el->num_values == 0) {
- ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)",
- el->name, ldb_dn_get_linearized(msg->dn));
- return LDB_ERR_CONSTRAINT_VIOLATION;
+ 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;
}
- if (idx == -1) {
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
- ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
- el->name, ldb_dn_get_linearized(msg->dn));
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
+
+ /* 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;
}
- if (msg_add_element(ldb, msg2, el) != 0) {
+ *el = msg->elements[i];
+ el->values = talloc_array(el, struct ldb_val, el->num_values);
+ if (el->values == NULL) {
ret = LDB_ERR_OTHER;
- goto failed;
+ goto done;
+ }
+ for (j = 0; j < el->num_values; j++) {
+ el->values[j] = msg->elements[i].values[j];
}
- continue;
}
- /* If this is an add, then if it already
- * exists in the object, then we violoate the
- * single-value rule */
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- 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(msg2->dn));
+ ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ goto done;
}
- el2 = &msg2->elements[idx];
-
- /* An attribute with this name already exists,
- * add all values if they don't already exist
- * (check both the other elements to be added,
- * and those already in the db). */
-
- for (j=0;j<el->num_values;j++) {
- if (ldb_msg_find_val(el2, &el->values[j])) {
- ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
- ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
- goto failed;
+ /* 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;
}
- 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);
+ 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 failed;
+ goto done;
}
- }
- vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
- el2->num_values + el->num_values);
+ /* 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;
+ }
+ }
- if (vals == NULL) {
- ret = LDB_ERR_OTHER;
- goto failed;
- }
+ /* 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;j<el->num_values;j++) {
- vals[el2->num_values + j] =
- ldb_val_dup(vals, &el->values[j]);
- }
+ for (j=0; j<el->num_values; j++) {
+ vals[el2->num_values + j] =
+ ldb_val_dup(vals, &el->values[j]);
+ }
- el2->values = vals;
- el2->num_values += el->num_values;
+ 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 (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
- ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
- 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(msg2->dn));
+ ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ goto done;
}
- /* replace all elements of this attribute name with the elements
- listed. The attribute not existing is not an error */
- msg_delete_attribute(module, ldb, msg2, el->name);
- for (j=0;j<el->num_values;j++) {
+ /* TODO: This is O(n^2) - replace with more efficient check */
+ for (j=0; j<el->num_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);
+ 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 failed;
+ 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;
}
}
- /* add the replacement element, if not empty */
- if (el->num_values != 0 &&
- msg_add_element(ldb, msg2, el) != 0) {
+ /* Recreate it with the new values */
+ if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
ret = LDB_ERR_OTHER;
- goto failed;
+ 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(msg->dn);
+ dn = ldb_dn_get_linearized(msg2->dn);
if (dn == NULL) {
ret = LDB_ERR_OTHER;
- goto failed;
+ goto done;
}
- /* we could be being asked to delete all
- values or just some values */
if (msg->elements[i].num_values == 0) {
- if (msg_delete_attribute(module, ldb, msg2,
- msg->elements[i].name) != 0) {
- ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
- ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
- goto failed;
- }
- break;
- }
- for (j=0;j<msg->elements[i].num_values;j++) {
- if (msg_delete_element(module,
- msg2,
- msg->elements[i].name,
- &msg->elements[i].values[j]) != 0) {
- ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
- ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
- goto failed;
+ /* 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);
}
- ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
if (ret != LDB_SUCCESS) {
- goto failed;
+ 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,
- "Invalid ldb_modify flags on %s: 0x%x",
- msg->elements[i].name,
- msg->elements[i].flags & LDB_FLAG_MOD_MASK);
+ "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 failed;
+ goto done;
}
}
- /* we've made all the mods
- * save the modified record back into the database */
ret = ltdb_store(module, msg2, TDB_MODIFY);
if (ret != LDB_SUCCESS) {
- goto failed;
+ goto done;
}
- ret = ltdb_modified(module, msg->dn);
+ ret = ltdb_modified(module, msg2->dn);
if (ret != LDB_SUCCESS) {
- goto failed;
+ goto done;
}
+done:
talloc_free(tdb_key.dptr);
- free(tdb_data.dptr);
- return ret;
-
-failed:
- talloc_free(tdb_key.dptr);
- free(tdb_data.dptr);
return ret;
}
@@ -795,25 +931,22 @@ static int ltdb_modify(struct ltdb_context *ctx)
{
struct ldb_module *module = ctx->module;
struct ldb_request *req = ctx->req;
- int tret;
-
- ldb_request_set_state(req, LDB_ASYNC_PENDING);
+ int ret = LDB_SUCCESS;
- tret = ltdb_check_special_dn(module, req->op.mod.message);
- if (tret != LDB_SUCCESS) {
- return tret;
+ 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;
}
- tret = ltdb_modify_internal(module, req->op.mod.message);
- if (tret != LDB_SUCCESS) {
- return tret;
- }
+ ret = ltdb_modify_internal(module, req->op.mod.message, req);
- return LDB_SUCCESS;
+ return ret;
}
/*
@@ -824,7 +957,7 @@ 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 tret;
+ int ret = LDB_SUCCESS;
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -832,39 +965,36 @@ static int ltdb_rename(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
- msg = talloc(ctx, struct ldb_message);
+ 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 */
- tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
- if (tret != LDB_SUCCESS) {
+ ret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
+ if (ret != LDB_SUCCESS) {
/* not finding the old record is an error */
- return tret;
- }
-
- msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
- if (!msg->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
/* Always delete first then add, to avoid conflicts with
* unique indexes. We rely on the transaction to make this
* atomic
*/
- tret = ltdb_delete_internal(module, req->op.rename.olddn);
- if (tret != LDB_SUCCESS) {
- return tret;
+ ret = ltdb_delete_internal(module, msg->dn);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- tret = ltdb_add_internal(module, msg);
- if (tret != LDB_SUCCESS) {
- return tret;
+ msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
+ if (msg->dn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- return LDB_SUCCESS;
+ ret = ltdb_add_internal(module, msg);
+
+ return ret;
}
static int ltdb_start_trans(struct ldb_module *module)
@@ -958,13 +1088,13 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
struct ldb_context *ldb;
struct ldb_module *module = ctx->module;
struct ldb_request *req = ctx->req;
- TALLOC_CTX *tmp_ctx;
+ 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;
+ int ret = LDB_SUCCESS;
ldb = ldb_module_get_ctx(module);
@@ -985,6 +1115,7 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
ret = LDB_ERR_OPERATIONS_ERROR;
goto done;
}
+
tmp_ctx = talloc_new(req);
if (tmp_ctx == NULL) {
ret = LDB_ERR_OPERATIONS_ERROR;
@@ -992,8 +1123,12 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
}
dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
+ if (dn == NULL) {
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto done;
+ }
- msg = talloc(tmp_ctx, struct ldb_message);
+ msg = ldb_msg_new(tmp_ctx);
if (msg == NULL) {
ret = LDB_ERR_OPERATIONS_ERROR;
goto done;
@@ -1031,8 +1166,6 @@ static int ltdb_sequence_number(struct ltdb_context *ctx,
(*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
(*ext)->data = talloc_steal(*ext, res);
- ret = LDB_SUCCESS;
-
done:
talloc_free(tmp_ctx);
ltdb_unlock_read(module);
@@ -1166,7 +1299,7 @@ static void ltdb_callback(struct tevent_context *ev,
goto done;
default:
/* no other op supported */
- ret = LDB_ERR_UNWILLING_TO_PERFORM;
+ ret = LDB_ERR_PROTOCOL_ERROR;
}
if (!ctx->request_terminated) {
@@ -1196,18 +1329,28 @@ static int ltdb_request_destructor(void *ptr)
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;
-
- if (check_critical_controls(req->controls)) {
- return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
- }
+ 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;
@@ -1217,7 +1360,7 @@ static int ltdb_handle_request(struct ldb_module *module,
ac = talloc_zero(ldb, struct ltdb_context);
if (ac == NULL) {
- ldb_set_errstring(ldb, "Out of Memory");
+ ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1253,8 +1396,24 @@ static int ltdb_handle_request(struct ldb_module *module,
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,
@@ -1284,7 +1443,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
if (strncmp(url, "tdb://", 6) != 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
"Invalid tdb URL '%s'", url);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
path = url+6;
} else {
@@ -1312,7 +1471,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
ltdb = talloc_zero(ldb, struct ltdb_private);
if (!ltdb) {
ldb_oom(ldb);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* note that we use quite a large default hash size */
@@ -1323,7 +1482,11 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
ldb_debug(ldb, LDB_DEBUG_ERROR,
"Unable to open tdb '%s'", path);
talloc_free(ltdb);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (getenv("LDB_WARN_UNINDEXED")) {
+ ltdb->warn_unindexed = true;
}
ltdb->sequence_number = 0;
@@ -1331,21 +1494,23 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
module = ldb_module_new(ldb, ldb, "ldb_tdb backend", &ltdb_ops);
if (!module) {
talloc_free(ltdb);
- return -1;
+ 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 -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
*_module = module;
- return 0;
+ return LDB_SUCCESS;
}
-const struct ldb_backend_ops ldb_tdb_backend_ops = {
- .name = "tdb",
- .connect_fn = ltdb_connect
-};
+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
index c8c1dad5de..33313b00da 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -1,4 +1,6 @@
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "tdb.h"
#include "ldb_module.h"
@@ -17,6 +19,8 @@ struct ltdb_private {
struct ltdb_cache {
struct ldb_message *indexlist;
struct ldb_message *attributes;
+ bool one_level_indexes;
+ bool attribute_indexes;
struct {
char *name;
@@ -29,6 +33,9 @@ struct ltdb_private {
bool check_base;
struct ltdb_idxptr *idxptr;
bool prepared_commit;
+ int read_lock_count;
+
+ bool warn_unindexed;
};
/*
@@ -58,7 +65,7 @@ struct ltdb_context {
#define LTDB_INDEX "@INDEX"
#define LTDB_INDEXLIST "@INDEXLIST"
#define LTDB_IDX "@IDX"
-#define LTDB_IDXPTR "@IDXPTR"
+#define LTDB_IDXVERSION "@IDXVERSION"
#define LTDB_IDXATTR "@IDXATTR"
#define LTDB_IDXONE "@IDXONE"
#define LTDB_BASEINFO "@BASEINFO"
@@ -83,9 +90,14 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value);
struct ldb_parse_tree;
int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *);
-int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg);
-int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg);
-int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add);
+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);
@@ -122,11 +134,9 @@ int ltdb_lock_read(struct ldb_module *module);
int ltdb_unlock_read(struct ldb_module *module);
struct 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_modify_internal(struct ldb_module *module, const struct ldb_message *msg);
-
-int ltdb_index_del_value(struct ldb_module *module, const char *dn,
- struct ldb_message_element *el, int v_idx);
+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,
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c
index 6ee8417e25..b9f3e79f20 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c
@@ -22,6 +22,7 @@
*/
#include "ldb_tdb.h"
+#include "dlinklist.h"
/*
the purpose of this code is to work around the braindead posix locking
@@ -42,15 +43,7 @@ static struct ltdb_wrap *tdb_list;
static int ltdb_wrap_destructor(struct ltdb_wrap *w)
{
tdb_close(w->tdb);
- if (w->next) {
- w->next->prev = w->prev;
- }
- if (w->prev) {
- w->prev->next = w->next;
- }
- if (w == tdb_list) {
- tdb_list = w->next;
- }
+ DLIST_REMOVE(tdb_list, w);
return 0;
}
@@ -143,12 +136,7 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,
talloc_set_destructor(w, ltdb_wrap_destructor);
- w->next = tdb_list;
- w->prev = NULL;
- if (tdb_list) {
- tdb_list->prev = w;
- }
- tdb_list = w;
+ DLIST_ADD(tdb_list, w);
return w->tdb;
}
diff --git a/source4/lib/ldb/libldb.m4 b/source4/lib/ldb/libldb.m4
deleted file mode 100644
index 5653794a88..0000000000
--- a/source4/lib/ldb/libldb.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# disable ldb_sqlite3 by default
-SMB_ENABLE(ldb_sqlite3, NO)
-
-#if test x"$with_sqlite3_support" = x"yes"; then
-# SMB_ENABLE(ldb_sqlite3, YES)
-#fi
diff --git a/source4/lib/ldb/man/ad2oLschema.1.xml b/source4/lib/ldb/man/ad2oLschema.1.xml
deleted file mode 100644
index 6ae8996477..0000000000
--- a/source4/lib/ldb/man/ad2oLschema.1.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ad2oLschema.1">
-
-<refmeta>
- <refentrytitle>ad2oLschema</refentrytitle>
- <manvolnum>1</manvolnum>
-</refmeta>
-
-
-<refnamediv>
- <refname>ad2oLschema</refname>
- <refpurpose>Converts AC-like LDAP schemas to OpenLDAP
- compatible schema files</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
- <cmdsynopsis>
- <command>ad2oLschema</command>
- <arg choice="opt">-I INPUT-FILE</arg>
- <arg choice="opt">-O OUTPUT-FILE</arg>
- </cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
- <title>DESCRIPTION</title>
-
- <para>ad2oLschema is a simple tool that converts AD-like LDIF
- schema files into OpenLDAP schema files.</para>
-</refsect1>
-
-
-<refsect1>
- <title>OPTIONS</title>
-
- <variablelist>
- <varlistentry>
- <term>-H url</term>
- <listitem><para>URL to an LDB or LDAP server with an AD schema to read. </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-I input-file</term> <listitem><para>AD schema
- to read. If neither this nor -H is specified, the
- schema file will be read from standard input.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-O output-file</term>
- <listitem><para>File to write OpenLDAP version of schema to.
- </para></listitem>
- </varlistentry>
- </variablelist>
-</refsect1>
-
-<refsect1>
- <title>VERSION</title>
-
- <para>This man page is correct for version 4.0 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
- <title>SEE ALSO</title>
-
- <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
-
-</refsect1>
-
-<refsect1>
- <title>AUTHOR</title>
-
- <para> ldb was written by
- <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
- ad2oLschema was written by <ulink
- url="http://samba.org/~abartlet/">Andrew Bartlett</ulink>.
- </para>
-
- <para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
- </para>
-
-</refsect1>
-
-</refentry>
diff --git a/source4/lib/ldb/man/ldbadd.1.xml b/source4/lib/ldb/man/ldbadd.1.xml
index 7ad0f835d0..b77b151e2d 100644
--- a/source4/lib/ldb/man/ldbadd.1.xml
+++ b/source4/lib/ldb/man/ldbadd.1.xml
@@ -27,7 +27,7 @@
<refsect1>
<title>DESCRIPTION</title>
- <para>ldbadd adds records to an ldb(7) database. It reads
+ <para>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.
@@ -52,7 +52,7 @@
<varlistentry>
<term>-H &lt;ldb-url&gt;</term>
<listitem><para>
- LDB URL to connect to. See ldb(7) for details.
+ LDB URL to connect to. See ldb(3) for details.
</para></listitem>
</varlistentry>
@@ -81,7 +81,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
+ <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para>
</refsect1>
diff --git a/source4/lib/ldb/man/ldbdel.1.xml b/source4/lib/ldb/man/ldbdel.1.xml
index 7dfc7366f6..41da3bc984 100644
--- a/source4/lib/ldb/man/ldbdel.1.xml
+++ b/source4/lib/ldb/man/ldbdel.1.xml
@@ -26,7 +26,7 @@
<refsect1>
<title>DESCRIPTION</title>
- <para>ldbdel deletes records from an ldb(7) database.
+ <para>ldbdel deletes records from an ldb(3) database.
It deletes the records identified by the dn's specified
on the command-line. </para>
@@ -50,7 +50,7 @@
<varlistentry>
<term>-H &lt;ldb-url&gt;</term>
<listitem><para>
- LDB URL to connect to. See ldb(7) for details.
+ LDB URL to connect to. See ldb(3) for details.
</para></listitem>
</varlistentry>
@@ -79,7 +79,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbmodify, ldbadd, ldif(5)</para>
+ <para>ldb(3), ldbmodify, ldbadd, ldif(5)</para>
</refsect1>
diff --git a/source4/lib/ldb/man/ldbedit.1.xml b/source4/lib/ldb/man/ldbedit.1.xml
index 15c69b1b25..a2eec0579c 100644
--- a/source4/lib/ldb/man/ldbedit.1.xml
+++ b/source4/lib/ldb/man/ldbedit.1.xml
@@ -172,7 +172,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>
+ <para>ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>
</refsect1>
diff --git a/source4/lib/ldb/man/ldbmodify.1.xml b/source4/lib/ldb/man/ldbmodify.1.xml
index bc19647785..9bb492ab1b 100644
--- a/source4/lib/ldb/man/ldbmodify.1.xml
+++ b/source4/lib/ldb/man/ldbmodify.1.xml
@@ -42,7 +42,7 @@
<varlistentry>
<term>-H &lt;ldb-url&gt;</term>
<listitem><para>
- LDB URL to connect to. See ldb(7) for details.
+ LDB URL to connect to. See ldb(3) for details.
</para></listitem>
</varlistentry>
</variablelist>
@@ -69,7 +69,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbedit</para>
+ <para>ldb(3), ldbedit</para>
</refsect1>
diff --git a/source4/lib/ldb/man/ldbrename.1.xml b/source4/lib/ldb/man/ldbrename.1.xml
index 391ec84ccc..3576bc27bb 100644
--- a/source4/lib/ldb/man/ldbrename.1.xml
+++ b/source4/lib/ldb/man/ldbrename.1.xml
@@ -48,7 +48,7 @@
<varlistentry>
<term>-H &lt;ldb-url&gt;</term>
<listitem><para>
- LDB URL to connect to. See ldb(7) for details.
+ LDB URL to connect to. See ldb(3) for details.
</para></listitem>
</varlistentry>
@@ -83,7 +83,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
+ <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para>
</refsect1>
diff --git a/source4/lib/ldb/man/ldbsearch.1.xml b/source4/lib/ldb/man/ldbsearch.1.xml
index ed3749b920..623a5992e5 100644
--- a/source4/lib/ldb/man/ldbsearch.1.xml
+++ b/source4/lib/ldb/man/ldbsearch.1.xml
@@ -51,7 +51,7 @@
<varlistentry>
<term>-H &lt;ldb-url&gt;</term>
<listitem><para>
- LDB URL to connect to. See ldb(7) for details.
+ LDB URL to connect to. See ldb(3) for details.
</para></listitem>
</varlistentry>
@@ -95,7 +95,7 @@
<refsect1>
<title>SEE ALSO</title>
- <para>ldb(7), ldbedit(1)</para>
+ <para>ldb(3), ldbedit(1)</para>
</refsect1>
diff --git a/source4/lib/ldb/man/oLschema2ldif.1.xml b/source4/lib/ldb/man/oLschema2ldif.1.xml
deleted file mode 100644
index b1e681be4e..0000000000
--- a/source4/lib/ldb/man/oLschema2ldif.1.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="oLschema2ldif.1">
-
-<refmeta>
- <refentrytitle>oLschema2ldif</refentrytitle>
- <manvolnum>1</manvolnum>
-</refmeta>
-
-
-<refnamediv>
- <refname>oLschema2ldif</refname>
- <refpurpose>Converts LDAP schema's to LDB-compatible LDIF</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
- <cmdsynopsis>
- <command>oLschema2ldif</command>
- <arg choice="opt">-I INPUT-FILE</arg>
- <arg choice="opt">-O OUTPUT-FILE</arg>
- </cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
- <title>DESCRIPTION</title>
-
- <para>oLschema2ldif is a simple tool that converts standard OpenLDAP schema files to a LDIF format that is understood by LDB.</para>
-</refsect1>
-
-
-<refsect1>
- <title>OPTIONS</title>
-
- <variablelist>
- <varlistentry>
- <term>-I input-file</term>
- <listitem><para>OpenLDAP schema to read. If none are specified,
-the schema file will be read from standard input.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-O output-file</term>
- <listitem><para>File to write ldif version of schema to.
- </para></listitem>
- </varlistentry>
- </variablelist>
-</refsect1>
-
-<refsect1>
- <title>VERSION</title>
-
- <para>This man page is correct for version 4.0 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
- <title>SEE ALSO</title>
-
- <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
-
-</refsect1>
-
-<refsect1>
- <title>AUTHOR</title>
-
- <para> ldb was written by
- <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
- oLschema2ldif was written by <ulink url="mailto:idra@samba.org">Simo Sorce</ulink>.
- </para>
-
- <para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
- </para>
-
-</refsect1>
-
-</refentry>
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c
index 0819f7f559..7482de826f 100644
--- a/source4/lib/ldb/modules/asq.c
+++ b/source4/lib/ldb/modules/asq.c
@@ -32,6 +32,9 @@
* Author: Simo Sorce
*/
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
struct asq_context {
@@ -55,8 +58,8 @@ struct asq_context {
struct ldb_reply *base_res;
struct ldb_request **reqs;
- int num_reqs;
- int cur_req;
+ unsigned int num_reqs;
+ unsigned int cur_req;
struct ldb_control **controls;
};
@@ -85,7 +88,7 @@ static int asq_search_continue(struct asq_context *ac);
static int asq_search_terminate(struct asq_context *ac)
{
struct ldb_asq_control *asq;
- int i;
+ unsigned int i;
if (ac->controls) {
for (i = 0; ac->controls[i]; i++) /* count em */ ;
@@ -237,7 +240,7 @@ static int asq_build_first_request(struct asq_context *ac, struct ldb_request **
ac, asq_base_callback,
ac->req);
if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
return LDB_SUCCESS;
@@ -250,7 +253,8 @@ static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated)
struct ldb_control *control;
struct ldb_dn *dn;
struct ldb_message_element *el;
- int ret, i;
+ unsigned int i;
+ int ret;
if (ac->base_res == NULL) {
return LDB_ERR_NO_SUCH_OBJECT;
@@ -292,12 +296,12 @@ static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated)
ac, asq_reqs_callback,
ac->req);
if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
/* remove the ASQ control itself */
control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID);
- if (!save_controls(control, ac->reqs[i], &saved_controls)) {
+ if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) {
return LDB_ERR_OPERATIONS_ERROR;
}
}
@@ -399,8 +403,14 @@ static int asq_init(struct ldb_module *module)
return ldb_next_init(module);
}
-const struct ldb_module_ops ldb_asq_module_ops = {
+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
index b712f84872..2d6c62fd54 100644
--- a/source4/lib/ldb/modules/paged_results.c
+++ b/source4/lib/ldb/modules/paged_results.c
@@ -32,7 +32,9 @@
* Author: Simo Sorce
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
struct message_store {
@@ -65,8 +67,7 @@ struct results_store {
};
struct private_data {
-
- int next_free_id;
+ unsigned int next_free_id;
struct results_store *store;
};
@@ -95,7 +96,7 @@ static int store_destructor(struct results_store *del)
static struct results_store *new_store(struct private_data *priv)
{
struct results_store *newr;
- int new_id = priv->next_free_id++;
+ unsigned int new_id = priv->next_free_id++;
/* TODO: we should have a limit on the number of
* outstanding paged searches
@@ -140,7 +141,8 @@ static int paged_results(struct paged_context *ac)
{
struct ldb_paged_control *paged;
struct message_store *msg;
- int i, num_ctrls, ret;
+ unsigned int i, num_ctrls;
+ int ret;
if (ac->store == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
@@ -326,6 +328,11 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
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) {
@@ -347,11 +354,14 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
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 (!save_controls(control, search_req, &saved_controls)) {
+ if (!ldb_save_controls(control, search_req, &saved_controls)) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -415,8 +425,14 @@ static int paged_request_init(struct ldb_module *module)
return ldb_next_init(module);
}
-const struct ldb_module_ops ldb_paged_results_module_ops = {
+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
index c5430eb9bf..68eeb4c76e 100644
--- a/source4/lib/ldb/modules/paged_searches.c
+++ b/source4/lib/ldb/modules/paged_searches.c
@@ -33,7 +33,9 @@
* Author: Simo Sorce
*/
-#include "includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
#define PS_DEFAULT_PAGE_SIZE 500
@@ -52,7 +54,7 @@ struct ps_context {
bool pending;
char **saved_referrals;
- int num_referrals;
+ unsigned int num_referrals;
struct ldb_request *down_req;
};
@@ -78,7 +80,7 @@ static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req,
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 recived yet, valid to just return the full data set */
+ /* No cookie received yet, valid to just return the full data set */
/* we are done */
ac->pending = false;
@@ -132,7 +134,7 @@ static int send_referrals(struct ps_context *ac)
{
struct ldb_reply *ares;
int ret;
- int i;
+ unsigned int i;
for (i = 0; i < ac->num_referrals; i++) {
ares = talloc_zero(ac->req, struct ldb_reply);
@@ -270,6 +272,7 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
ac,
ps_callback,
ac->req);
+ LDB_REQ_SET_LOCATION(ac->down_req);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -351,6 +354,7 @@ static int ps_init(struct ldb_module *module)
attrs, NULL,
data, check_supported_paged,
NULL);
+ LDB_REQ_SET_LOCATION(req);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -369,8 +373,14 @@ static int ps_init(struct ldb_module *module)
return ldb_next_init(module);
}
-_PUBLIC_ const struct ldb_module_ops ldb_paged_searches_module_ops = {
+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
index 8b54f52b5e..50b63aee13 100644
--- a/source4/lib/ldb/modules/rdn_name.c
+++ b/source4/lib/ldb/modules/rdn_name.c
@@ -1,7 +1,7 @@
/*
ldb database library
- Copyright (C) Andrew Bartlett 2005
+ Copyright (C) Andrew Bartlett 2005-2009
Copyright (C) Simo Sorce 2006-2008
** NOTE! The following LGPL license applies to the ldb
@@ -36,30 +36,18 @@
* Simo Sorce Mar 2006
*/
-#include "ldb_includes.h"
+#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 struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name)
-{
- int i;
-
- for (i = 0; i < msg->num_elements; i++) {
- if (ldb_attr_cmp(name, msg->elements[i].name) == 0) {
- return &msg->elements[i];
- }
- }
-
- return NULL;
-}
-
static int rdn_name_add_callback(struct ldb_request *req,
struct ldb_reply *ares)
{
@@ -71,6 +59,11 @@ static int rdn_name_add_callback(struct ldb_request *req,
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);
@@ -94,11 +87,12 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
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;
- int i, ret;
+ unsigned int i;
+ int ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.add.message->dn)) {
@@ -120,52 +114,78 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
rdn_name = ldb_dn_get_rdn_name(msg->dn);
if (rdn_name == NULL) {
- talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
- rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn));
-
- /* Perhaps someone above us tried to set this? */
- if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) {
- attribute->num_values = 0;
+ 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);
- if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
- talloc_free(ac);
- return LDB_ERR_OPERATIONS_ERROR;
+ /* 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;
}
- attribute = rdn_name_find_attribute(msg, rdn_name);
+ 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) {
- if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
- talloc_free(ac);
- return LDB_ERR_OPERATIONS_ERROR;
+ /* 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 {
- a = ldb_schema_attribute_by_name(ldb, rdn_name);
-
+ /* normalise attribute name if possible */
+ if (a->name != NULL) {
+ attribute->name = a->name;
+ }
+ /* normalise attribute value */
for (i = 0; i < attribute->num_values; i++) {
- ret = a->syntax->comparison_fn(ldb, msg,
- &rdn_val, &attribute->values[i]);
- if (ret == 0) {
+ 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);
+ 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);
+ rdn_errstring = talloc_asprintf_append(
+ rdn_errstring, " (%.*s)",
+ (int)attribute->values[i].length,
+ (const char *)attribute->values[i].data);
}
- ldb_debug_set(ldb, LDB_DEBUG_FATAL, "%s", rdn_errstring);
- talloc_free(ac);
+ ldb_set_errstring(ldb, rdn_errstring);
/* Match AD's error here */
return LDB_ERR_INVALID_DN_SYNTAX;
}
@@ -196,6 +216,11 @@ static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *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);
@@ -218,6 +243,7 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
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;
@@ -228,6 +254,11 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
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);
@@ -249,13 +280,24 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
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 = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn));
-
+
+ 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;
}
@@ -278,12 +320,11 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
}
talloc_steal(mod_req, msg);
- /* do the mod call */
- return ldb_request(ldb, mod_req);
+ /* 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);
+ 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)
@@ -294,7 +335,6 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
int ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.rename.newdn)) {
@@ -320,15 +360,94 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
req);
if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
/* rename first, modify "name" if rename is ok */
return ldb_next_request(module, down_req);
}
-const struct ldb_module_ops ldb_rdn_name_module_ops = {
+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
index 248f9b346b..1ce3ec1df9 100644
--- a/source4/lib/ldb/modules/skel.c
+++ b/source4/lib/ldb/modules/skel.c
@@ -1,4 +1,4 @@
-/*
+/*
ldb database library
Copyright (C) Simo Sorce 2004
@@ -6,7 +6,7 @@
** 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
@@ -31,6 +31,9 @@
* Author: Simo Sorce
*/
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
struct private_data {
@@ -123,7 +126,7 @@ static int skel_init(struct ldb_module *module)
return ldb_next_init(module);
}
-const struct ldb_module_ops ldb_skel_module_ops = {
+static const struct ldb_module_ops ldb_skel_module_ops = {
.name = "skel",
.init_context = skel_init,
.search = skel_search,
@@ -136,3 +139,9 @@ const struct ldb_module_ops ldb_skel_module_ops = {
.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
index b4ea017b32..c6fce2d96e 100644
--- a/source4/lib/ldb/modules/sort.c
+++ b/source4/lib/ldb/modules/sort.c
@@ -31,6 +31,9 @@
* Author: Simo Sorce
*/
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
struct opaque {
@@ -44,15 +47,15 @@ struct opaque {
struct sort_context {
struct ldb_module *module;
- char *attributeName;
- char *orderingRule;
+ const char *attributeName;
+ const char *orderingRule;
int reverse;
struct ldb_request *req;
struct ldb_message **msgs;
char **referrals;
- int num_msgs;
- int num_refs;
+ unsigned int num_msgs;
+ unsigned int num_refs;
const struct ldb_schema_attribute *a;
int sort_result;
@@ -62,7 +65,7 @@ static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result
{
struct ldb_control **controls;
struct ldb_sort_resp_control *resp;
- int i;
+ unsigned int i;
if (*ctrls) {
controls = *ctrls;
@@ -137,16 +140,15 @@ static int server_sort_results(struct sort_context *ac)
{
struct ldb_context *ldb;
struct ldb_reply *ares;
- int i, ret;
+ 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_qsort(ac->msgs, ac->num_msgs,
- sizeof(struct ldb_message *),
- ac, (ldb_qsort_cmp_fn_t)sort_compare);
+ LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare);
if (ac->sort_result != LDB_SUCCESS) {
return ac->sort_result;
@@ -315,13 +317,13 @@ static int server_sort_search(struct ldb_module *module, struct ldb_request *req
server_sort_search_callback,
req);
if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
+ 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 (!save_controls(control, down_req, &saved_controls)) {
+ if (!ldb_save_controls(control, down_req, &saved_controls)) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -345,8 +347,14 @@ static int server_sort_init(struct ldb_module *module)
return ldb_next_init(module);
}
-const struct ldb_module_ops ldb_server_sort_module_ops = {
+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/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c
index 8f7321031b..92b0635561 100644
--- a/source4/lib/ldb/nssldb/ldb-nss.c
+++ b/source4/lib/ldb/nssldb/ldb-nss.c
@@ -191,7 +191,7 @@ NSS_STATUS _ldb_nss_fill_group(struct group *result,
size_t len;
size_t bufpos;
size_t lsize;
- int i;
+ unsigned int i;
bufpos = 0;
@@ -280,7 +280,7 @@ NSS_STATUS _ldb_nss_fill_initgr(gid_t group,
struct ldb_result *grlist)
{
NSS_STATUS ret;
- int i;
+ unsigned int i;
for (i = 0; i < grlist->count; i++) {
diff --git a/source4/lib/ldb/pyldb-util.pc.in b/source4/lib/ldb/pyldb-util.pc.in
new file mode 100644
index 0000000000..348ae8b95d
--- /dev/null
+++ b/source4/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/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 1ba5109f2f..d14487ba02 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -5,12 +5,12 @@
Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
Copyright (C) 2006 Simo Sorce <idra@samba.org>
- Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
- Copyright (C) 2009 Matthias Dieter Wallnöfer
+ Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
+ Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
+ ** 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
@@ -26,11 +26,31 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "replace.h"
-#include "ldb_private.h"
#include <Python.h>
+#include <pytalloc.h>
+#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,
+ 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;
@@ -42,68 +62,164 @@ typedef intargfunc ssizeargfunc;
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
#endif
-static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+#define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
+
+
+
+static PyObject *py_ldb_control_str(PyLdbControlObject *self)
{
- if (ret == LDB_ERR_PYTHON_EXCEPTION)
- return; /* Python exception should already be set, just keep that */
+ 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");
+ }
+}
- PyErr_SetObject(error,
- Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
- ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+static void py_ldb_control_dealloc(PyLdbControlObject *self)
+{
+ if (self->mem_ctx != NULL) {
+ talloc_free(self->mem_ctx);
+ }
+ self->ob_type->tp_free(self);
}
-static PyObject *PyExc_LdbError;
+static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
+{
+ return PyString_FromString(self->data->oid);
+}
-PyAPI_DATA(PyTypeObject) PyLdbMessage;
-PyAPI_DATA(PyTypeObject) PyLdbModule;
-PyAPI_DATA(PyTypeObject) PyLdbDn;
-PyAPI_DATA(PyTypeObject) PyLdb;
-PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
-PyAPI_DATA(PyTypeObject) PyLdbTree;
+static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
+{
+ return PyBool_FromLong(self->data->critical);
+}
-static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
- struct ldb_message_element *el,
- struct ldb_val *val)
+static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
{
- struct ldb_val new_val;
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- PyObject *ret;
+ if (PyObject_IsTrue(value)) {
+ self->data->critical = true;
+ } else {
+ self->data->critical = false;
+ }
+ return 0;
+}
- new_val = *val;
+static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ char *data = NULL;
+ const char *array[2];
+ 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;
- ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
+ discard_const_p(char *, kwnames),
+ &py_ldb, &data))
+ return NULL;
- talloc_free(mem_ctx);
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
- return ret;
+ 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_steal(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);
}
/**
- * Obtain a ldb DN from a Python object.
+ * Create a Python object from a ldb_result.
*
- * @param mem_ctx Memory context
- * @param object Python object
- * @param ldb_ctx LDB context
- * @return Whether or not the conversion succeeded
+ * @param result LDB result to convert
+ * @return Python object with converted result (a list object)
*/
-bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
- struct ldb_context *ldb_ctx, struct ldb_dn **dn)
+static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
{
- struct ldb_dn *odn;
-
- if (ldb_ctx != NULL && PyString_Check(object)) {
- odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
- *dn = odn;
- return true;
+ TALLOC_CTX *ctl_ctx = talloc_new(NULL);
+ PyLdbControlObject *ctrl;
+ if (ctl_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
}
- if (PyLdbDn_Check(object)) {
- *dn = PyLdbDn_AsDn(object);
- return true;
+ ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
+ if (ctrl == NULL) {
+ PyErr_NoMemory();
+ return NULL;
}
-
- PyErr_SetString(PyExc_TypeError, "Expected DN");
- return false;
+ 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;
}
/**
@@ -114,17 +230,90 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
*/
static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
{
- PyObject *ret;
- int i;
+ PyLdbResultObject *ret;
+ PyObject *list, *controls, *referals;
+ Py_ssize_t i;
+
if (result == NULL) {
Py_RETURN_NONE;
- }
- ret = PyList_New(result->count);
+ }
+
+ 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(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
- );
+ PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
}
- return ret;
+
+ 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;
}
/**
@@ -136,10 +325,10 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
* @return a ldb_result, or NULL if the conversion failed
*/
static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
- PyObject *obj)
+ PyObject *obj)
{
struct ldb_result *res;
- int i;
+ Py_ssize_t i;
if (obj == Py_None)
return NULL;
@@ -295,8 +484,6 @@ static PyMethodDef py_ldb_dn_methods[] = {
{ "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)." },
- { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
- NULL },
{ "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
"S.parent() -> dn\n"
"Get the parent for this DN." },
@@ -307,7 +494,8 @@ static PyMethodDef py_ldb_dn_methods[] = {
"S.add_base(dn) -> None\n"
"Add a base DN to this DN." },
{ "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
- NULL },
+ "S.check_special(name) -> bool\n\n"
+ "Check if name is a special DN name"},
{ NULL }
};
@@ -365,8 +553,7 @@ static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwa
}
ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
-
- if (ret == NULL || !ldb_dn_validate(ret)) {
+ if (!ldb_dn_validate(ret)) {
talloc_free(mem_ctx);
PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
return NULL;
@@ -383,32 +570,14 @@ static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwa
return (PyObject *)py_ret;
}
-PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
-{
- PyLdbDnObject *py_ret;
-
- if (dn == NULL) {
- Py_RETURN_NONE;
- }
-
- 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 = talloc_reference(py_ret->mem_ctx, dn);
- return (PyObject *)py_ret;
-}
-
static void py_ldb_dn_dealloc(PyLdbDnObject *self)
{
talloc_free(self->mem_ctx);
- self->ob_type->tp_free(self);
+ PyObject_Del(self);
}
-PyTypeObject PyLdbDn = {
- .tp_name = "Dn",
+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,
@@ -417,7 +586,7 @@ PyTypeObject PyLdbDn = {
.tp_doc = "A LDB distinguished name.",
.tp_new = py_ldb_dn_new,
.tp_dealloc = (destructor)py_ldb_dn_dealloc,
- .tp_basicsize = sizeof(PyLdbObject),
+ .tp_basicsize = sizeof(PyLdbDnObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
};
@@ -477,6 +646,12 @@ static PyObject *py_ldb_transaction_commit(PyLdbObject *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));
@@ -528,15 +703,20 @@ static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
}
static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
- const char *paramname)
+ const char *paramname)
{
const char **ret;
- int i;
+ 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)) {
@@ -544,7 +724,7 @@ static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
return NULL;
}
ret[i] = talloc_strndup(ret, PyString_AsString(item),
- PyString_Size(item));
+ PyString_Size(item));
}
ret[i] = NULL;
return ret;
@@ -641,105 +821,196 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa
static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
{
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;
- if (!PyArg_ParseTuple(args, "O", &py_msg))
+ TALLOC_CTX *mem_ctx;
+
+ if (!PyArg_ParseTuple(args, "O|O", &py_msg, &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_msg)) {
PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
+ talloc_free(mem_ctx);
return NULL;
}
+ msg = PyLdbMessage_AsMessage(py_msg);
- ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
- PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
+ 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 *py_msg;
+ PyObject *py_obj;
int ret;
- Py_ssize_t dict_pos, msg_pos;
- struct ldb_message_element *msgel;
- struct ldb_message *msg;
struct ldb_context *ldb_ctx;
struct ldb_request *req;
- PyObject *key, *value;
+ struct ldb_message *msg = NULL;
PyObject *py_controls = Py_None;
TALLOC_CTX *mem_ctx;
struct ldb_control **parsed_controls;
- if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls ))
+ if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls ))
return NULL;
- ldb_ctx = PyLdb_AsLdbContext(self);
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(ldb_ctx, py_controls, "controls");
- parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
+ 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 (PyDict_Check(py_msg)) {
- PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
- msg = ldb_msg_new(mem_ctx);
- msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
- msg_pos = dict_pos = 0;
- if (dn_value) {
- if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
- PyErr_SetString(PyExc_TypeError, "unable to import dn object");
- talloc_free(mem_ctx);
- return NULL;
- }
- if (msg->dn == NULL) {
- PyErr_SetString(PyExc_TypeError, "dn set but not found");
- talloc_free(mem_ctx);
- return NULL;
- }
- }
-
- while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
- char *key_str = PyString_AsString(key);
- if (strcmp(key_str, "dn") != 0) {
- msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
- if (msgel == NULL) {
- PyErr_SetString(PyExc_TypeError, "unable to import element");
- talloc_free(mem_ctx);
- return NULL;
- }
- memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
- msg_pos++;
- }
- }
- if (msg->dn == NULL) {
- PyErr_SetString(PyExc_TypeError, "no dn set");
- talloc_free(mem_ctx);
- return NULL;
- }
-
- msg->num_elements = msg_pos;
+ 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 {
- msg = PyLdbMessage_AsMessage(py_msg);
+ PyErr_SetString(PyExc_TypeError,
+ "Dictionary or LdbMessage object expected!");
}
-
- ret = ldb_msg_sanity_check(ldb_ctx, msg);
- if (ret != LDB_SUCCESS) {
- PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
+
+ if (!msg) {
+ /* we should have a PyErr already set */
talloc_free(mem_ctx);
return NULL;
- }
+ }
- ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx,
- msg,
- parsed_controls,
- NULL,
- ldb_op_default_callback,
- 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;
+ }
- if (ret != LDB_SUCCESS) {
+ 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;
@@ -748,30 +1019,29 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
/* 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(req);
+ ret = ldb_transaction_start(ldb_ctx);
+ if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);
- PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
- }
+ 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);
- }
+ 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);
+ 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(req);
+
talloc_free(mem_ctx);
- PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
+ PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
Py_RETURN_NONE;
}
@@ -781,17 +1051,69 @@ static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
PyObject *py_dn;
struct ldb_dn *dn;
int ret;
- struct ldb_context *ldb;
- if (!PyArg_ParseTuple(args, "O", &py_dn))
+ struct ldb_context *ldb_ctx;
+ struct ldb_request *req;
+ PyObject *py_controls = Py_None;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_control **parsed_controls;
+
+ if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
return NULL;
- ldb = PyLdb_AsLdbContext(self);
+ 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(NULL, py_dn, ldb, &dn))
+ if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
+ talloc_free(mem_ctx);
return NULL;
+ }
- ret = ldb_delete(ldb, dn);
- PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
+ 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;
}
@@ -803,15 +1125,33 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
int ret;
struct ldb_context *ldb;
TALLOC_CTX *mem_ctx;
- if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
+ PyObject *py_controls = Py_None;
+ struct ldb_control **parsed_controls;
+ struct ldb_context *ldb_ctx;
+ struct ldb_request *req;
+
+ ldb_ctx = PyLdb_AsLdbContext(self);
+
+ if (!PyArg_ParseTuple(args, "OO|O", &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;
@@ -822,9 +1162,40 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
return NULL;
}
- ret = ldb_rename(ldb, dn1, dn2);
+ 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);
+ PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
Py_RETURN_NONE;
}
@@ -868,7 +1239,7 @@ static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
}
-static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args)
+static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
{
int changetype;
PyObject *py_msg;
@@ -937,9 +1308,11 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
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))
@@ -955,12 +1328,20 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
return NULL;
}
- diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new));
- if (diff == 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;
}
@@ -1003,7 +1384,7 @@ static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *py_base = Py_None;
- enum ldb_scope scope = LDB_SCOPE_DEFAULT;
+ int scope = LDB_SCOPE_DEFAULT;
char *expr = NULL;
PyObject *py_attrs = Py_None;
PyObject *py_controls = Py_None;
@@ -1016,20 +1397,30 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
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(NULL, py_attrs, "attrs");
- if (attrs == NULL)
+ attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
+ if (attrs == NULL) {
+ talloc_free(mem_ctx);
return NULL;
+ }
}
if (py_base == Py_None) {
@@ -1044,19 +1435,19 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
if (py_controls == Py_None) {
parsed_controls = NULL;
} else {
- const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
- parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
+ 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(ldb_ctx, struct ldb_result);
+ res = talloc_zero(mem_ctx, struct ldb_result);
if (res == NULL) {
PyErr_NoMemory();
- talloc_free(attrs);
+ talloc_free(mem_ctx);
return NULL;
}
- ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
+ ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
base,
scope,
expr,
@@ -1066,31 +1457,29 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
ldb_search_default_callback,
NULL);
- talloc_steal(req, attrs);
-
if (ret != LDB_SUCCESS) {
- talloc_free(res);
+ 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);
}
- talloc_free(req);
-
if (ret != LDB_SUCCESS) {
- talloc_free(res);
+ talloc_free(mem_ctx);
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
return NULL;
}
py_ret = PyLdbResult_FromResult(res);
- talloc_free(res);
+ talloc_free(mem_ctx);
return py_ret;
}
@@ -1141,6 +1530,25 @@ static PyObject *py_ldb_modules(PyLdbObject *self)
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"
@@ -1155,6 +1563,9 @@ static PyMethodDef py_ldb_methods[] = {
{ "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." },
@@ -1224,10 +1635,13 @@ static PyMethodDef py_ldb_methods[] = {
{ "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 },
};
-PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
+static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
{
PyLdbModuleObject *ret;
@@ -1256,13 +1670,15 @@ 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;
- int count;
- if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
+ 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);
+ 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;
@@ -1272,6 +1688,14 @@ static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
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;
}
@@ -1279,7 +1703,7 @@ static PySequenceMethods py_ldb_seq = {
.sq_contains = (objobjproc)py_ldb_contains,
};
-PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
+static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
{
PyLdbObject *ret;
@@ -1299,8 +1723,8 @@ static void py_ldb_dealloc(PyLdbObject *self)
self->ob_type->tp_free(self);
}
-PyTypeObject PyLdb = {
- .tp_name = "Ldb",
+static PyTypeObject PyLdb = {
+ .tp_name = "ldb.Ldb",
.tp_methods = py_ldb_methods,
.tp_repr = (reprfunc)py_ldb_repr,
.tp_new = py_ldb_new,
@@ -1314,6 +1738,91 @@ PyTypeObject PyLdb = {
.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("<ldb result>");
+}
+
+
+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("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
@@ -1351,6 +1860,7 @@ static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, P
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))
@@ -1489,11 +1999,11 @@ static PyMethodDef py_ldb_module_methods[] = {
static void py_ldb_module_dealloc(PyLdbModuleObject *self)
{
talloc_free(self->mem_ctx);
- self->ob_type->tp_free(self);
+ PyObject_Del(self);
}
-PyTypeObject PyLdbModule = {
- .tp_name = "LdbModule",
+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,
@@ -1517,17 +2027,29 @@ PyTypeObject PyLdbModule = {
* @param attr_name Name of the attribute
* @return New ldb_message_element, allocated as child of mem_ctx
*/
-struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
- PyObject *set_obj, int flags,
- const char *attr_name)
+static struct ldb_message_element *PyObject_AsMessageElement(
+ TALLOC_CTX *mem_ctx,
+ PyObject *set_obj,
+ int flags,
+ const char *attr_name)
{
struct ldb_message_element *me;
- if (PyLdbMessageElement_Check(set_obj))
- return talloc_reference(mem_ctx,
- PyLdbMessageElement_AsMessageElement(set_obj));
+ 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;
@@ -1536,17 +2058,23 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
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);
+ (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
} else if (PySequence_Check(set_obj)) {
- int i;
+ 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);
+ (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
}
} else {
talloc_free(me);
@@ -1557,10 +2085,10 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
}
-static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
- struct ldb_message_element *me)
+static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
+ struct ldb_message_element *me)
{
- int i;
+ Py_ssize_t i;
PyObject *result;
/* Python << 2.5 doesn't have PySet_New and PySet_Add. */
@@ -1568,7 +2096,7 @@ static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
for (i = 0; i < me->num_values; i++) {
PyList_SetItem(result, i,
- PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
+ PyObject_FromLdbValue(&me->values[i]));
}
return result;
@@ -1576,21 +2104,18 @@ static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
{
- int i;
- if (!PyArg_ParseTuple(args, "i", &i))
+ unsigned int i;
+ if (!PyArg_ParseTuple(args, "I", &i))
return NULL;
- if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
+ if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
Py_RETURN_NONE;
- return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
- &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
+ return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i]));
}
static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
{
- struct ldb_message_element *el;
-
- el = PyLdbMessageElement_AsMessageElement(self);
+ struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
return PyInt_FromLong(el->flags);
}
@@ -1635,8 +2160,9 @@ static PySequenceMethods py_ldb_msg_element_seq = {
static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
{
- return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
- PyLdbMessageElement_AsMessageElement(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)
@@ -1644,10 +2170,10 @@ static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
}
-PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
+static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
{
PyLdbMessageElementObject *ret;
- ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
+ ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
if (ret == NULL) {
PyErr_NoMemory();
return NULL;
@@ -1683,30 +2209,48 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb
}
el = talloc_zero(mem_ctx, struct ldb_message_element);
+ if (el == NULL) {
+ PyErr_NoMemory();
+ talloc_free(mem_ctx);
+ return NULL;
+ }
if (py_elements != NULL) {
- int i;
+ 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,
- (uint8_t *)PyString_AsString(py_elements), el->values[0].length);
+ 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 %d in list",
- i);
+ "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);
+ el->values[i].data = talloc_memdup(el,
+ (uint8_t *)PyString_AsString(item), el->values[i].length+1);
}
} else {
PyErr_SetString(PyExc_TypeError,
@@ -1719,9 +2263,8 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb
el->flags = flags;
el->name = talloc_strdup(el, name);
- ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
+ ret = PyObject_New(PyLdbMessageElementObject, type);
if (ret == NULL) {
- PyErr_NoMemory();
talloc_free(mem_ctx);
return NULL;
}
@@ -1734,7 +2277,7 @@ static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyOb
static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
{
char *element_str = NULL;
- int i;
+ Py_ssize_t i;
struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
PyObject *ret;
@@ -1746,9 +2289,12 @@ static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
}
- ret = PyString_FromFormat("MessageElement([%s])", element_str);
-
- talloc_free(element_str);
+ if (element_str != NULL) {
+ ret = PyString_FromFormat("MessageElement([%s])", element_str);
+ talloc_free(element_str);
+ } else {
+ ret = PyString_FromString("MessageElement([])");
+ }
return ret;
}
@@ -1759,18 +2305,18 @@ static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
if (el->num_values == 1)
return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
- else
+ else
Py_RETURN_NONE;
}
static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
{
talloc_free(self->mem_ctx);
- self->ob_type->tp_free(self);
+ PyObject_Del(self);
}
-PyTypeObject PyLdbMessageElement = {
- .tp_name = "MessageElement",
+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,
@@ -1783,6 +2329,45 @@ PyTypeObject PyLdbMessageElement = {
.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;
@@ -1797,7 +2382,7 @@ static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args
static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
{
struct ldb_message *msg = PyLdbMessage_AsMessage(self);
- int i, j = 0;
+ 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"));
@@ -1826,7 +2411,7 @@ static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *p
if (el == NULL) {
return NULL;
}
- return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
+ return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
}
static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
@@ -1857,24 +2442,70 @@ static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
{
struct ldb_message *msg = PyLdbMessage_AsMessage(self);
- int i, j;
+ Py_ssize_t i, j = 0;
PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
- j = 0;
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++) {
- PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
+ 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 PyMethodDef py_ldb_msg_methods[] = {
- { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
- { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
+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 },
};
@@ -1896,14 +2527,14 @@ static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject
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);
+ value, 0, attr_name);
if (el == NULL)
return -1;
ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
@@ -1970,7 +2601,7 @@ static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kw
return (PyObject *)py_ret;
}
-PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
+static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
{
PyLdbMessageObject *ret;
@@ -2020,11 +2651,48 @@ static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
{
talloc_free(self->mem_ctx);
- self->ob_type->tp_free(self);
+ 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;
}
-PyTypeObject PyLdbMessage = {
- .tp_name = "Message",
+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,
@@ -2034,9 +2702,10 @@ PyTypeObject PyLdbMessage = {
.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,
};
-PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
+static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
{
PyLdbTreeObject *ret;
@@ -2054,11 +2723,11 @@ PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
{
talloc_free(self->mem_ctx);
- self->ob_type->tp_free(self);
+ PyObject_Del(self);
}
-PyTypeObject PyLdbTree = {
- .tp_name = "Tree",
+static PyTypeObject PyLdbTree = {
+ .tp_name = "ldb.Tree",
.tp_basicsize = sizeof(PyLdbTreeObject),
.tp_dealloc = (destructor)py_ldb_tree_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
@@ -2366,12 +3035,14 @@ static PyObject *py_register_module(PyObject *module, PyObject *args)
static PyObject *py_timestring(PyObject *module, PyObject *args)
{
- time_t t;
+ /* 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))
+ if (!PyArg_ParseTuple(args, "l", &t_val))
return NULL;
- tresult = ldb_timestring(NULL, t);
+ tresult = ldb_timestring(NULL, (time_t) t_val);
ret = PyString_FromString(tresult);
talloc_free(tresult);
return ret;
@@ -2434,11 +3105,20 @@ void initldb(void)
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));
@@ -2493,11 +3173,10 @@ void initldb(void)
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, "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"));
@@ -2510,6 +3189,8 @@ void initldb(void)
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);
@@ -2517,4 +3198,7 @@ void initldb(void)
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));
}
diff --git a/source4/lib/ldb/pyldb.h b/source4/lib/ldb/pyldb.h
index a0954158bd..04d8ff856c 100644
--- a/source4/lib/ldb/pyldb.h
+++ b/source4/lib/ldb/pyldb.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- Swig interface to ldb.
+ Python interface to ldb.
Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
@@ -26,23 +26,21 @@
#ifndef _PYLDB_H_
#define _PYLDB_H_
-#include <Python.h>
#include <talloc.h>
typedef struct {
PyObject_HEAD
- struct ldb_context *ldb_ctx;
TALLOC_CTX *mem_ctx;
+ struct ldb_context *ldb_ctx;
} PyLdbObject;
-PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
#define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx
#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
typedef struct {
PyObject_HEAD
- struct ldb_dn *dn;
TALLOC_CTX *mem_ctx;
+ struct ldb_dn *dn;
} PyLdbDnObject;
PyObject *PyLdbDn_FromDn(struct ldb_dn *);
@@ -52,39 +50,48 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ld
typedef struct {
PyObject_HEAD
- struct ldb_message *msg;
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
- struct ldb_module *mod;
TALLOC_CTX *mem_ctx;
+ struct ldb_module *mod;
} PyLdbModuleObject;
-PyObject *PyLdbMessage_FromMessage(struct ldb_message *message);
-PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
#define PyLdbModule_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod
typedef struct {
- PyObject_HEAD
- struct ldb_message_element *el;
+ PyObject_HEAD
TALLOC_CTX *mem_ctx;
+ struct ldb_message_element *el;
} PyLdbMessageElementObject;
-struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *obj, int flags, const char *name);
-PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *, TALLOC_CTX *mem_ctx);
#define PyLdbMessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el
#define PyLdbMessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
typedef struct {
PyObject_HEAD
- struct ldb_parse_tree *tree;
TALLOC_CTX *mem_ctx;
+ struct ldb_parse_tree *tree;
} PyLdbTreeObject;
-PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
#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); \
diff --git a/source4/lib/ldb/pyldb_util.c b/source4/lib/ldb/pyldb_util.c
new file mode 100644
index 0000000000..79077416be
--- /dev/null
+++ b/source4/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 <jelmer@samba.org>
+
+ ** 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <Python.h>
+#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/python.mk b/source4/lib/ldb/python.mk
deleted file mode 100644
index dbc2eb27eb..0000000000
--- a/source4/lib/ldb/python.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-[PYTHON::pyldb]
-LIBRARY_REALNAME = ldb.$(SHLIBEXT)
-PUBLIC_DEPENDENCIES = LIBLDB PYTALLOC
-
-pyldb_OBJ_FILES = $(ldbsrcdir)/pyldb.o
-$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
diff --git a/source4/lib/ldb/rules.mk b/source4/lib/ldb/rules.mk
deleted file mode 100644
index 0598f8039b..0000000000
--- a/source4/lib/ldb/rules.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-etags:
- etags `find $(srcdir) -name "*.[ch]"`
-
-ctags:
- ctags `find $(srcdir) -name "*.[ch]"`
-
-.SUFFIXES: .1 .1.xml .3 .3.xml .xml .html .c .o
-
-.c.o:
- @echo Compiling $*.c
- @mkdir -p `dirname $@`
- @$(CC) $(CFLAGS) $(PICFLAG) -c $< -o $@
-
-.c.po:
- @echo Compiling $*.c
- @mkdir -p `dirname $@`
- @$(CC) -fPIC $(CFLAGS) -c $< -o $@
-
-showflags::
- @echo 'ldb will be compiled with flags:'
- @echo ' CFLAGS = $(CFLAGS)'
- @echo ' SHLD_FLAGS = $(SHLD_FLAGS)'
- @echo ' LIBS = $(LIBS)'
-
-distclean::
- rm -f *~ */*~
diff --git a/source4/lib/ldb/sqlite3.m4 b/source4/lib/ldb/sqlite3.m4
deleted file mode 100644
index d0a74ee53c..0000000000
--- a/source4/lib/ldb/sqlite3.m4
+++ /dev/null
@@ -1,62 +0,0 @@
-########################################################
-# Compile with SQLITE3 support?
-
-SQLITE3_LIBS=""
-with_sqlite3_support=no
-AC_MSG_CHECKING([for SQLITE3 support])
-
-AC_ARG_WITH(sqlite3,
-AS_HELP_STRING([--with-sqlite3],[SQLITE3 backend support (default=no)]),
-[ case "$withval" in
- yes|no|auto)
- with_sqlite3_support=$withval
- ;;
- esac ])
-
-AC_MSG_RESULT($with_sqlite3_support)
-
-if test x"$with_sqlite3_support" != x"no"; then
- ##################################################################
- # first test for sqlite3.h
- AC_CHECK_HEADERS(sqlite3.h)
-
- if test x"$ac_cv_header_sqlite3_h" != x"yes"; then
- if test x"$with_sqlite3_support" = x"yes"; then
- AC_MSG_ERROR(sqlite3.h is needed for SQLITE3 support)
- else
- AC_MSG_WARN(sqlite3.h is needed for SQLITE3 support)
- fi
-
- with_sqlite3_support=no
- fi
-fi
-
-if test x"$with_sqlite3_support" != x"no"; then
- ac_save_LIBS=$LIBS
-
- ########################################################
- # now see if we can find the sqlite3 libs in standard paths
- AC_CHECK_LIB_EXT(sqlite3, SQLITE3_LIBS, sqlite3_open)
-
- if test x"$ac_cv_lib_ext_sqlite3_sqlite3_open" = x"yes"; then
- AC_DEFINE(HAVE_SQLITE3,1,[Whether sqlite3 is available])
- AC_DEFINE(HAVE_LDB_SQLITE3,1,[Whether ldb_sqlite3 is available])
- AC_MSG_CHECKING(whether SQLITE3 support is used)
- AC_MSG_RESULT(yes)
- with_sqlite3_support=yes
- SMB_ENABLE(SQLITE3,YES)
- else
- if test x"$with_sqlite3_support" = x"yes"; then
- AC_MSG_ERROR(libsqlite3 is needed for SQLITE3 support)
- else
- AC_MSG_WARN(libsqlite3 is needed for SQLITE3 support)
- fi
-
- SQLITE3_LIBS=""
- with_sqlite3_support=no
- fi
-
- LIBS=$ac_save_LIBS;
-fi
-
-SMB_EXT_LIB(SQLITE3,[${SQLITE3_LIBS}],[${SQLITE3_CFLAGS}],[${SQLITE3_CPPFLAGS}],[${SQLITE3_LDFLAGS}])
diff --git a/source4/lib/ldb/standalone.sh b/source4/lib/ldb/standalone.sh
deleted file mode 100755
index 8ab081e0f3..0000000000
--- a/source4/lib/ldb/standalone.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-cd ../replace
-make clean
-
-cd ../talloc
-make clean
-
-cd ../tdb
-make clean
-
-cd ../events
-make clean
-
-cd ../ldb
-make clean
-
-./autogen.sh
-
-rm -fr build
-mkdir build
-cd build
-
-../configure $*
-make dirs
-make all
-
-cd ..
diff --git a/source4/lib/ldb/tests/photo.ldif b/source4/lib/ldb/tests/photo.ldif
index 28981b1f24..95ab065672 100644
--- a/source4/lib/ldb/tests/photo.ldif
+++ b/source4/lib/ldb/tests/photo.ldif
@@ -1,5 +1,5 @@
dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST
changetype: modify
add: jpegPhoto
-jpegPhoto:< file://tests/tmp/samba4.png
+jpegPhoto:< file://tests/samba4.png
diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py
index 956908d7d6..a9f68cbd71 100755
--- a/source4/lib/ldb/tests/python/api.py
+++ b/source4/lib/ldb/tests/python/api.py
@@ -1,17 +1,20 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# Simple tests for the ldb python bindings.
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
-import os, sys
+import os
import unittest
-# Required for the standalone LDB build
-sys.path.append("build/lib.linux-i686-2.4")
-
import ldb
+
def filename():
- return os.tempnam()
+ 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):
@@ -57,7 +60,7 @@ class SimpleLdb(unittest.TestCase):
self.assertEquals([], x.modules())
def test_modules_tdb(self):
- x = ldb.Ldb("bar.ldb")
+ x = ldb.Ldb(filename())
self.assertEquals("[<ldb module 'tdb'>]", repr(x.modules()))
def test_search(self):
@@ -77,7 +80,7 @@ class SimpleLdb(unittest.TestCase):
self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
def test_search_attr_string(self):
- l = ldb.Ldb("foo.tdb")
+ l = ldb.Ldb(filename())
self.assertRaises(TypeError, l.search, attrs="dc")
def test_opaque(self):
@@ -95,10 +98,20 @@ class SimpleLdb(unittest.TestCase):
l = ldb.Ldb(filename())
self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2")))
- def test_contains(self):
+ 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(filename())
+ l = ldb.Ldb(name)
m = ldb.Message()
m.dn = ldb.Dn(l, "dc=foo3")
m["b"] = ["a"]
@@ -208,7 +221,7 @@ class SimpleLdb(unittest.TestCase):
l.modify(m)
rm = l.search(m.dn)[0]
self.assertEquals(1, len(rm))
- rm = l.search(m.dn, attrs=["bla"])[0]
+ rm = l.search(m.dn, attrs=["bla"])
self.assertEquals(0, len(rm))
finally:
l.delete(ldb.Dn(l, "dc=modifydelete"))
@@ -266,15 +279,14 @@ class SimpleLdb(unittest.TestCase):
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
+
+ # 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"))
@@ -315,6 +327,10 @@ class SimpleLdb(unittest.TestCase):
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):
@@ -331,6 +347,8 @@ class DnTests(unittest.TestCase):
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")
@@ -356,20 +374,11 @@ class DnTests(unittest.TestCase):
x = ldb.Dn(self.ldb, "@BLA")
self.assertEquals(None, x.parent())
- def test_compare(self):
- x = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
- y = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
- self.assertEquals(x, y)
- z = ldb.Dn(self.ldb, "dc=foo17,bar=blie")
- self.assertNotEquals(z, y)
-
def test_is_valid(self):
x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe")
self.assertTrue(x.is_valid())
x = ldb.Dn(self.ldb, "")
- # is_valid()'s return values appears to be a side effect of
- # some other ldb functions. yuck.
- # self.assertFalse(x.is_valid())
+ self.assertTrue(x.is_valid())
def test_is_special(self):
x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe")
@@ -412,7 +421,7 @@ class DnTests(unittest.TestCase):
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()
@@ -440,11 +449,11 @@ class LdbMsgTests(unittest.TestCase):
def test_iter_items(self):
self.assertEquals(0, len(self.msg.items()))
- self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo28")
+ 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("foo.tdb"), "dc=foo29")
+ 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))
@@ -457,6 +466,17 @@ class LdbMsgTests(unittest.TestCase):
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"]
@@ -475,7 +495,7 @@ class LdbMsgTests(unittest.TestCase):
self.assertEquals(["bar"], list(self.msg["foo"]))
def test_keys(self):
- self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
+ 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())
@@ -485,11 +505,11 @@ class LdbMsgTests(unittest.TestCase):
self.assertEquals("@BASEINFO", self.msg.dn.__str__())
def test_get_dn(self):
- self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
+ 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("foo.tdb"), "@BASEINFO")
+ self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO")
self.assertRaises(TypeError, self.msg.get, 42)
def test_get_other(self):
@@ -509,6 +529,42 @@ class LdbMsgTests(unittest.TestCase):
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):
@@ -551,6 +607,10 @@ class MessageElementTests(unittest.TestCase):
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):
@@ -571,15 +631,112 @@ class ModuleTests(unittest.TestCase):
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("usemodule.ldb"):
- os.unlink("usemodule.ldb")
- l = ldb.Ldb("usemodule.ldb")
+ if os.path.exists(name):
+ os.unlink(name)
+ l = ldb.Ldb(name)
l.add({"dn": "@MODULES", "@LIST": "bla"})
self.assertEquals([], ops)
- l = ldb.Ldb("usemodule.ldb")
+ 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), "<ldb result>")
+
+ 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
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
deleted file mode 100755
index 5b2d380f11..0000000000
--- a/source4/lib/ldb/tests/python/ldap.py
+++ /dev/null
@@ -1,1540 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# This is a port of the original in testprogs/ejs/ldap.js
-
-import getopt
-import optparse
-import sys
-import time
-import random
-import base64
-
-sys.path.append("bin/python")
-sys.path.append("../lib/subunit/python")
-
-import samba.getopt as options
-
-from samba.auth import system_session
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
-from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
-from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
-from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
-from ldb import Message, MessageElement, Dn, FLAG_MOD_REPLACE
-from samba import Ldb, param, dom_sid_to_rid
-from subunit import SubunitTestRunner
-import unittest
-
-from samba.ndr import ndr_pack, ndr_unpack
-from samba.dcerpc import security
-
-parser = optparse.OptionParser("ldap [options] <host>")
-sambaopts = options.SambaOptions(parser)
-parser.add_option_group(sambaopts)
-parser.add_option_group(options.VersionOptions(parser))
-# use command line creds if available
-credopts = options.CredentialsOptions(parser)
-parser.add_option_group(credopts)
-opts, args = parser.parse_args()
-
-if len(args) < 1:
- parser.print_usage()
- sys.exit(1)
-
-host = args[0]
-
-lp = sambaopts.get_loadparm()
-creds = credopts.get_credentials(lp)
-
-class BasicTests(unittest.TestCase):
- def delete_force(self, ldb, dn):
- try:
- ldb.delete(dn)
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- def find_basedn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE,
- attrs=["defaultNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["defaultNamingContext"][0]
-
- def find_configurationdn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["configurationNamingContext"][0]
-
- def find_schemadn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["schemaNamingContext"][0]
-
- def find_domain_sid(self):
- res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
- return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
-
- def setUp(self):
- self.ldb = ldb
- self.gc_ldb = gc_ldb
- self.base_dn = self.find_basedn(ldb)
- self.configuration_dn = self.find_configurationdn(ldb)
- self.schema_dn = self.find_schemadn(ldb)
- self.domain_sid = self.find_domain_sid()
-
- print "baseDN: %s\n" % self.base_dn
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà ,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
- self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
-
- def test_group_add_invalid_member(self):
- """Testing group add with invalid member"""
- try:
- self.ldb.add({
- "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
- "objectclass": "group",
- "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- def test_parentGUID(self):
- """Test parentGUID behaviour"""
- print "Testing parentGUID behaviour\n"
-
- self.ldb.add({
- "dn": "cn=parentguidtest,cn=users," + self.base_dn,
- "objectclass":"user",
- "samaccountname":"parentguidtest"});
- res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
- attrs=["parentGUID"]);
- res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
- attrs=["objectGUID"]);
- self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
-
- """Test parentGUID behaviour"""
- print "Testing parentGUID behaviour on rename\n"
-
- self.ldb.add({
- "dn": "cn=testotherusers," + self.base_dn,
- "objectclass":"container"});
- res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
- attrs=["objectGUID"]);
- ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
- "cn=parentguidtest,cn=testotherusers," + self.base_dn);
- res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
- scope=SCOPE_BASE,
- attrs=["parentGUID"]);
- self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
- ldb.delete("cn=parentguidtest,cn=testotherusers," + self.base_dn)
- ldb.delete("cn=testotherusers," + self.base_dn)
-
- def test_groupType(self):
- """Test groupType behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
- print "Testing groupType behaviour\n"
-
- res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
- attrs=["groupType"], expression="groupType=2147483653");
-
- res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
- attrs=["groupType"], expression="groupType=-2147483643");
-
- self.assertEquals(len(res1), len(res2))
-
- self.assertTrue(res1.count > 0)
-
- self.assertEquals(res1[0]["groupType"][0], "-2147483643")
-
- def test_primary_group(self):
- """This tests the primary group behaviour (setting, changing) of a user account"""
- print "Testing primary group behaviour\n"
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- ldb.add({
- "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["objectSID"])
- self.assertTrue(len(res1) == 1)
- group_rid_1 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
- res1[0]["objectSID"][0]))
-
- res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["objectSID"])
- self.assertTrue(len(res1) == 1)
- group_rid_2 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
- res1[0]["objectSID"][0]))
-
- # Try to add invalid primary group
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
- "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- # Try to make group 1 primary - should be denied since it is not yet
- # secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_1),
- FLAG_MOD_REPLACE, "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- # Make group 1 secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
- ldb.modify(m)
-
- # Make group 1 primary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_1),
- FLAG_MOD_REPLACE, "primaryGroupID")
- ldb.modify(m)
-
- # Try to delete group 1 - should be denied
- try:
- ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
-
- # Try to add group 1 also as secondary - should be denied
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
-
- # Make group 2 secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
- m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
- ldb.modify(m)
-
- # Swap the groups
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_2),
- FLAG_MOD_REPLACE, "primaryGroupID")
- ldb.modify(m)
-
- # Old primary group should contain a "member" attribute for the user,
- # the new shouldn't contain anymore one
- res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["member"])
- self.assertTrue(len(res1) == 1)
- self.assertTrue(len(res1[0]["member"]) == 1)
- self.assertEquals(res1[0]["member"][0].lower(),
- ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
-
- res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["member"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("member" in res1[0])
-
- # Also this should be denied
- try:
- ldb.add({
- "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "primaryGroupID": "0"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
-
- def test_primary_group_token(self):
- """Test the primary group token behaviour (hidden-generated-readonly attribute on groups)"""
- print "Testing primary group token behaviour\n"
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE)
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
- self.assertTrue(len(res1) == 1)
- primary_group_token = int(res1[0]["primaryGroupToken"][0])
-
- rid = dom_sid_to_rid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0]))
- self.assertEquals(primary_group_token, rid)
-
-# Has to wait until we support read-only generated attributes correctly
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["primaryGroupToken"] = "100"
-# try:
-# ldb.modify(m)
-# self.fail()
-# except LdbError, (num, msg):
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- def test_all(self):
- """Basic tests"""
-
- print "Testing user add"
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
- "objectclass": ["user", "person"],
- "cN": "LDAPtestUSER",
- "givenname": "ldap",
- "sn": "testy"})
-
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
- "objectclass": "group",
- "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
-
- self.delete_force(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": "computer",
- "cN": "LDAPtestCOMPUTER"})
-
- self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
- ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
- "objectClass": "computer",
- "cn": "LDAPtest2COMPUTER",
- "userAccountControl": "4096",
- "displayname": "ldap testy"})
-
- self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
- try:
- ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
- "objectClass": "computer",
- "cn": "LDAPtest2COMPUTER"
- })
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
-
- self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
- try:
- ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
- "objectClass": "computer",
- "cn": "ldaptestcomputer3",
- "sAMAccountType": "805306368"
- })
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
- try:
- ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
- "objectClass": "computer",
- "cn": "ldaptestcomputer3",
- "userAccountControl": "0"
- })
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
- try:
- ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
- "objectClass": "user",
- "cn": "LDAPtestuser7",
- "userAccountControl": "0"
- })
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
-
- ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
- "objectClass": "user",
- "cn": "LDAPtestuser7",
- "userAccountControl": "2"
- })
-
- self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
-
- self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
- ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
- "objectClass": "computer",
- "cn": "LDAPtestCOMPUTER3"
- })
-
- print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
- self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
- self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
- self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
- self.assertEquals(res[0]["objectClass"][0], "top");
- self.assertEquals(res[0]["objectClass"][1], "person");
- self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
- self.assertEquals(res[0]["objectClass"][3], "user");
- self.assertEquals(res[0]["objectClass"][4], "computer");
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
- self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
- self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368);
- self.assertEquals(int(res[0]["userAccountControl"][0]), 546);
-
- self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
-
- print "Testing attribute or value exists behaviour"
- try:
- ldb.modify_ldif("""
-dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
-changetype: modify
-replace: servicePrincipalName
-servicePrincipalName: host/ldaptest2computer
-servicePrincipalName: host/ldaptest2computer
-servicePrincipalName: cifs/ldaptest2computer
-""")
- self.fail()
- except LdbError, (num, msg):
- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
-
- ldb.modify_ldif("""
-dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
-changetype: modify
-replace: servicePrincipalName
-servicePrincipalName: host/ldaptest2computer
-servicePrincipalName: cifs/ldaptest2computer
-""")
- try:
- ldb.modify_ldif("""
-dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
-changetype: modify
-add: servicePrincipalName
-servicePrincipalName: host/ldaptest2computer
-""")
- self.fail()
- except LdbError, (num, msg):
- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
-
- print "Testing ranged results"
- ldb.modify_ldif("""
-dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
-changetype: modify
-replace: servicePrincipalName
-""")
-
- ldb.modify_ldif("""
-dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
-changetype: modify
-add: servicePrincipalName
-servicePrincipalName: host/ldaptest2computer0
-servicePrincipalName: host/ldaptest2computer1
-servicePrincipalName: host/ldaptest2computer2
-servicePrincipalName: host/ldaptest2computer3
-servicePrincipalName: host/ldaptest2computer4
-servicePrincipalName: host/ldaptest2computer5
-servicePrincipalName: host/ldaptest2computer6
-servicePrincipalName: host/ldaptest2computer7
-servicePrincipalName: host/ldaptest2computer8
-servicePrincipalName: host/ldaptest2computer9
-servicePrincipalName: host/ldaptest2computer10
-servicePrincipalName: host/ldaptest2computer11
-servicePrincipalName: host/ldaptest2computer12
-servicePrincipalName: host/ldaptest2computer13
-servicePrincipalName: host/ldaptest2computer14
-servicePrincipalName: host/ldaptest2computer15
-servicePrincipalName: host/ldaptest2computer16
-servicePrincipalName: host/ldaptest2computer17
-servicePrincipalName: host/ldaptest2computer18
-servicePrincipalName: host/ldaptest2computer19
-servicePrincipalName: host/ldaptest2computer20
-servicePrincipalName: host/ldaptest2computer21
-servicePrincipalName: host/ldaptest2computer22
-servicePrincipalName: host/ldaptest2computer23
-servicePrincipalName: host/ldaptest2computer24
-servicePrincipalName: host/ldaptest2computer25
-servicePrincipalName: host/ldaptest2computer26
-servicePrincipalName: host/ldaptest2computer27
-servicePrincipalName: host/ldaptest2computer28
-servicePrincipalName: host/ldaptest2computer29
-""")
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
- attrs=["servicePrincipalName;range=0-*"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- #print len(res[0]["servicePrincipalName;range=0-*"])
- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- # print res[0]["servicePrincipalName;range=0-19"].length
- self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
-
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
-
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
- # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
- # print res[0]["servicePrincipalName;range=11-*"][18]
- # print pos_11
- # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
- # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
-
- res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
- self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
- # print res[0]["servicePrincipalName"][18]
- # print pos_11
- self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
- # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
-
- self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
- ldb.add({
- "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
- "objectClass": ["person", "user"],
- "cn": "LDAPtestUSER2",
- "givenname": "testy",
- "sn": "ldap user2"})
-
- print "Testing Ambigious Name Resolution"
- # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
- res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
- self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
-
- # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
- res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
- self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
-
- # Testing ldb.search for (&(anr=ldap)(objectClass=user))
- res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
- self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
-
- # Testing ldb.search for (&(anr==ldap)(objectClass=user))
- res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["cn"][0], "ldaptestuser")
- self.assertEquals(str(res[0]["name"]), "ldaptestuser")
-
- # Testing ldb.search for (&(anr=testy)(objectClass=user))
- res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
- self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
-
- # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
- res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
- self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
-
- # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
-# this test disabled for the moment, as anr with == tests are not understood
-# res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
-# self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["cn"][0], "ldaptestuser")
- self.assertEquals(res[0]["name"][0], "ldaptestuser")
-
- # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
-# res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
-# self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["cn"][0], "ldaptestuser")
- self.assertEquals(res[0]["name"][0], "ldaptestuser")
-
- # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
- res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
- self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
-
- # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
-# res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
-# self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
- self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
-
- # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
-# res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
-# self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
- self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
-
- # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
-# res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
-# self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
-
- # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
- res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
- self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
-
- # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
-# res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
-# self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
-
- print "Testing Group Modifies"
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup,cn=users,""" + self.base_dn + """
-changetype: modify
-add: member
-member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
-member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
-""")
-
- self.delete_force(ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
-
- print "Testing adding non-existent user to a group"
- try:
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup,cn=users,""" + self.base_dn + """
-changetype: modify
-add: member
-member: cn=ldaptestuser3,cn=users,""" + self.base_dn + """
-""")
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- print "Testing Renames"
-
- attrs = ["objectGUID", "objectSid"]
- print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
- res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
-
- #Check rename works with extended/alternate DN forms
- ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestuser3,cn=users," + self.base_dn)
-
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
-
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
-
- print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
-
- #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
- res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
- self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
-
- #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
- res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
- self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
-
- #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
- res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
- self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
-
- # This is a Samba special, and does not exist in real AD
- # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
- # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
- # if (res.error != 0 || len(res) != 1) {
- # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
- # self.assertEquals(len(res), 1)
- # }
- # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
- # self.assertEquals(res[0].cn, "ldaptestUSER3")
- # self.assertEquals(res[0].name, "ldaptestUSER3")
-
- print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
- res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
- self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
- self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
- self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
-
- # ensure we cannot add it again
- try:
- ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
- "objectClass": ["person", "user"],
- "cn": "LDAPtestUSER3"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
-
- # rename back
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
-
- # ensure we cannnot rename it twice
- try:
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
- "cn=ldaptestuser2,cn=users," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- # ensure can now use that name
- ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
- "objectClass": ["person", "user"],
- "cn": "LDAPtestUSER3"})
-
- # ensure we now cannnot rename
- try:
- ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
- try:
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertTrue(num in (71, 64))
-
- ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
-
- ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
-
- self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
-
- ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
-
- print "Testing subtree Renames"
-
- ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
- "objectClass": "container"})
-
- self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
- ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
- "objectClass": ["person", "user"],
- "cn": "LDAPtestUSER4"})
-
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-add: member
-member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
-""")
-
- print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
- ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
-
- print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
-
- print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
- try:
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- expression="(&(cn=ldaptestuser4)(objectClass=user))",
- scope=SCOPE_SUBTREE)
- self.fail(res)
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
- try:
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
- res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
- self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
-
- time.sleep(4)
-
- print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
- res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
- self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?")
-
- print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
- try:
- ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
- try:
- ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
-
- print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
- try:
- ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
-
- print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
- res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
- self.assertEquals(len(res), 1)
- res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
- self.assertEquals(len(res), 0)
-
- print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
- res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
- # FIXME: self.assertEquals(len(res), 0)
-
- print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
- res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
- # FIXME: self.assertEquals(len(res), 0)
-
- print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
- ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
- print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
- ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
-
- self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn)
- ldb.add({"dn": "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn, "objectClass": "user"})
-
- self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà ,cn=users," + self.base_dn)
- ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà ,cn=users," + self.base_dn, "objectClass": "user"})
-
- print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
- self.assertEquals(str(res[0]["name"]), "ldaptestuser")
- self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
- self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
- self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
- self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
- self.assertEquals(len(res[0]["memberOf"]), 1)
-
- print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
- res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
- self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
-
- self.assertEquals(res[0].dn, res2[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
- res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
- self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
-
- self.assertEquals(res[0].dn, res3[0].dn)
-
- if gc_ldb is not None:
- print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
- res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
- self.assertEquals(len(res3gc), 1)
-
- self.assertEquals(res[0].dn, res3gc[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
-
- res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
- self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
-
- self.assertEquals(res[0].dn, res3control[0].dn)
-
- ldb.delete(res[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
- self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
- self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
- self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
- self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
- self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
- self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
- self.assertEquals(len(res[0]["memberOf"]), 1)
-
- print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
- res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
- self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
-
- self.assertEquals(res[0].dn, res2[0].dn)
-
- if gc_ldb is not None:
- print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
- res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
- self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
-
- self.assertEquals(res[0].dn, res2gc[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
- res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
- self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
-
- self.assertEquals(res[0].dn, res3[0].dn)
-
- if gc_ldb is not None:
- print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
- res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
- self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
-
- self.assertEquals(res[0].dn, res3gc[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
- res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
- self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
-
- self.assertEquals(res[0].dn, res4[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
- res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
- self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
-
- self.assertEquals(res[0].dn, res5[0].dn)
-
- print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
- res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
- self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
-
- self.assertEquals(res[0].dn, res6[0].dn)
-
- ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
-
- print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
- self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
- self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
- self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
- self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369)
- self.assertEquals(int(res[0]["userAccountControl"][0]), 4096)
-
- ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
-
- attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
- print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
- res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
-
- self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
- self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
- self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
- self.assertTrue("objectSid" in res_user[0])
- self.assertTrue("objectGUID" in res_user[0])
- self.assertTrue("whenCreated" in res_user[0])
- self.assertTrue("nTSecurityDescriptor" in res_user[0])
- self.assertTrue("allowedAttributes" in res_user[0])
- self.assertTrue("allowedAttributesEffective" in res_user[0])
- self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
-
- ldaptestuser2_sid = res_user[0]["objectSid"][0]
- ldaptestuser2_guid = res_user[0]["objectGUID"][0]
-
- attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
- print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
- self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
- self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("objectSid" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertTrue("nTSecurityDescriptor" in res[0])
- self.assertTrue("allowedAttributes" in res[0])
- self.assertTrue("allowedAttributesEffective" in res[0])
- memberUP = []
- for m in res[0]["member"]:
- memberUP.append(m.upper())
- self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
-
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
-
- print res[0]["member"]
- memberUP = []
- for m in res[0]["member"]:
- memberUP.append(m.upper())
- print ("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper()
-
- self.assertTrue(("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
-
- print "Testing Linked attribute behaviours"
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-replace: member
-member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
-member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
-""")
-
- ldb.modify_ldif("""
-dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
-changetype: modify
-replace: member
-member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
-""")
-
- ldb.modify_ldif("""
-dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
-changetype: modify
-delete: member
-""")
-
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-add: member
-member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
-member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
-""")
-
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-replace: member
-""")
-
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-add: member
-member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
-member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
-""")
-
- ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
-changetype: modify
-delete: member
-member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
-""")
-
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(len(res[0]["member"]), 1)
-
- ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
-
- time.sleep(4)
-
- attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
- print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
- self.assertTrue("member" not in res[0])
-
- print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
-
- self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
- self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
- self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
- self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("whenCreated" in res[0])
-
- ldb.delete(res[0].dn)
-
- print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
-
- ldb.delete(res[0].dn)
-
- ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
-
- print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
- res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
-
- #FIXME: self.assert len(res) == 1, "Could not find (expect space collapse, win2k3 fails) (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
-
- print "Testing that we can't get at the configuration DN from the main search base"
- res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertEquals(len(res), 0)
-
- print "Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control"
- res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
- self.assertTrue(len(res) > 0)
-
- if gc_ldb is not None:
- print "Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
-
- res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
- self.assertTrue(len(res) > 0)
-
- print "Testing that we do find configuration elements in the global catlog"
- res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing that we do find configuration elements and user elements at the same time"
- res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
- res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing that we can get at the configuration DN on the main LDAP port"
- res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing objectCategory canonacolisation"
- res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
- self.assertTrue(len(res) != 0)
-
- res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
- self.assertTrue(len(res) != 0)
-
- print "Testing objectClass attribute order on "+ self.base_dn
- res = ldb.search(expression="objectClass=domain", base=self.base_dn,
- scope=SCOPE_BASE, attrs=["objectClass"])
- self.assertEquals(len(res), 1)
-
- self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
-
- # check enumeration
-
- print "Testing ldb.search for objectCategory=person"
- res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing ldb.search for objectCategory=person with domain scope control"
- res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
- self.assertTrue(len(res) > 0)
-
- print "Testing ldb.search for objectCategory=user"
- res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing ldb.search for objectCategory=user with domain scope control"
- res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
- self.assertTrue(len(res) > 0)
-
- print "Testing ldb.search for objectCategory=group"
- res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
- self.assertTrue(len(res) > 0)
-
- print "Testing ldb.search for objectCategory=group with domain scope control"
- res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
- self.assertTrue(len(res) > 0)
-
- def test_security_descriptor_add(self):
- """ Testing ldb.add_ldif() for nTSecurityDescriptor """
- user_name = "testdescriptoruser1"
- user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
- #
- # Test add_ldif() with SDDL security descriptor input
- #
- self.delete_force(self.ldb, user_dn)
- try:
- sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name + """
-nTSecurityDescriptor: """ + sddl)
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack( security.descriptor, desc )
- desc_sddl = desc.as_sddl( self.domain_sid )
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
- #
- # Test add_ldif() with BASE64 security descriptor
- #
- try:
- sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
- desc = security.descriptor.from_sddl(sddl, self.domain_sid)
- desc_binary = ndr_pack(desc)
- desc_base64 = base64.b64encode(desc_binary)
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name + """
-nTSecurityDescriptor:: """ + desc_base64)
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
-
- def test_security_descriptor_add_neg(self):
- """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
- Negative test
- """
- user_name = "testdescriptoruser1"
- user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
- self.delete_force(self.ldb, user_dn)
- try:
- sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
- desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
- desc_base64 = base64.b64encode( ndr_pack(desc) )
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name + """
-nTSecurityDescriptor:: """ + desc_base64)
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- print res
- self.assertRaises(KeyError, lambda: res[0]["nTSecurityDescriptor"])
- finally:
- self.delete_force(self.ldb, user_dn)
-
- def test_security_descriptor_modify(self):
- """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
- user_name = "testdescriptoruser2"
- user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
- #
- # Delete user object and test modify_ldif() with SDDL security descriptor input
- # Add ACE to the original descriptor test
- #
- try:
- self.delete_force(self.ldb, user_dn)
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name)
- # Modify descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
- mod = """
-dn: """ + user_dn + """
-changetype: modify
-replace: nTSecurityDescriptor
-nTSecurityDescriptor: """ + sddl
- self.ldb.modify_ldif(mod)
- # Read modified descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
- #
- # Test modify_ldif() with SDDL security descriptor input
- # New desctiptor test
- #
- try:
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name)
- # Modify descriptor
- sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
- mod = """
-dn: """ + user_dn + """
-changetype: modify
-replace: nTSecurityDescriptor
-nTSecurityDescriptor: """ + sddl
- self.ldb.modify_ldif(mod)
- # Read modified descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
- #
- # Test modify_ldif() with BASE64 security descriptor input
- # Add ACE to the original descriptor test
- #
- try:
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name)
- # Modify descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
- desc = security.descriptor.from_sddl(sddl, self.domain_sid)
- desc_base64 = base64.b64encode(ndr_pack(desc))
- mod = """
-dn: """ + user_dn + """
-changetype: modify
-replace: nTSecurityDescriptor
-nTSecurityDescriptor:: """ + desc_base64
- self.ldb.modify_ldif(mod)
- # Read modified descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
- #
- # Test modify_ldif() with BASE64 security descriptor input
- # New descriptor test
- #
- try:
- self.delete_force(self.ldb, user_dn)
- self.ldb.add_ldif("""
-dn: """ + user_dn + """
-objectclass: user
-sAMAccountName: """ + user_name)
- # Modify descriptor
- sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
- desc = security.descriptor.from_sddl(sddl, self.domain_sid)
- desc_base64 = base64.b64encode(ndr_pack(desc))
- mod = """
-dn: """ + user_dn + """
-changetype: modify
-replace: nTSecurityDescriptor
-nTSecurityDescriptor:: """ + desc_base64
- self.ldb.modify_ldif(mod)
- # Read modified descriptor
- res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- desc = ndr_unpack(security.descriptor, desc)
- desc_sddl = desc.as_sddl(self.domain_sid)
- self.assertEqual(desc_sddl, sddl)
- finally:
- self.delete_force(self.ldb, user_dn)
-
-class BaseDnTests(unittest.TestCase):
- def setUp(self):
- self.ldb = ldb
-
- def test_rootdse_attrs(self):
- """Testing for all rootDSE attributes"""
- res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
- self.assertEquals(len(res), 1)
-
- def test_highestcommittedusn(self):
- """Testing for highestCommittedUSN"""
- res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
- self.assertEquals(len(res), 1)
- self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
-
- def test_netlogon(self):
- """Testing for netlogon via LDAP"""
- res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
- self.assertEquals(len(res), 0)
-
- def test_netlogon_highestcommitted_usn(self):
- """Testing for netlogon and highestCommittedUSN via LDAP"""
- res = self.ldb.search("", scope=SCOPE_BASE,
- attrs=["netlogon", "highestCommittedUSN"])
- self.assertEquals(len(res), 0)
-
-class SchemaTests(unittest.TestCase):
- def delete_force(self, ldb, dn):
- try:
- ldb.delete(dn)
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- def find_schemadn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["schemaNamingContext"][0]
-
- def find_basedn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE,
- attrs=["defaultNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["defaultNamingContext"][0]
-
- def setUp(self):
- self.ldb = ldb
- self.schema_dn = self.find_schemadn(ldb)
- self.base_dn = self.find_basedn(ldb)
-
- def test_generated_schema(self):
- """Testing we can read the generated schema via LDAP"""
- res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
- attrs=["objectClasses", "attributeTypes", "dITContentRules"])
- self.assertEquals(len(res), 1)
- self.assertTrue("dITContentRules" in res[0])
- self.assertTrue("objectClasses" in res[0])
- self.assertTrue("attributeTypes" in res[0])
-
- def test_generated_schema_is_operational(self):
- """Testing we don't get the generated schema via LDAP by default"""
- res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
- attrs=["*"])
- self.assertEquals(len(res), 1)
- self.assertFalse("dITContentRules" in res[0])
- self.assertFalse("objectClasses" in res[0])
- self.assertFalse("attributeTypes" in res[0])
-
- def test_schemaUpdateNow(self):
- """Testing schemaUpdateNow"""
- class_name = "test-class" + time.strftime("%s", time.gmtime())
- class_ldap_display_name = class_name.replace("-", "")
- object_name = "obj" + time.strftime("%s", time.gmtime())
-
- ldif = """
-dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
-lDAPDisplayName: """ + class_ldap_display_name + """
-objectClass: top
-objectClass: classSchema
-adminDescription: """ + class_name + """
-adminDisplayName: """ + class_name + """
-cn: """ + class_name + """
-objectCategory: CN=Class-Schema,""" + self.schema_dn + """
-defaultObjectCategory: CN=%s,%s""" % (class_name, self.schema_dn) + """
-distinguishedName: CN=%s,%s""" % (class_name, self.schema_dn) + """
-governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
-instanceType: 4
-name: """ + class_name + """
-objectClassCategory: 1
-subClassOf: organizationalPerson
-systemFlags: 16
-rDNAttID: cn
-systemMustContain: cn
-systemOnly: FALSE
-"""
- self.ldb.add_ldif(ldif)
- ldif = """
-dn:
-changetype: modify
-add: schemaUpdateNow
-schemaUpdateNow: 1
-"""
- self.ldb.modify_ldif(ldif)
- ldif = """
-dn: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
-objectClass: organizationalPerson
-objectClass: person
-objectClass: """ + class_ldap_display_name + """
-objectClass: top
-cn: """ + object_name + """
-instanceType: 4
-objectCategory: CN=%s,%s"""% (class_name, self.schema_dn) + """
-distinguishedName: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
-name: """ + object_name + """
-"""
- self.ldb.add_ldif(ldif)
- # Search for created objectClass
- res = []
- res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
- self.assertNotEqual(res, [])
-
- res = []
- res = self.ldb.search("cn=%s,cn=Users,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["*"])
- self.assertNotEqual(res, [])
- # Delete the object
- self.delete_force(self.ldb, "cn=%s,cn=Users,%s" % (object_name, self.base_dn))
-
-if not "://" in host:
- host = "ldap://%s" % host
-
-ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
-gc_ldb = Ldb("%s:3268" % host, credentials=creds,
- session_info=system_session(), lp=lp)
-
-runner = SubunitTestRunner()
-rc = 0
-if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
- rc = 1
-if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
- rc = 1
-if not runner.run(unittest.makeSuite(SchemaTests)).wasSuccessful():
- rc = 1
-sys.exit(rc)
diff --git a/source4/lib/ldb/tests/python/sec_descriptor.py b/source4/lib/ldb/tests/python/sec_descriptor.py
deleted file mode 100755
index 155b65f4ab..0000000000
--- a/source4/lib/ldb/tests/python/sec_descriptor.py
+++ /dev/null
@@ -1,1615 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import getopt
-import optparse
-import sys
-import os
-import base64
-import re
-import random
-
-sys.path.append("bin/python")
-sys.path.append("../lib/subunit/python")
-
-import samba.getopt as options
-
-# Some error messages that are being tested
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
-from ldb import ERR_NO_SUCH_OBJECT, ERR_INVALID_DN_SYNTAX, ERR_UNWILLING_TO_PERFORM
-from ldb import ERR_INSUFFICIENT_ACCESS_RIGHTS
-
-# For running the test unit
-from samba.ndr import ndr_pack, ndr_unpack
-from samba.dcerpc import security
-
-from samba.auth import system_session
-from samba import Ldb, DS_DOMAIN_FUNCTION_2008
-from subunit import SubunitTestRunner
-import unittest
-
-parser = optparse.OptionParser("sec_descriptor [options] <host>")
-sambaopts = options.SambaOptions(parser)
-parser.add_option_group(sambaopts)
-parser.add_option_group(options.VersionOptions(parser))
-
-# use command line creds if available
-credopts = options.CredentialsOptions(parser)
-parser.add_option_group(credopts)
-opts, args = parser.parse_args()
-
-if len(args) < 1:
- parser.print_usage()
- sys.exit(1)
-
-host = args[0]
-
-lp = sambaopts.get_loadparm()
-creds = credopts.get_credentials(lp)
-
-#
-# Tests start here
-#
-
-class DescriptorTests(unittest.TestCase):
-
- def delete_force(self, ldb, dn):
- try:
- ldb.delete(dn)
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- def find_basedn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE,
- attrs=["defaultNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["defaultNamingContext"][0]
-
- def find_configurationdn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["configurationNamingContext"][0]
-
- def find_schemadn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["schemaNamingContext"][0]
-
- def find_domain_sid(self, ldb):
- res = ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
- return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
-
- def get_users_domain_dn(self, name):
- return "CN=%s,CN=Users,%s" % (name, self.base_dn)
-
- def modify_desc(self, object_dn, desc):
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- mod = """
-dn: """ + object_dn + """
-changetype: modify
-replace: nTSecurityDescriptor
-"""
- if isinstance(desc, str):
- mod += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- mod += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- self.ldb_admin.modify_ldif(mod)
-
- def create_domain_ou(self, _ldb, ou_dn, desc=None):
- ldif = """
-dn: """ + ou_dn + """
-ou: """ + ou_dn.split(",")[0][3:] + """
-objectClass: organizationalUnit
-url: www.example.com
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def create_domain_user(self, _ldb, user_dn, desc=None):
- ldif = """
-dn: """ + user_dn + """
-sAMAccountName: """ + user_dn.split(",")[0][3:] + """
-objectClass: user
-userPassword: samba123@
-url: www.example.com
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def create_domain_group(self, _ldb, group_dn, desc=None):
- ldif = """
-dn: """ + group_dn + """
-objectClass: group
-sAMAccountName: """ + group_dn.split(",")[0][3:] + """
-groupType: 4
-url: www.example.com
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def get_unique_schema_class_name(self):
- while True:
- class_name = "test-class%s" % random.randint(1,100000)
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- try:
- self.ldb_admin.search(base=class_dn, attrs=["*"])
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
- return class_name
-
- def create_schema_class(self, _ldb, object_dn, desc=None):
- ldif = """
-dn: """ + object_dn + """
-objectClass: classSchema
-objectCategory: CN=Class-Schema,""" + self.schema_dn + """
-defaultObjectCategory: """ + object_dn + """
-distinguishedName: """ + object_dn + """
-governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
-instanceType: 4
-objectClassCategory: 1
-subClassOf: organizationalPerson
-systemFlags: 16
-rDNAttID: cn
-systemMustContain: cn
-systemOnly: FALSE
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def create_configuration_container(self, _ldb, object_dn, desc=None):
- ldif = """
-dn: """ + object_dn + """
-objectClass: container
-objectCategory: CN=Container,""" + self.schema_dn + """
-showInAdvancedViewOnly: TRUE
-instanceType: 4
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def create_configuration_specifier(self, _ldb, object_dn, desc=None):
- ldif = """
-dn: """ + object_dn + """
-objectClass: displaySpecifier
-showInAdvancedViewOnly: TRUE
-"""
- if desc:
- assert(isinstance(desc, str) or isinstance(desc, security.descriptor))
- if isinstance(desc, str):
- ldif += "nTSecurityDescriptor: %s" % desc
- elif isinstance(desc, security.descriptor):
- ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
- _ldb.add_ldif(ldif)
-
- def read_desc(self, object_dn):
- res = self.ldb_admin.search(base=object_dn, attrs=["nTSecurityDescriptor"])
- desc = res[0]["nTSecurityDescriptor"][0]
- return ndr_unpack( security.descriptor, desc )
-
- def enable_account(self, user_dn):
- """Enable an account.
- :param user_dn: Dn of the account to enable.
- """
- res = self.ldb_admin.search(user_dn, SCOPE_BASE, None, ["userAccountControl"])
- assert len(res) == 1
- userAccountControl = res[0]["userAccountControl"][0]
- userAccountControl = int(userAccountControl)
- if (userAccountControl & 0x2):
- userAccountControl = userAccountControl & ~0x2 # remove disabled bit
- if (userAccountControl & 0x20):
- userAccountControl = userAccountControl & ~0x20 # remove 'no password required' bit
- mod = """
-dn: """ + user_dn + """
-changetype: modify
-replace: userAccountControl
-userAccountControl: %s""" % userAccountControl
- if self.WIN2003:
- mod = re.sub("userAccountControl: \d.*", "userAccountControl: 544", mod)
- self.ldb_admin.modify_ldif(mod)
-
- def get_ldb_connection(self, target_username, target_password):
- username_save = creds.get_username(); password_save = creds.get_password()
- creds.set_username(target_username)
- creds.set_password(target_password)
- ldb_target = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
- creds.set_username(username_save); creds.set_password(password_save)
- return ldb_target
-
- def get_object_sid(self, object_dn):
- res = self.ldb_admin.search(object_dn)
- return ndr_unpack( security.dom_sid, res[0]["objectSid"][0] )
-
- def dacl_add_ace(self, object_dn, ace):
- desc = self.read_desc( object_dn )
- desc_sddl = desc.as_sddl( self.domain_sid )
- if ace in desc_sddl:
- return
- if desc_sddl.find("(") >= 0:
- desc_sddl = desc_sddl[0:desc_sddl.index("(")] + ace + desc_sddl[desc_sddl.index("("):]
- else:
- desc_sddl = desc_sddl + ace
- self.modify_desc(object_dn, desc_sddl)
-
- def get_desc_sddl(self, object_dn):
- """ Return object nTSecutiryDescriptor in SDDL format
- """
- desc = self.read_desc(object_dn)
- return desc.as_sddl(self.domain_sid)
-
- def setUp(self):
- self.ldb_admin = ldb
- self.base_dn = self.find_basedn(self.ldb_admin)
- self.configuration_dn = self.find_configurationdn(self.ldb_admin)
- self.schema_dn = self.find_schemadn(self.ldb_admin)
- self.domain_sid = self.find_domain_sid(self.ldb_admin)
- print "baseDN: %s" % self.base_dn
- self.SAMBA = False; self.WIN2003 = False
- res = self.ldb_admin.search(base="", expression="", scope=SCOPE_BASE, attrs=["vendorName"])
- if "vendorName" in res[0].keys() and "Samba Team" in res[0]["vendorName"][0]:
- self.SAMBA = True
- else:
- self.WIN2003 = True
- #print "self.SAMBA:", self.SAMBA
- #print "self.WIN2003:", self.WIN2003
-
- ################################################################################################
-
- ## Tests for DOMAIN
-
- # Default descriptor tests #####################################################################
-
-class OwnerGroupDescriptorTests(DescriptorTests):
-
- def setUp(self):
- DescriptorTests.setUp(self)
- if self.SAMBA:
- ### Create users
- # User 1
- user_dn = self.get_users_domain_dn("testuser1")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Enterprise Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 2
- user_dn = self.get_users_domain_dn("testuser2")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Domain Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 3
- user_dn = self.get_users_domain_dn("testuser3")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Schema Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 4
- user_dn = self.get_users_domain_dn("testuser4")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- # User 5
- user_dn = self.get_users_domain_dn("testuser5")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Enterprise Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn + """
-
-dn: CN=Domain Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 6
- user_dn = self.get_users_domain_dn("testuser6")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Enterprise Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn + """
-
-dn: CN=Domain Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn + """
-
-dn: CN=Schema Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 7
- user_dn = self.get_users_domain_dn("testuser7")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Domain Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn + """
-
-dn: CN=Schema Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- # User 8
- user_dn = self.get_users_domain_dn("testuser8")
- self.create_domain_user(self.ldb_admin, user_dn)
- self.enable_account(user_dn)
- ldif = """
-dn: CN=Enterprise Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn + """
-
-dn: CN=Schema Admins,CN=Users,""" + self.base_dn + """
-changetype: add
-member: """ + user_dn
- self.ldb_admin.modify_ldif(ldif)
- self.results = {
- # msDS-Behavior-Version < DS_DOMAIN_FUNCTION_2008
- "ds_behavior_win2003" : {
- "100" : "O:EAG:DU",
- "101" : "O:DAG:DU",
- "102" : "O:%sG:DU",
- "103" : "O:%sG:DU",
- "104" : "O:DAG:DU",
- "105" : "O:DAG:DU",
- "106" : "O:DAG:DU",
- "107" : "O:EAG:DU",
- "108" : "O:DAG:DA",
- "109" : "O:DAG:DA",
- "110" : "O:%sG:DA",
- "111" : "O:%sG:DA",
- "112" : "O:DAG:DA",
- "113" : "O:DAG:DA",
- "114" : "O:DAG:DA",
- "115" : "O:DAG:DA",
- "130" : "O:EAG:DU",
- "131" : "O:DAG:DU",
- "132" : "O:SAG:DU",
- "133" : "O:%sG:DU",
- "134" : "O:EAG:DU",
- "135" : "O:SAG:DU",
- "136" : "O:SAG:DU",
- "137" : "O:SAG:DU",
- "138" : "O:DAG:DA",
- "139" : "O:DAG:DA",
- "140" : "O:%sG:DA",
- "141" : "O:%sG:DA",
- "142" : "O:DAG:DA",
- "143" : "O:DAG:DA",
- "144" : "O:DAG:DA",
- "145" : "O:DAG:DA",
- "160" : "O:EAG:DU",
- "161" : "O:DAG:DU",
- "162" : "O:%sG:DU",
- "163" : "O:%sG:DU",
- "164" : "O:EAG:DU",
- "165" : "O:EAG:DU",
- "166" : "O:DAG:DU",
- "167" : "O:EAG:DU",
- "168" : "O:DAG:DA",
- "169" : "O:DAG:DA",
- "170" : "O:%sG:DA",
- "171" : "O:%sG:DA",
- "172" : "O:DAG:DA",
- "173" : "O:DAG:DA",
- "174" : "O:DAG:DA",
- "175" : "O:DAG:DA",
- },
- # msDS-Behavior-Version >= 3
- "ds_behavior_win2008" : {
- "100" : "O:EAG:EA",
- "101" : "O:DAG:DA",
- "102" : "O:%sG:DU",
- "103" : "O:%sG:DU",
- "104" : "O:DAG:DA",
- "105" : "O:DAG:DA",
- "106" : "O:DAG:DA",
- "107" : "O:EAG:EA",
- "108" : "O:DAG:DA",
- "109" : "O:DAG:DA",
- "110" : "O:%sG:DA",
- "111" : "O:%sG:DA",
- "112" : "O:DAG:DA",
- "113" : "O:DAG:DA",
- "114" : "O:DAG:DA",
- "115" : "O:DAG:DA",
- "130" : "",
- "131" : "",
- "132" : "",
- "133" : "%s",
- "134" : "",
- "135" : "",
- "136" : "",
- "137" : "",
- "138" : "",
- "139" : "",
- "140" : "%s",
- "141" : "%s",
- "142" : "",
- "143" : "",
- "144" : "",
- "145" : "",
- "160" : "O:EAG:EA",
- "161" : "O:DAG:DA",
- "162" : "O:%sG:DU",
- "163" : "O:%sG:DU",
- "164" : "O:EAG:EA",
- "165" : "O:EAG:EA",
- "166" : "O:DAG:DA",
- "167" : "O:EAG:EA",
- "168" : "O:DAG:DA",
- "169" : "O:DAG:DA",
- "170" : "O:%sG:DA",
- "171" : "O:%sG:DA",
- "172" : "O:DAG:DA",
- "173" : "O:DAG:DA",
- "174" : "O:DAG:DA",
- "175" : "O:DAG:DA",
- },
- }
- # Discover 'msDS-Behavior-Version'
- res = self.ldb_admin.search(base=self.base_dn, expression="distinguishedName=%s" % self.base_dn, \
- attrs=['msDS-Behavior-Version'])
- res = int(res[0]['msDS-Behavior-Version'][0])
- if res < DS_DOMAIN_FUNCTION_2008:
- self.DS_BEHAVIOR = "ds_behavior_win2003"
- else:
- self.DS_BEHAVIOR = "ds_behavior_win2008"
-
- def tearDown(self):
- if self.SAMBA:
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser1"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser2"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser3"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser4"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser5"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser6"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser7"))
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("testuser8"))
- # DOMAIN
- self.delete_force(self.ldb_admin, self.get_users_domain_dn("test_domain_group1"))
- self.delete_force(self.ldb_admin, "CN=test_domain_user1,OU=test_domain_ou1," + self.base_dn)
- self.delete_force(self.ldb_admin, "OU=test_domain_ou2,OU=test_domain_ou1," + self.base_dn)
- self.delete_force(self.ldb_admin, "OU=test_domain_ou1," + self.base_dn)
- # SCHEMA
- # CONFIGURATION
- self.delete_force(self.ldb_admin, "CN=test-specifier1,CN=test-container1,CN=DisplaySpecifiers," \
- + self.configuration_dn)
- self.delete_force(self.ldb_admin, "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn)
-
- def check_user_belongs(self, user_dn, groups=[]):
- """ Test wether user is member of the expected group(s) """
- if groups != []:
- # User is member of at least one additional group
- res = self.ldb_admin.search(user_dn, attrs=["memberOf"])
- res = [x.upper() for x in sorted(list(res[0]["memberOf"]))]
- expected = []
- for x in groups:
- expected.append(self.get_users_domain_dn(x))
- expected = [x.upper() for x in sorted(expected)]
- self.assertEqual(expected, res)
- else:
- # User is not a member of any additional groups but default
- res = self.ldb_admin.search(user_dn, attrs=["*"])
- res = [x.upper() for x in res[0].keys()]
- self.assertFalse( "MEMBEROF" in res)
-
- def test_100(self):
- """ Enterprise admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection("testuser1", "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["100"], res)
-
- def test_101(self):
- """ Dmain admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["101"], res)
-
- def test_102(self):
- """ Schema admin group member with CC right creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- object_dn = "OU=test_domain_ou1," + self.base_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;%s)" % str(user_sid)
- self.dacl_add_ace(object_dn, mod)
- # Create additional object into the first one
- object_dn = "CN=test_domain_user1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_user(_ldb, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["102"] % str(user_sid), res)
-
- def test_103(self):
- """ Regular user with CC right creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- object_dn = "OU=test_domain_ou1," + self.base_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;%s)" % str(user_sid)
- self.dacl_add_ace(object_dn, mod)
- # Create additional object into the first one
- object_dn = "CN=test_domain_user1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_user(_ldb, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["103"] % str(user_sid), res)
-
- def test_104(self):
- """ Enterprise & Domain admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["104"], res)
-
- def test_105(self):
- """ Enterprise & Domain & Schema admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["105"], res)
-
- def test_106(self):
- """ Domain & Schema admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["106"], res)
-
- def test_107(self):
- """ Enterprise & Schema admin group member creates object (default nTSecurityDescriptor) in DOMAIN
- """
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- self.create_domain_group(_ldb, group_dn)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["107"], res)
-
- # Control descriptor tests #####################################################################
-
- def test_108(self):
- """ Enterprise admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["108"], res)
-
- def test_109(self):
- """ Domain admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["109"], res)
-
- def test_110(self):
- """ Schema admin group member with CC right creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- object_dn = "OU=test_domain_ou1," + self.base_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;%s)" % str(user_sid)
- self.dacl_add_ace(object_dn, mod)
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- # Create additional object into the first one
- object_dn = "CN=test_domain_user1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_user(_ldb, object_dn, desc_sddl)
- desc = self.read_desc(object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["110"] % str(user_sid), res)
-
- def test_111(self):
- """ Regular user with CC right creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- object_dn = "OU=test_domain_ou1," + self.base_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;%s)" % str(user_sid)
- self.dacl_add_ace(object_dn, mod)
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- # Create additional object into the first one
- object_dn = "CN=test_domain_user1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_user(_ldb, object_dn, desc_sddl)
- desc = self.read_desc(object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["111"] % str(user_sid), res)
-
- def test_112(self):
- """ Domain & Enterprise admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["112"], res)
-
- def test_113(self):
- """ Domain & Enterprise & Schema admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["113"], res)
-
- def test_114(self):
- """ Domain & Schema admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["114"], res)
-
- def test_115(self):
- """ Enterprise & Schema admin group member creates object (custom descriptor) in DOMAIN
- """
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- group_dn = "CN=test_domain_group1,CN=Users," + self.base_dn
- self.delete_force(self.ldb_admin, group_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_domain_group(_ldb, group_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(group_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["115"], res)
-
-
- def test_999(self):
- user_name = "Administrator"
- object_dn = "OU=test_domain_ou1," + self.base_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(D;CI;WP;;;S-1-3-0)"
- #mod = ""
- self.dacl_add_ace(object_dn, mod)
- desc_sddl = self.get_desc_sddl(object_dn)
- # Create additional object into the first one
- object_dn = "OU=test_domain_ou2," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_domain_ou(self.ldb_admin, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
-
- ## Tests for SCHEMA
-
- # Defalt descriptor tests ##################################################################
-
- def test_130(self):
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["130"], res)
-
- def test_131(self):
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["131"], res)
-
- def test_132(self):
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["132"], res)
-
- def test_133(self):
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- #Change Schema partition descriptor
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["133"] % str(user_sid), res)
-
- def test_134(self):
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- #Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["134"], res)
-
- def test_135(self):
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["135"], res)
-
- def test_136(self):
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["136"], res)
-
- def test_137(self):
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["137"], res)
-
- # Custom descriptor tests ##################################################################
-
- def test_138(self):
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_139(self):
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_140(self):
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["140"] % str(user_sid), res)
-
- def test_141(self):
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["141"] % str(user_sid), res)
-
- def test_142(self):
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_143(self):
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_144(self):
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_145(self):
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Change Schema partition descriptor
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(self.schema_dn, mod)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- # Create example Schema class
- class_name = self.get_unique_schema_class_name()
- class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
- self.create_schema_class(_ldb, class_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(class_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- ## Tests for CONFIGURATION
-
- # Defalt descriptor tests ##################################################################
-
- def test_160(self):
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["160"], res)
-
- def test_161(self):
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["161"], res)
-
- def test_162(self):
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(self.ldb_admin, object_dn, )
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(object_dn, mod)
- # Create child object with user's credentials
- object_dn = "CN=test-specifier1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_specifier(_ldb, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["162"] % str(user_sid), res)
-
- def test_163(self):
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(self.ldb_admin, object_dn, )
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(object_dn, mod)
- # Create child object with user's credentials
- object_dn = "CN=test-specifier1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_specifier(_ldb, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["163"] % str(user_sid), res)
-
- def test_164(self):
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["164"], res)
-
- def test_165(self):
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["165"], res)
-
- def test_166(self):
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["166"], res)
-
- def test_167(self):
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(_ldb, object_dn, )
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["167"], res)
-
- # Custom descriptor tests ##################################################################
-
- def test_168(self):
- user_name = "testuser1"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_169(self):
- user_name = "testuser2"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_170(self):
- user_name = "testuser3"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(self.ldb_admin, object_dn, )
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(object_dn, mod)
- # Create child object with user's credentials
- object_dn = "CN=test-specifier1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- self.create_configuration_specifier(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["170"] % str(user_sid), res)
-
- def test_171(self):
- user_name = "testuser4"
- self.check_user_belongs(self.get_users_domain_dn(user_name), [])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
- self.delete_force(self.ldb_admin, object_dn)
- self.create_configuration_container(self.ldb_admin, object_dn, )
- user_sid = self.get_object_sid( self.get_users_domain_dn(user_name) )
- mod = "(A;;CC;;;AU)"
- self.dacl_add_ace(object_dn, mod)
- # Create child object with user's credentials
- object_dn = "CN=test-specifier1," + object_dn
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- # NB! Problematic owner part won't accept DA only <User Sid> !!!
- desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
- self.create_configuration_specifier(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual(self.results[self.DS_BEHAVIOR]["171"] % str(user_sid), res)
-
- def test_172(self):
- user_name = "testuser5"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_173(self):
- user_name = "testuser6"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_174(self):
- user_name = "testuser7"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Domain Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- def test_175(self):
- user_name = "testuser8"
- self.check_user_belongs(self.get_users_domain_dn(user_name), ["Enterprise Admins", "Schema Admins"])
- # Open Ldb connection with the tested user
- _ldb = self.get_ldb_connection(user_name, "samba123@")
- # Create example Configuration container
- container_name = "test-container1"
- object_dn = "CN=%s,CN=DisplaySpecifiers,%s" % (container_name, self.configuration_dn)
- self.delete_force(self.ldb_admin, object_dn)
- # Create a custom security descriptor
- desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
- self.create_configuration_container(_ldb, object_dn, desc_sddl)
- desc_sddl = self.get_desc_sddl(object_dn)
- res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
- self.assertEqual("O:DAG:DA", res)
-
- ########################################################################################
- # Inharitance tests for DACL
-
-class DaclDescriptorTests(DescriptorTests):
-
- def setUp(self):
- DescriptorTests.setUp(self)
-
- def tearDown(self):
- self.delete_force(self.ldb_admin, "CN=test_inherit_group,OU=test_inherit_ou," + self.base_dn)
- self.delete_force(self.ldb_admin, "OU=test_inherit_ou," + self.base_dn)
-
- def create_clean_ou(self, object_dn):
- """ Base repeating setup for unittests to follow """
- res = self.ldb_admin.search(base=self.base_dn, scope=SCOPE_SUBTREE, \
- expression="distinguishedName=%s" % object_dn)
- # Make sure top testing OU has been deleted before starting the test
- self.assertEqual(res, [])
- self.create_domain_ou(self.ldb_admin, object_dn)
- desc_sddl = self.get_desc_sddl(object_dn)
- # Make sutre there are inheritable ACEs initially
- self.assertTrue("CI" in desc_sddl or "OI" in desc_sddl)
- # Find and remove all inherit ACEs
- res = re.findall("\(.*?\)", desc_sddl)
- res = [x for x in res if ("CI" in x) or ("OI" in x)]
- for x in res:
- desc_sddl = desc_sddl.replace(x, "")
- # Add flag 'protected' in both DACL and SACL so no inherit ACEs
- # can propagate from above
- desc_sddl = desc_sddl.replace(":AI", ":AIP")
- # colon at the end breaks ldif parsing, fix it
- res = re.findall(".*?S:", desc_sddl)
- if res:
- desc_sddl = desc_sddl.replace("S:", "")
- self.modify_desc(object_dn, desc_sddl)
- # Verify all inheritable ACEs are gone
- desc_sddl = self.get_desc_sddl(object_dn)
- self.assertFalse("CI" in desc_sddl)
- self.assertFalse("OI" in desc_sddl)
-
- def test_200(self):
- """ OU with protected flag and child group. See if the group has inherit ACEs.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn)
- # Make sure created group object contains NO inherit ACEs
- desc_sddl = self.get_desc_sddl(group_dn)
- self.assertFalse("ID" in desc_sddl)
-
- def test_201(self):
- """ OU with protected flag and no inherit ACEs, child group with custom descriptor.
- Verify group has custom and default ACEs only.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Create group child object using custom security descriptor
- sddl = "O:AUG:AUD:AI(D;;WP;;;DU)"
- self.create_domain_group(self.ldb_admin, group_dn, sddl)
- # Make sure created group descriptor has NO additional ACEs
- desc_sddl = self.get_desc_sddl(group_dn)
- print "group descriptor: " + desc_sddl
- self.assertEqual(desc_sddl, sddl)
-
- def test_202(self):
- """ OU with protected flag and add couple non-inheritable ACEs, child group.
- See if the group has any of the added ACEs.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom non-inheritable ACEs
- mod = "(D;;WP;;;DU)(A;;RP;;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- # Verify all inheritable ACEs are gone
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn)
- # Make sure created group object contains NO inherit ACEs
- # also make sure the added above non-inheritable ACEs are absant too
- desc_sddl = self.get_desc_sddl(group_dn)
- self.assertFalse("ID" in desc_sddl)
- for x in re.findall("\(.*?\)", mod):
- self.assertFalse(x in desc_sddl)
-
- def test_203(self):
- """ OU with protected flag and add 'CI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'CI' ACE
- mod = "(D;CI;WP;;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";CI;", ";CIID;")
- self.assertTrue(mod in desc_sddl)
-
- def test_204(self):
- """ OU with protected flag and add 'OI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'CI' ACE
- mod = "(D;OI;WP;;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";OI;", ";OIIOID;") # change it how it's gonna look like
- self.assertTrue(mod in desc_sddl)
-
- def test_205(self):
- """ OU with protected flag and add 'OA' for GUID & 'CI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'OA' for 'name' attribute & 'CI' ACE
- mod = "(OA;CI;WP;bf967a0e-0de6-11d0-a285-00aa003049e2;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";CI;", ";CIID;") # change it how it's gonna look like
- self.assertTrue(mod in desc_sddl)
-
- def test_206(self):
- """ OU with protected flag and add 'OA' for GUID & 'OI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'OA' for 'name' attribute & 'OI' ACE
- mod = "(OA;OI;WP;bf967a0e-0de6-11d0-a285-00aa003049e2;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";OI;", ";OIIOID;") # change it how it's gonna look like
- self.assertTrue(mod in desc_sddl)
-
- def test_207(self):
- """ OU with protected flag and add 'OA' for OU specific GUID & 'CI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'OA' for 'st' attribute (OU specific) & 'CI' ACE
- mod = "(OA;CI;WP;bf967a39-0de6-11d0-a285-00aa003049e2;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";CI;", ";CIID;") # change it how it's gonna look like
- self.assertTrue(mod in desc_sddl)
-
- def test_208(self):
- """ OU with protected flag and add 'OA' for OU specific GUID & 'OI' ACE, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'OA' for 'st' attribute (OU specific) & 'OI' ACE
- mod = "(OA;OI;WP;bf967a39-0de6-11d0-a285-00aa003049e2;;DU)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- mod = mod.replace(";OI;", ";OIIOID;") # change it how it's gonna look like
- self.assertTrue(mod in desc_sddl)
-
- def test_209(self):
- """ OU with protected flag and add 'CI' ACE with 'CO' SID, child group.
- See if the group has the added inherited ACE.
- """
- ou_dn = "OU=test_inherit_ou," + self.base_dn
- group_dn = "CN=test_inherit_group," + ou_dn
- # Create inheritable-free OU
- self.create_clean_ou(ou_dn)
- # Add some custom 'CI' ACE
- mod = "(D;CI;WP;;;CO)"
- self.dacl_add_ace(ou_dn, mod)
- desc_sddl = self.get_desc_sddl(ou_dn)
- # Create group child object
- self.create_domain_group(self.ldb_admin, group_dn, "O:AUG:AUD:AI(A;;CC;;;AU)")
- # Make sure created group object contains only the above inherited ACE(s)
- # that we've added manually
- desc_sddl = self.get_desc_sddl(group_dn)
- self.assertTrue("(D;ID;WP;;;AU)" in desc_sddl)
- self.assertTrue("(D;CIIOID;WP;;;CO)" in desc_sddl)
-
- ########################################################################################
-
-if not "://" in host:
- host = "ldap://%s" % host
-ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp, options=["modules:paged_searches"])
-
-runner = SubunitTestRunner()
-rc = 0
-if not runner.run(unittest.makeSuite(OwnerGroupDescriptorTests)).wasSuccessful():
- rc = 1
-if not runner.run(unittest.makeSuite(DaclDescriptorTests)).wasSuccessful():
- rc = 1
-
-sys.exit(rc)
diff --git a/source4/lib/ldb/tests/sample_module.c b/source4/lib/ldb/tests/sample_module.c
index bbe4419b59..bee40a5e80 100644
--- a/source4/lib/ldb/tests/sample_module.c
+++ b/source4/lib/ldb/tests/sample_module.c
@@ -21,16 +21,51 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb_module.h"
-int sample_add(struct ldb_module *mod, struct ldb_request *req)
+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");
- return ldb_next_request(mod, req);
+ /* 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;
+ }
}
-const struct ldb_module_ops ldb_sample_module_ops = {
+
+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/test-controls.sh b/source4/lib/ldb/tests/test-controls.sh
new file mode 100755
index 0000000000..771085ec60
--- /dev/null
+++ b/source4/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 <<EOF | $VALGRIND ldbadd || exit 1
+dn: @MODULES
+@LIST: sample
+EOF
+
+cat <<EOF | $VALGRIND ldbadd || exit 1
+dn: dc=bar
+dc: bar
+someThing: someThingElse
+EOF
+
+$VALGRIND ldbsearch "(touchedBy=sample)" | grep "touchedBy: sample" || exit 1
+# This action are expected to fails because the sample module return an error when presented the relax control
+
+cat <<EOF | $VALGRIND ldbadd --controls "relax:0" && exit 1
+dn: dc=foobar
+dc: foobar
+someThing: someThingElse
+EOF
+
+cat <<EOF | $VALGRIND ldbmodify --controls "relax:0" && exit 1
+dn: dc=bar
+changetype: modify
+replace someThing
+someThing: someThingElseBetter
+EOF
+
+$VALGRIND ldbsearch --controls "bypassoperational:0" >/dev/null 2>&1 || exit 1
+
+set
diff --git a/source4/lib/ldb/tests/test-generic.sh b/source4/lib/ldb/tests/test-generic.sh
index fec4b5b078..8bbb7698fd 100755
--- a/source4/lib/ldb/tests/test-generic.sh
+++ b/source4/lib/ldb/tests/test-generic.sh
@@ -44,7 +44,7 @@ $VALGRIND ldbadd$EXEEXT $LDBDIR/tests/test-wrong_attributes.ldif && {
exit 1
}
-echo "testing indexed search"
+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
@@ -81,15 +81,12 @@ if [ $count != 3 ]; then
fi
echo "Testing binary file attribute value"
-mkdir -p tests/tmp
-cp $LDBDIR/tests/samba4.png tests/tmp/samba4.png
$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
-rm -f tests/tmp/samba4.png
echo "*TODO* Testing UTF8 upper lower case searches !!"
diff --git a/source4/lib/ldb/tests/test-schema.sh b/source4/lib/ldb/tests/test-schema.sh
index 2f10fb45e2..97841844db 100755
--- a/source4/lib/ldb/tests/test-schema.sh
+++ b/source4/lib/ldb/tests/test-schema.sh
@@ -19,12 +19,12 @@ $VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-1.ldif || exi
$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
+if [ "$?" = "0" ]; then
echo "test failed!"
exit 1
fi
$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif
-if [ "$?" == "0" ]; then
+if [ "$?" = "0" ]; then
echo "test failed!"
exit 1
fi
diff --git a/source4/lib/ldb/tests/test-tdb.sh b/source4/lib/ldb/tests/test-tdb.sh
index 1c35451962..9da1e57060 100755
--- a/source4/lib/ldb/tests/test-tdb.sh
+++ b/source4/lib/ldb/tests/test-tdb.sh
@@ -29,3 +29,5 @@ $VALGRIND ldbadd$EXEEXT $LDBDIR/tests/init.ldif || exit 1
. $LDBDIR/tests/test-extended.sh
. $LDBDIR/tests/test-tdb-features.sh
+
+. $LDBDIR/tests/test-controls.sh
diff --git a/source4/lib/ldb/tests/test.ldif b/source4/lib/ldb/tests/test.ldif
index e53fadc700..fd37f0037e 100644
--- a/source4/lib/ldb/tests/test.ldif
+++ b/source4/lib/ldb/tests/test.ldif
@@ -409,3 +409,9 @@ homephone: +1 313 555 8421
pager: +1 313 555 2844
facsimiletelephonenumber: +1 313 555 9700
telephonenumber: +1 313 555 5331
+
+dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST
+objectclass: OpenLDAPperson
+cn: Fred Bassett
+sn: Bassett
+uid: Bassett, Fred
diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c
index 73bf2a93a7..b2be54ebf9 100644
--- a/source4/lib/ldb/tools/cmdline.c
+++ b/source4/lib/ldb/tools/cmdline.c
@@ -21,23 +21,18 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb.h"
+#include "ldb_module.h"
#include "tools/cmdline.h"
-#if (_SAMBA_BUILD_ >= 4)
-#include "includes.h"
-#include "lib/cmdline/popt_common.h"
-#include "lib/ldb-samba/ldif_handlers.h"
-#include "auth/gensec/gensec.h"
-#include "auth/auth.h"
-#include "ldb_wrap.h"
-#include "param/param.h"
-#endif
-
static struct ldb_cmdline options; /* needs to be static for older compilers */
-static struct poptOption popt_options[] = {
+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" },
@@ -53,51 +48,65 @@ static struct poptOption popt_options[] = {
{ "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 },
- { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },
- { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },
{ 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 },
-#if (_SAMBA_BUILD_ >= 4)
- POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
- POPT_COMMON_CONNECTION
- POPT_COMMON_VERSION
-#endif
+ { "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(const char *cmdname, FILE *f)
+void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f)
{
poptContext pc;
- pc = poptGetContext(cmdname, 0, NULL, popt_options,
+ 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)(void))
+ void (*usage)(struct ldb_context *))
{
struct ldb_cmdline *ret=NULL;
poptContext pc;
-#if (_SAMBA_BUILD_ >= 4)
- int r;
-#endif
int num_options = 0;
int opt;
int flags = 0;
+ int rc;
+ struct poptOption **popt_options;
-#if (_SAMBA_BUILD_ >= 4)
- r = ldb_register_samba_handlers(ldb);
- if (r != 0) {
- goto failed;
- }
-
-#endif
+ /* make the ldb utilities line buffered */
+ setlinebuf(stdout);
ret = talloc_zero(ldb, struct ldb_cmdline);
if (ret == NULL) {
@@ -121,7 +130,16 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
options.scope = LDB_SCOPE_DEFAULT;
- pc = poptGetContext(argv[0], argc, argv, popt_options,
+ 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) {
@@ -159,36 +177,79 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
case 'c': {
const char *cs = poptGetOptArg(pc);
- const char *p, *q;
- int cc;
-
- for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ;
+ const char *p;
- options.controls = talloc_array(ret, char *, cc + 1);
- if (options.controls == NULL) {
- fprintf(stderr, "Out of memory!\n");
- goto failed;
- }
- for (p = cs, cc = 0; p != NULL; cc++) {
- const char *t;
+ for (p = cs; p != NULL; ) {
+ const char *t, *c;
t = strchr(p, ',');
if (t == NULL) {
- options.controls[cc] = talloc_strdup(options.controls, p);
+ c = talloc_strdup(options.controls, p);
p = NULL;
} else {
- options.controls[cc] = talloc_strndup(options.controls, p, t-p);
+ 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;
+ }
}
- options.controls[cc] = NULL;
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();
+ if (usage) usage(ldb);
goto failed;
}
}
@@ -205,7 +266,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
/* 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();
+ if (usage) usage(ldb);
goto failed;
}
@@ -225,27 +286,14 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
flags |= LDB_FLG_ENABLE_TRACING;
}
-#if (_SAMBA_BUILD_ >= 4)
- /* Must be after we have processed command line options */
- gensec_init(cmdline_lp_ctx);
-
- if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb, cmdline_lp_ctx))) {
- goto failed;
- }
- if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {
- goto failed;
- }
- if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) {
- goto failed;
- }
-
- ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
-#endif
-
if (options.modules_path != NULL) {
ldb_set_modules_dir(ldb, options.modules_path);
- } else if (getenv("LDB_MODULES_PATH") != NULL) {
- ldb_set_modules_dir(ldb, getenv("LDB_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 */
@@ -255,11 +303,17 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *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(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
return NULL;
}
@@ -273,8 +327,8 @@ failed:
*/
int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request)
{
- int i, j;
- int ret = 0;
+ unsigned int i, j;
+ int ret = 0;
if (reply == NULL || request == NULL) return -1;
diff --git a/source4/lib/ldb/tools/cmdline.h b/source4/lib/ldb/tools/cmdline.h
index 28061a5a7d..416bf51d22 100644
--- a/source4/lib/ldb/tools/cmdline.h
+++ b/source4/lib/ldb/tools/cmdline.h
@@ -41,17 +41,16 @@ struct ldb_cmdline {
int num_records;
int num_searches;
const char *sasl_mechanism;
- const char *input;
- const char *output;
- char **controls;
+ 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)(void));
+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(const char *cmdname, FILE *f);
+void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f);
diff --git a/source4/lib/ldb/tools/config.mk b/source4/lib/ldb/tools/config.mk
deleted file mode 100644
index 6b57929df0..0000000000
--- a/source4/lib/ldb/tools/config.mk
+++ /dev/null
@@ -1,90 +0,0 @@
-################################################
-# Start SUBSYSTEM LIBLDB_CMDLINE
-[SUBSYSTEM::LIBLDB_CMDLINE]
-CFLAGS = -I$(ldbsrcdir) -I$(ldbsrcdir)/include
-PUBLIC_DEPENDENCIES = LIBLDB LIBPOPT
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL POPT_SAMBA POPT_CREDENTIALS gensec
-# End SUBSYSTEM LIBLDB_CMDLINE
-################################################
-
-LIBLDB_CMDLINE_OBJ_FILES = $(ldbsrcdir)/tools/cmdline.o
-
-################################################
-# Start BINARY ldbadd
-[BINARY::ldbadd]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE LIBCLI_RESOLVE
-# End BINARY ldbadd
-################################################
-
-
-ldbadd_OBJ_FILES = $(ldbsrcdir)/tools/ldbadd.o
-
-MANPAGES += $(ldbsrcdir)/man/ldbadd.1
-
-################################################
-# Start BINARY ldbdel
-[BINARY::ldbdel]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbdel
-################################################
-
-ldbdel_OBJ_FILES = $(ldbsrcdir)/tools/ldbdel.o
-
-MANPAGES += $(ldbsrcdir)/man/ldbdel.1
-
-################################################
-# Start BINARY ldbmodify
-[BINARY::ldbmodify]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbmodify
-################################################
-
-ldbmodify_OBJ_FILES = $(ldbsrcdir)/tools/ldbmodify.o
-MANPAGES += $(ldbsrcdir)/man/ldbmodify.1
-
-################################################
-# Start BINARY ldbsearch
-[BINARY::ldbsearch]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbsearch
-################################################
-
-ldbsearch_OBJ_FILES = $(ldbsrcdir)/tools/ldbsearch.o
-
-MANPAGES += $(ldbsrcdir)/man/ldbsearch.1
-
-################################################
-# Start BINARY ldbedit
-[BINARY::ldbedit]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbedit
-################################################
-
-ldbedit_OBJ_FILES = $(ldbsrcdir)/tools/ldbedit.o
-
-MANPAGES += $(ldbsrcdir)/man/ldbedit.1
-
-################################################
-# Start BINARY ldbrename
-[BINARY::ldbrename]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ldbrename
-################################################
-
-ldbrename_OBJ_FILES = $(ldbsrcdir)/tools/ldbrename.o
-
-MANPAGES += $(ldbsrcdir)/man/ldbrename.1
-
-
diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c
index f022486db8..a5285121c7 100644
--- a/source4/lib/ldb/tools/ldbadd.c
+++ b/source4/lib/ldb/tools/ldbadd.c
@@ -1,4 +1,4 @@
-/*
+/*
ldb database library
Copyright (C) Andrew Tridgell 2004
@@ -6,7 +6,7 @@
** 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
@@ -33,25 +33,33 @@
#include "ldb.h"
#include "tools/cmdline.h"
+#include "ldbutil.h"
-static int failures;
+static unsigned int failures;
+static struct ldb_cmdline *options;
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
- printf("Usage: ldbadd <options> <ldif...>\n");
+ printf("Usage: ldbadd <options> <ldif...>\n");
printf("Adds records to a ldb, reading ldif the specified list of files\n\n");
- ldb_cmdline_help("ldbadd", stdout);
- exit(1);
+ 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, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
+ 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 &&
@@ -60,15 +68,27 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
break;
}
- ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg);
+ 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++;
+ ldb_ldif_read_free(ldb, ldif);
+ continue;
+ }
- ret = ldb_add(ldb, ldif->msg);
+ ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
if (ret != LDB_SUCCESS) {
- fprintf(stderr, "ERR: \"%s\" on DN %s\n",
- ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
+ fprintf(stderr, "ERR: %s : \"%s\" on DN %s\n",
+ ldb_strerror(ret), ldb_errstring(ldb),
+ ldb_dn_get_linearized(ldif->msg->dn));
failures++;
} else {
(*count)++;
+ if (options->verbose) {
+ printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn));
+ }
}
ldb_ldif_read_free(ldb, ldif);
}
@@ -81,16 +101,21 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
- int i, ret=0, count=0;
- struct ldb_cmdline *options;
+ unsigned int i, count = 0;
+ int ret = LDB_SUCCESS;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
- ldb = ldb_init(NULL, NULL);
+ ldb = ldb_init(mem_ctx, NULL);
+ if (ldb == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
options = ldb_cmdline_process(ldb, argc, argv, usage);
- if (ldb_transaction_start(ldb) != 0) {
+ ret = ldb_transaction_start(ldb);
+ if (ret != LDB_SUCCESS) {
printf("Failed to start transaction: %s\n", ldb_errstring(ldb));
- exit(1);
+ return ret;
}
if (options->argc == 0) {
@@ -102,7 +127,7 @@ int main(int argc, const char **argv)
f = fopen(fname, "r");
if (!f) {
perror(fname);
- exit(1);
+ return LDB_ERR_OPERATIONS_ERROR;
}
ret = process_file(ldb, f, &count);
fclose(f);
@@ -110,17 +135,18 @@ int main(int argc, const char **argv)
}
if (count != 0) {
- if (ldb_transaction_commit(ldb) != 0) {
+ ret = ldb_transaction_commit(ldb);
+ if (ret != LDB_SUCCESS) {
printf("Failed to commit transaction: %s\n", ldb_errstring(ldb));
- exit(1);
+ return ret;
}
} else {
ldb_transaction_cancel(ldb);
}
- talloc_free(ldb);
+ talloc_free(mem_ctx);
+
+ printf("Added %u records with %u failures\n", count, failures);
- printf("Added %d records with %d failures\n", count, failures);
-
return ret;
}
diff --git a/source4/lib/ldb/tools/ldbdel.c b/source4/lib/ldb/tools/ldbdel.c
index ddf168d574..8036d09a70 100644
--- a/source4/lib/ldb/tools/ldbdel.c
+++ b/source4/lib/ldb/tools/ldbdel.c
@@ -31,80 +31,105 @@
* Author: Andrew Tridgell
*/
+#include "replace.h"
#include "ldb.h"
#include "tools/cmdline.h"
+#include "ldbutil.h"
-static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn)
+static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2)
{
- int ret, i, total=0;
+ 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 -1;
+ 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(ldb, res->msgs[i]->dn) == 0) {
+ 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 -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- printf("Deleted %d records\n", total);
- return 0;
+ printf("Deleted %u records\n", total);
+ return LDB_SUCCESS;
}
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbdel <options> <DN...>\n");
printf("Deletes records from a ldb\n\n");
- ldb_cmdline_help("ldbdel", stdout);
- exit(1);
+ 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;
- struct ldb_cmdline *options;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
- ldb = ldb_init(NULL, 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();
- exit(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;i<options->argc;i++) {
struct ldb_dn *dn;
dn = ldb_dn_new(ldb, ldb, options->argv[i]);
- if ( ! ldb_dn_validate(dn)) {
- printf("Invalid DN format\n");
- exit(1);
+ if (dn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (options->recursive) {
- ret = ldb_delete_recursive(ldb, dn);
+ ret = ldb_delete_recursive(ldb, dn,req_ctrls);
} else {
- ret = ldb_delete(ldb, dn);
- if (ret == 0) {
+ ret = ldb_delete_ctrl(ldb, dn,req_ctrls);
+ if (ret == LDB_SUCCESS) {
printf("Deleted 1 record\n");
}
}
- if (ret != 0) {
- printf("delete of '%s' failed - %s\n",
- ldb_dn_get_linearized(dn),
- ldb_errstring(ldb));
+ 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(ldb);
+ talloc_free(mem_ctx);
return ret;
}
diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c
index ecadf0f61c..36d054e563 100644
--- a/source4/lib/ldb/tools/ldbedit.c
+++ b/source4/lib/ldb/tools/ldbedit.c
@@ -1,4 +1,4 @@
-/*
+/*
ldb database library
Copyright (C) Andrew Tridgell 2004
@@ -6,7 +6,7 @@
** 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
@@ -30,17 +30,22 @@
*
* Author: Andrew Tridgell
*/
-#include "ldb_includes.h"
+
+#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
+ debug routine
*/
-static void ldif_write_msg(struct ldb_context *ldb,
- FILE *f,
+static void ldif_write_msg(struct ldb_context *ldb,
+ FILE *f,
enum ldb_changetype changetype,
struct ldb_message *msg)
{
@@ -54,33 +59,38 @@ static void ldif_write_msg(struct ldb_context *ldb,
modify a database record so msg1 becomes msg2
returns the number of modified elements
*/
-static int modify_record(struct ldb_context *ldb,
+static int modify_record(struct ldb_context *ldb,
struct ldb_message *msg1,
- struct ldb_message *msg2)
+ struct ldb_message *msg2,
+ struct ldb_control **req_ctrls)
{
+ int ret;
struct ldb_message *mod;
- mod = ldb_msg_diff(ldb, msg1, msg2);
- if (mod == NULL) {
+ if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) {
fprintf(stderr, "Failed to calculate message differences\n");
return -1;
}
- if (mod->num_elements == 0) {
- return 0;
+ 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(ldb, mod) != 0) {
- fprintf(stderr, "failed to modify %s - %s\n",
+ 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));
- return -1;
+ ret = -1;
+ goto done;
}
- return mod->num_elements;
+done:
+ talloc_free(mod);
+ return ret;
}
/*
@@ -88,10 +98,10 @@ static int modify_record(struct ldb_context *ldb,
*/
static struct ldb_message *msg_find(struct ldb_context *ldb,
struct ldb_message **msgs,
- int count,
+ unsigned int count,
struct ldb_dn *dn)
{
- int i;
+ unsigned int i;
for (i=0;i<count;i++) {
if (ldb_dn_compare(dn, msgs[i]->dn) == 0) {
return msgs[i];
@@ -104,15 +114,20 @@ static struct ldb_message *msg_find(struct ldb_context *ldb,
merge the changes in msgs2 into the messages from msgs1
*/
static int merge_edits(struct ldb_context *ldb,
- struct ldb_message **msgs1, int count1,
- struct ldb_message **msgs2, int count2)
+ struct ldb_message **msgs1, unsigned int count1,
+ struct ldb_message **msgs2, unsigned int count2)
{
- int i;
+ unsigned int i;
struct ldb_message *msg;
- int ret = 0;
- int adds=0, modifies=0, deletes=0;
+ 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) != 0) {
+ if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb));
return -1;
}
@@ -124,7 +139,7 @@ static int merge_edits(struct ldb_context *ldb,
if (options->verbose > 0) {
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]);
}
- if (ldb_add(ldb, msgs2[i]) != 0) {
+ 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));
@@ -133,8 +148,11 @@ static int merge_edits(struct ldb_context *ldb,
}
adds++;
} else {
- if (modify_record(ldb, msg, msgs2[i]) > 0) {
- modifies++;
+ ret = modify_record(ldb, msg, msgs2[i], req_ctrls);
+ if (ret != -1) {
+ modifies += (unsigned int) ret;
+ } else {
+ return -1;
}
}
}
@@ -146,7 +164,7 @@ static int merge_edits(struct ldb_context *ldb,
if (options->verbose > 0) {
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]);
}
- if (ldb_delete(ldb, msgs1[i]->dn) != 0) {
+ 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));
@@ -157,29 +175,29 @@ static int merge_edits(struct ldb_context *ldb,
}
}
- if (ldb_transaction_commit(ldb) != 0) {
+ if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb));
return -1;
}
- printf("# %d adds %d modifies %d deletes\n", adds, modifies, deletes);
+ printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes);
- return ret;
+ 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, int count)
+static int save_ldif(struct ldb_context *ldb,
+ FILE *f, struct ldb_message **msgs, unsigned int count)
{
- int i;
+ unsigned int i;
- fprintf(f, "# editing %d records\n", count);
+ fprintf(f, "# editing %u records\n", count);
for (i=0;i<count;i++) {
struct ldb_ldif ldif;
- fprintf(f, "# record %d\n", i+1);
+ fprintf(f, "# record %u\n", i+1);
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msgs[i];
@@ -194,8 +212,8 @@ static int save_ldif(struct ldb_context *ldb,
/*
edit the ldb search results in msgs using the user selected editor
*/
-static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int count1,
- const char *editor)
+static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1,
+ unsigned int count1, const char *editor)
{
int fd, ret;
FILE *f;
@@ -203,7 +221,7 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun
char *cmd;
struct ldb_ldif *ldif;
struct ldb_message **msgs2 = NULL;
- int count2 = 0;
+ unsigned int count2 = 0;
/* write out the original set of messages to a temporary
file */
@@ -269,11 +287,11 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun
return merge_edits(ldb, msgs1, count1, msgs2, count2);
}
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbedit <options> <expression> <attributes ...>\n");
- ldb_cmdline_help("ldbedit", stdout);
- exit(1);
+ ldb_cmdline_help(ldb, "ldbedit", stdout);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
int main(int argc, const char **argv)
@@ -284,13 +302,18 @@ int main(int argc, const char **argv)
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(NULL, 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->argc > 0 &&
+ if (options->argc > 0 &&
strchr(options->argv[0], '=')) {
expression = options->argv[0];
options->argv++;
@@ -303,33 +326,32 @@ int main(int argc, const char **argv)
if (options->basedn != NULL) {
basedn = ldb_dn_new(ldb, ldb, options->basedn);
- if ( ! ldb_dn_validate(basedn)) {
- printf("Invalid Base DN format\n");
- exit(1);
+ if (basedn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
}
- ret = ldb_search(ldb, ldb, &result, basedn, options->scope, attrs, "%s", expression);
+ 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));
- exit(1);
+ return ret;
}
if (result->count == 0) {
printf("no matching records - cannot edit\n");
- return 0;
+ talloc_free(mem_ctx);
+ return LDB_SUCCESS;
}
- do_edit(ldb, result->msgs, result->count, options->editor);
+ ret = do_edit(ldb, result->msgs, result->count, options->editor);
- if (result) {
- ret = talloc_free(result);
- if (ret == -1) {
- fprintf(stderr, "talloc_free failed\n");
- exit(1);
- }
- }
+ talloc_free(mem_ctx);
- talloc_free(ldb);
- return 0;
+ 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
index d0bca0479b..1484bbf655 100644
--- a/source4/lib/ldb/tools/ldbmodify.c
+++ b/source4/lib/ldb/tools/ldbmodify.c
@@ -33,44 +33,56 @@
#include "ldb.h"
#include "tools/cmdline.h"
+#include "ldbutil.h"
-static int failures;
+static unsigned int failures;
+static struct ldb_cmdline *options;
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbmodify <options> <ldif...>\n");
printf("Modifies a ldb based upon ldif change records\n\n");
- ldb_cmdline_help("ldbmodify", stdout);
- exit(1);
+ 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, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
-
+ 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))) {
switch (ldif->changetype) {
case LDB_CHANGETYPE_NONE:
case LDB_CHANGETYPE_ADD:
- ret = ldb_add(ldb, ldif->msg);
+ ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
break;
case LDB_CHANGETYPE_DELETE:
- ret = ldb_delete(ldb, ldif->msg->dn);
+ ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls);
break;
case LDB_CHANGETYPE_MODIFY:
- ret = ldb_modify(ldb, ldif->msg);
+ ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls);
break;
}
if (ret != LDB_SUCCESS) {
- fprintf(stderr, "ERR: \"%s\" on DN %s\n",
+ fprintf(stderr, "ERR: (%s) \"%s\" on DN %s\n",
+ ldb_strerror(ret),
ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
failures++;
} else {
(*count)++;
+ if (options->verbose) {
+ printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn));
+ }
}
ldb_ldif_read_free(ldb, ldif);
}
@@ -81,11 +93,14 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
- int count=0;
- int i, ret=LDB_SUCCESS;
- struct ldb_cmdline *options;
+ unsigned int i, count = 0;
+ int ret = LDB_SUCCESS;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
- ldb = ldb_init(NULL, NULL);
+ ldb = ldb_init(mem_ctx, NULL);
+ if (ldb == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
options = ldb_cmdline_process(ldb, argc, argv, usage);
@@ -98,16 +113,16 @@ int main(int argc, const char **argv)
f = fopen(fname, "r");
if (!f) {
perror(fname);
- exit(1);
+ return LDB_ERR_OPERATIONS_ERROR;
}
ret = process_file(ldb, f, &count);
fclose(f);
}
}
- talloc_free(ldb);
+ talloc_free(mem_ctx);
- printf("Modified %d records with %d failures\n", count, failures);
+ 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
index fcae766a20..9bbd1f06b1 100644
--- a/source4/lib/ldb/tools/ldbrename.c
+++ b/source4/lib/ldb/tools/ldbrename.c
@@ -36,12 +36,12 @@
#include "ldb.h"
#include "tools/cmdline.h"
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbrename [<options>] <olddn> <newdn>\n");
printf("Renames records in a ldb\n\n");
- ldb_cmdline_help("ldbmodify", stdout);
- exit(1);
+ ldb_cmdline_help(ldb, "ldbmodify", stdout);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
@@ -51,36 +51,34 @@ int main(int argc, const char **argv)
int ret;
struct ldb_cmdline *options;
struct ldb_dn *dn1, *dn2;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
- ldb = ldb_init(NULL, 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();
+ usage(ldb);
}
dn1 = ldb_dn_new(ldb, ldb, options->argv[0]);
dn2 = ldb_dn_new(ldb, ldb, options->argv[1]);
-
- if ( ! ldb_dn_validate(dn1)) {
- printf("Invalid DN1: %s\n", options->argv[0]);
- return -1;
- }
- if ( ! ldb_dn_validate(dn2)) {
- printf("Invalid DN2: %s\n", options->argv[1]);
- return -1;
+ if ((dn1 == NULL) || (dn2 == NULL)) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
ret = ldb_rename(ldb, dn1, dn2);
- if (ret == 0) {
+ 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(ldb);
+ talloc_free(mem_ctx);
return ret;
}
diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c
index 8f7ee1ce38..d10b9650da 100644
--- a/source4/lib/ldb/tools/ldbsearch.c
+++ b/source4/lib/ldb/tools/ldbsearch.c
@@ -31,15 +31,17 @@
* Author: Andrew Tridgell
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb.h"
#include "tools/cmdline.h"
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbsearch <options> <expression> <attrs...>\n");
- ldb_cmdline_help("ldbsearch", stdout);
- exit(1);
+ ldb_cmdline_help(ldb, "ldbsearch", stdout);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
static int do_compare_msg(struct ldb_message **el1,
@@ -54,15 +56,15 @@ struct search_context {
struct ldb_control **req_ctrls;
int sort;
- int num_stored;
+ unsigned int num_stored;
struct ldb_message **store;
- int refs_stored;
+ unsigned int refs_stored;
char **refs_store;
- int entries;
- int refs;
+ unsigned int entries;
+ unsigned int refs;
- int pending;
+ unsigned int pending;
int status;
};
@@ -131,7 +133,7 @@ static int display_referral(char *referral, struct search_context *sctx)
static int search_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct search_context *sctx;
- int ret;
+ int ret = LDB_SUCCESS;
sctx = talloc_get_type(req->context, struct search_context);
@@ -172,7 +174,7 @@ static int search_callback(struct ldb_request *req, struct ldb_reply *ares)
}
talloc_free(ares);
- if (ret) {
+ if (ret != LDB_SUCCESS) {
return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
}
@@ -191,21 +193,16 @@ static int do_search(struct ldb_context *ldb,
req = NULL;
- sctx = talloc(ldb, struct search_context);
- if (!sctx) return -1;
+ sctx = talloc_zero(ldb, struct search_context);
+ if (!sctx) return LDB_ERR_OPERATIONS_ERROR;
sctx->ldb = ldb;
sctx->sort = options->sorted;
- sctx->num_stored = 0;
- sctx->refs_stored = 0;
- sctx->store = NULL;
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 -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- sctx->entries = 0;
- sctx->refs = 0;
if (basedn == NULL) {
basedn = ldb_get_default_basedn(ldb);
@@ -224,7 +221,7 @@ again:
if (ret != LDB_SUCCESS) {
talloc_free(sctx);
printf("allocating request failed: %s\n", ldb_errstring(ldb));
- return -1;
+ return ret;
}
sctx->pending = 0;
@@ -232,24 +229,23 @@ again:
ret = ldb_request(ldb, req);
if (ret != LDB_SUCCESS) {
printf("search failed - %s\n", ldb_errstring(ldb));
- return -1;
+ return ret;
}
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
printf("search error - %s\n", ldb_errstring(ldb));
- return -1;
+ return ret;
}
if (sctx->pending)
goto again;
if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) {
- int i;
+ unsigned int i;
if (sctx->num_stored) {
- ldb_qsort(sctx->store, sctx->num_stored, sizeof(struct ldb_message *),
- ldb, (ldb_qsort_cmp_fn_t)do_compare_msg);
+ 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);
@@ -260,13 +256,13 @@ again:
}
}
- printf("# returned %d records\n# %d entries\n# %d referrals\n",
+ 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 0;
+ return LDB_SUCCESS;
}
int main(int argc, const char **argv)
@@ -277,10 +273,11 @@ int main(int argc, const char **argv)
struct ldb_cmdline *options;
int ret = -1;
const char *expression = "(|(objectClass=*)(distinguishedName=*))";
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
- ldb = ldb_init(NULL, NULL);
+ ldb = ldb_init(mem_ctx, NULL);
if (ldb == NULL) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
options = ldb_cmdline_process(ldb, argc, argv, usage);
@@ -300,23 +297,21 @@ int main(int argc, const char **argv)
if (options->basedn != NULL) {
basedn = ldb_dn_new(ldb, ldb, options->basedn);
- if ( ! ldb_dn_validate(basedn)) {
- fprintf(stderr, "Invalid Base DN format\n");
- exit(1);
+ if (basedn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
}
if (options->interactive) {
char line[1024];
while (fgets(line, sizeof(line), stdin)) {
- if (do_search(ldb, basedn, options, line, attrs) == -1) {
- ret = -1;
- }
+ ret = do_search(ldb, basedn, options, line, attrs);
}
} else {
ret = do_search(ldb, basedn, options, expression, attrs);
}
- talloc_free(ldb);
+ talloc_free(mem_ctx);
+
return ret;
}
diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c
index 6af0ee9336..a9d8fafe81 100644
--- a/source4/lib/ldb/tools/ldbtest.c
+++ b/source4/lib/ldb/tools/ldbtest.c
@@ -31,36 +31,42 @@
* Author: Andrew Tridgell
*/
-#include "ldb_includes.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/time.h"
#include "ldb.h"
#include "tools/cmdline.h"
-static struct timeval tp1,tp2;
+static struct timespec tp1,tp2;
static struct ldb_cmdline *options;
static void _start_timer(void)
{
- gettimeofday(&tp1,NULL);
+ if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) {
+ clock_gettime(CLOCK_REALTIME, &tp1);
+ }
}
static double _end_timer(void)
{
- gettimeofday(&tp2,NULL);
+ if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) {
+ clock_gettime(CLOCK_REALTIME, &tp2);
+ }
return((tp2.tv_sec - tp1.tv_sec) +
- (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+ (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9);
}
static void add_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
- int count)
+ unsigned int count)
{
struct ldb_message msg;
- int i;
+ unsigned int i;
#if 0
if (ldb_lock(ldb, "transaction") != 0) {
printf("transaction lock failed\n");
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
#endif
for (i=0;i<count;i++) {
@@ -122,7 +128,7 @@ static void add_records(struct ldb_context *ldb,
if (ldb_add(ldb, &msg) != 0) {
printf("Add of %s failed - %s\n", name, ldb_errstring(ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
printf("adding uid %s\r", name);
@@ -133,7 +139,7 @@ static void add_records(struct ldb_context *ldb,
#if 0
if (ldb_unlock(ldb, "transaction") != 0) {
printf("transaction unlock failed\n");
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
#endif
printf("\n");
@@ -141,10 +147,10 @@ static void add_records(struct ldb_context *ldb,
static void modify_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
- int count)
+ unsigned int count)
{
struct ldb_message msg;
- int i;
+ unsigned int i;
for (i=0;i<count;i++) {
struct ldb_message_element el[3];
@@ -179,7 +185,7 @@ static void modify_records(struct ldb_context *ldb,
if (ldb_modify(ldb, &msg) != 0) {
printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
printf("Modifying uid %s\r", name);
@@ -194,9 +200,9 @@ static void modify_records(struct ldb_context *ldb,
static void delete_records(struct ldb_context *ldb,
struct ldb_dn *basedn,
- int count)
+ unsigned int count)
{
- int i;
+ unsigned int i;
for (i=0;i<count;i++) {
struct ldb_dn *dn;
@@ -209,7 +215,7 @@ static void delete_records(struct ldb_context *ldb,
if (ldb_delete(ldb, dn) != 0) {
printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
talloc_free(name);
}
@@ -217,9 +223,10 @@ static void delete_records(struct ldb_context *ldb,
printf("\n");
}
-static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches)
+static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn,
+ unsigned int nrecords, unsigned int nsearches)
{
- int i;
+ unsigned int i;
for (i=0;i<nsearches;i++) {
int uid = (i * 700 + 17) % (nrecords * 2);
@@ -232,15 +239,15 @@ static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nreco
if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) {
printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
if (uid >= nrecords && res->count > 0) {
printf("Found %s !? - %d\n", expr, ret);
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
- printf("testing uid %d/%d - %d \r", i, uid, res->count);
+ printf("Testing uid %d/%d - %d \r", i, uid, res->count);
fflush(stdout);
talloc_free(res);
@@ -250,14 +257,15 @@ static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nreco
printf("\n");
}
-static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
+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\n");
- exit(1);
+ printf("Invalid base DN format\n");
+ exit(LDB_ERR_INVALID_DN_SYNTAX);
}
printf("Adding %d records\n", nrecords);
@@ -322,7 +330,7 @@ static void start_test_index(struct ldb_context **ldb)
if (ldb_add(*ldb, msg) != 0) {
printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
@@ -337,12 +345,12 @@ static void start_test_index(struct ldb_context **ldb)
if (ldb_add(*ldb, msg) != 0) {
printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
if (talloc_free(*ldb) != 0) {
printf("failed to free/close ldb database");
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
(*ldb) = ldb_init(options, NULL);
@@ -350,19 +358,21 @@ static void start_test_index(struct ldb_context **ldb)
ret = ldb_connect(*ldb, options->url, flags, NULL);
if (ret != 0) {
printf("failed to connect to %s\n", options->url);
- exit(1);
+ 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(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
if(res->count != 1) {
printf("Should have found 1 record - found %d\n", res->count);
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
@@ -370,14 +380,14 @@ static void start_test_index(struct ldb_context **ldb)
if (ldb_delete(*ldb, msg->dn) != 0 ||
ldb_delete(*ldb, indexlist) != 0) {
printf("cleanup failed - %s\n", ldb_errstring(*ldb));
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
printf("Finished index test\n");
}
-static void usage(void)
+static void usage(struct ldb_context *ldb)
{
printf("Usage: ldbtest <options>\n");
printf("Options:\n");
@@ -386,7 +396,7 @@ static void usage(void)
printf(" --num-searches nsearches number of searches to do\n");
printf("\n");
printf("tests ldb API\n\n");
- exit(1);
+ exit(LDB_ERR_OPERATIONS_ERROR);
}
int main(int argc, const char **argv)
@@ -395,6 +405,9 @@ int main(int argc, const char **argv)
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);
@@ -409,11 +422,13 @@ int main(int argc, const char **argv)
printf("Testing with num-records=%d and num-searches=%d\n",
options->num_records, options->num_searches);
- start_test(ldb, 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 0;
+ return LDB_SUCCESS;
}
diff --git a/source4/lib/ldb/tools/ldbutil.c b/source4/lib/ldb/tools/ldbutil.c
new file mode 100644
index 0000000000..26f252704c
--- /dev/null
+++ b/source4/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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * 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
new file mode 100644
index 0000000000..f8d3f3a210
--- /dev/null
+++ b/source4/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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * 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
index 26dd344527..7f50cdc63a 100644
--- a/source4/lib/ldb/web/index.html
+++ b/source4/lib/ldb/web/index.html
@@ -50,31 +50,19 @@ would be preferred.
<h2>Discussion and bug reports</h2>
-ldb does not currently have its own mailing list or bug tracking
-system. For now, please use the <a
-href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>
-mailing list or the <a href="https://lists.samba.org/mailman/listinfo/ldb">ldb</a>
-mailing list, and the <a href="http://bugzilla.samba.org/">Samba bugzilla</a> bug tracking system.
+ldb does not have its own mailing list or bug tracking system. Please
+use
+the <a href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>
+mailing list, and the <a href="http://bugzilla.samba.org/">Samba
+bugzilla</a> bug tracking system.
<h2>Download</h2>
-You can download the latest release either via rsync or thtough git.<br>
-<br>
-To fetch via git see the following guide:<br>
+You can download the latest release here:<br>
+ <a href="http://samba.org/ftp/pub/ldb">http://samba.org/ftp/pub/ldb</a>
+
+Alternatively, you can fetch via git. See the following guide:<br>
<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br>
-Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/ldb directory.<br>
-<br>
-To fetch via rsync use these commands:
-
-<pre>
- rsync -Pavz samba.org::ftp/unpacked/ldb .
- rsync -Pavz samba.org::ftp/unpacked/tdb .
- rsync -Pavz samba.org::ftp/unpacked/talloc .
- rsync -Pavz samba.org::ftp/unpacked/libreplace .
-</pre>
-
-and build in ldb. It will find the other libraries in the directory
-above automatically.
<hr>
<tiny>
diff --git a/source4/lib/ldb/wscript b/source4/lib/ldb/wscript
new file mode 100755
index 0000000000..df08f8753d
--- /dev/null
+++ b/source4/lib/ldb/wscript
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+
+APPNAME = 'ldb'
+VERSION = '1.0.2'
+
+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/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')
+ opt.RECURSE('lib/tevent')
+ opt.RECURSE('lib/replace')
+
+def configure(conf):
+ conf.RECURSE('lib/tdb')
+ conf.RECURSE('lib/tevent')
+ conf.RECURSE('lib/popt')
+ conf.RECURSE('lib/replace')
+
+ # 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')
+ bld.RECURSE('lib/tevent')
+ bld.RECURSE('lib/popt')
+ bld.RECURSE('lib/replace')
+
+ 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 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',
+ 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/lib/ldb_wrap.c b/source4/lib/ldb_wrap.c
deleted file mode 100644
index 74502afde2..0000000000
--- a/source4/lib/ldb_wrap.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- LDB wrap functions
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-/*
- 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 "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
-#include "lib/ldb-samba/ldif_handlers.h"
-#include "ldb_wrap.h"
-#include "dsdb/samdb/samdb.h"
-#include "param/param.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);
-}
-
-/* check for memory leaks on the ldb context */
-static int ldb_wrap_destructor(struct ldb_context *ldb)
-{
- size_t *startup_blocks = (size_t *)ldb_get_opaque(ldb, "startup_blocks");
-
- if (startup_blocks &&
- talloc_total_blocks(ldb) > *startup_blocks + 400) {
- DEBUG(0,("WARNING: probable memory leak in ldb %s - %lu blocks (startup %lu) %lu bytes\n",
- (char *)ldb_get_opaque(ldb, "wrap_url"),
- (unsigned long)talloc_total_blocks(ldb),
- (unsigned long)*startup_blocks,
- (unsigned long)talloc_total_size(ldb)));
-#if 0
- talloc_report_full(ldb, stdout);
- call_backtrace();
- smb_panic("probable memory leak in ldb");
-#endif
- }
- return 0;
-}
-
-/*
- 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,
- const char *options[])
-{
- struct ldb_context *ldb;
- int ret;
- char *real_url = NULL;
- size_t *startup_blocks;
-
- /* we want to use the existing event context if possible. This
- relies on the fact that in smbd, everything is a child of
- the main event_context */
- if (ev == NULL) {
- return NULL;
- }
-
- ldb = ldb_init(mem_ctx, ev);
- if (ldb == NULL) {
- return NULL;
- }
-
- ldb_set_modules_dir(ldb,
- talloc_asprintf(ldb,
- "%s/ldb",
- lp_modulesdir(lp_ctx)));
-
- if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
- talloc_free(ldb);
- return NULL;
- }
-
- 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 == -1) {
- talloc_free(ldb);
- return NULL;
- }
-
- if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) {
- dsdb_set_global_schema(ldb);
- }
-
- ldb_set_debug(ldb, ldb_wrap_debug, NULL);
-
- ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
-
- real_url = private_path(ldb, lp_ctx, url);
- if (real_url == NULL) {
- talloc_free(ldb);
- return NULL;
- }
-
- /* allow admins to force non-sync ldb for all databases */
- if (lp_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) {
- flags |= LDB_FLG_NOSYNC;
- }
-
- if (DEBUGLVL(10)) {
- flags |= LDB_FLG_ENABLE_TRACING;
- }
-
- /* 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);
-
- ret = ldb_connect(ldb, real_url, flags, options);
- if (ret != LDB_SUCCESS) {
- talloc_free(ldb);
- return NULL;
- }
-
- /* setup for leak detection */
- ldb_set_opaque(ldb, "wrap_url", real_url);
- startup_blocks = talloc(ldb, size_t);
- *startup_blocks = talloc_total_blocks(ldb);
- ldb_set_opaque(ldb, "startup_blocks", startup_blocks);
-
- talloc_set_destructor(ldb, ldb_wrap_destructor);
-
- return ldb;
-}
diff --git a/source4/lib/messaging/config.mk b/source4/lib/messaging/config.mk
deleted file mode 100644
index 1cdbbc6d76..0000000000
--- a/source4/lib/messaging/config.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-[SUBSYSTEM::MESSAGING]
-PUBLIC_DEPENDENCIES = \
- LIBSAMBA-UTIL \
- TDB_WRAP \
- NDR_IRPC \
- UNIX_PRIVS \
- UTIL_TDB \
- CLUSTER \
- LIBNDR \
- samba_socket
-
-MESSAGING_OBJ_FILES = $(libmessagingsrcdir)/messaging.o
-
-[PYTHON::python_messaging]
-LIBRARY_REALNAME = samba/messaging.$(SHLIBEXT)
-PRIVATE_DEPENDENCIES = MESSAGING LIBEVENTS python_irpc pyparam_util
-
-python_messaging_OBJ_FILES = $(libmessagingsrcdir)/pymessaging.o
diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h
index c82ad398ff..bdb1b8fedb 100644
--- a/source4/lib/messaging/irpc.h
+++ b/source4/lib/messaging/irpc.h
@@ -24,7 +24,6 @@
#include "lib/messaging/messaging.h"
#include "librpc/gen_ndr/irpc.h"
-#include "librpc/gen_ndr/server_id.h"
/*
an incoming irpc message
@@ -35,6 +34,7 @@ struct irpc_message {
struct irpc_header header;
struct ndr_pull *ndr;
bool defer_reply;
+ bool no_reply;
struct messaging_context *msg_ctx;
struct irpc_list *irpc;
void *data;
@@ -42,7 +42,9 @@ struct irpc_message {
};
/* don't allow calls to take too long */
-#define IRPC_CALL_TIMEOUT 10
+#define IRPC_CALL_TIMEOUT 10
+/* wait for the calls as long as it takes */
+#define IRPC_CALL_TIMEOUT_INF 0
/* the server function type */
@@ -54,80 +56,27 @@ typedef NTSTATUS (*irpc_function_t)(struct irpc_message *, void *r);
NDR_ ## funcname, \
(irpc_function_t)function, private_data)
-/* make a irpc call */
-#define IRPC_CALL(msg_ctx, server_id, pipename, funcname, ptr, ctx) \
- irpc_call(msg_ctx, server_id, &ndr_table_ ## pipename, NDR_ ## funcname, ptr, ctx)
-
-#define IRPC_CALL_SEND(msg_ctx, server_id, pipename, funcname, ptr, ctx) \
- irpc_call_send(msg_ctx, server_id, &ndr_table_ ## pipename, NDR_ ## funcname, ptr, ctx)
-
-
-/*
- a pending irpc call
-*/
-struct irpc_request {
- struct messaging_context *msg_ctx;
- const struct ndr_interface_table *table;
- int callnum;
- int callid;
- void *r;
- NTSTATUS status;
- bool done;
- bool reject_free;
- TALLOC_CTX *mem_ctx;
- struct {
- void (*fn)(struct irpc_request *);
- void *private_data;
- } async;
-};
-
-struct loadparm_context;
-
-typedef void (*msg_callback_t)(struct messaging_context *msg, void *private_data,
- uint32_t msg_type,
- struct server_id server_id, DATA_BLOB *data);
-
-NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server,
- uint32_t msg_type, DATA_BLOB *data);
-NTSTATUS messaging_register(struct messaging_context *msg, void *private_data,
- uint32_t msg_type,
- msg_callback_t fn);
-NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data,
- msg_callback_t fn, uint32_t *msg_type);
-struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
- const char *dir,
- struct server_id server_id,
- struct smb_iconv_convenience *iconv_convenience,
- struct tevent_context *ev);
-struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx,
- const char *dir,
- struct smb_iconv_convenience *iconv_convenience,
- struct tevent_context *ev);
-NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server,
- uint32_t msg_type, void *ptr);
-void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data);
-
-
-
+struct ndr_interface_table;
NTSTATUS irpc_register(struct messaging_context *msg_ctx,
const struct ndr_interface_table *table,
int call, irpc_function_t fn, void *private_data);
-struct irpc_request *irpc_call_send(struct messaging_context *msg_ctx,
- struct server_id server_id,
- const struct ndr_interface_table *table,
- int callnum, void *r, TALLOC_CTX *ctx);
-NTSTATUS irpc_call_recv(struct irpc_request *irpc);
-NTSTATUS irpc_call(struct messaging_context *msg_ctx,
- struct server_id server_id,
- const struct ndr_interface_table *table,
- int callnum, void *r, TALLOC_CTX *ctx);
+
+struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ struct server_id server_id,
+ const struct ndr_interface_table *table);
+struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ const char *dest_task,
+ const struct ndr_interface_table *table);
+void irpc_binding_handle_add_security_token(struct dcerpc_binding_handle *h,
+ struct security_token *token);
NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name);
struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx, const char *name);
void irpc_remove_name(struct messaging_context *msg_ctx, const char *name);
NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status);
-struct server_id messaging_get_server_id(struct messaging_context *msg_ctx);
#endif
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 277688e8b6..a716e9daa4 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -27,16 +27,29 @@
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_irpc.h"
#include "lib/messaging/irpc.h"
-#include "tdb_wrap.h"
+#include "lib/util/tdb_wrap.h"
#include "../lib/util/unix_privs.h"
#include "librpc/rpc/dcerpc.h"
-#include "../tdb/include/tdb.h"
+#include <tdb.h>
#include "../lib/util/util_tdb.h"
#include "cluster/cluster.h"
+#include "../lib/util/tevent_ntstatus.h"
/* change the message version with any incompatible changes in the protocol */
#define MESSAGING_VERSION 1
+/*
+ a pending irpc call
+*/
+struct irpc_request {
+ struct messaging_context *msg_ctx;
+ int callid;
+ struct {
+ void (*handler)(struct irpc_request *irpc, struct irpc_message *m);
+ void *private_data;
+ } incoming;
+};
+
struct messaging_context {
struct server_id server_id;
struct socket_context *sock;
@@ -47,7 +60,6 @@ struct messaging_context {
struct idr_context *dispatch_tree;
struct messaging_rec *pending;
struct messaging_rec *retry_queue;
- struct smb_iconv_convenience *iconv_convenience;
struct irpc_list *irpc;
struct idr_context *idr;
const char **names;
@@ -98,7 +110,7 @@ static void ping_message(struct messaging_context *msg, void *private_data,
uint32_t msg_type, struct server_id src, DATA_BLOB *data)
{
DEBUG(1,("INFO: Received PING message from server %u.%u [%.*s]\n",
- (uint_t)src.node, (uint_t)src.id, (int)data->length,
+ (unsigned int)src.node, (unsigned int)src.id, (int)data->length,
data->data?(const char *)data->data:""));
messaging_send(msg, src, MSG_PONG, data);
}
@@ -119,8 +131,15 @@ static NTSTATUS irpc_uptime(struct irpc_message *msg,
*/
static char *messaging_path(struct messaging_context *msg, struct server_id server_id)
{
- return talloc_asprintf(msg, "%s/msg.%s", msg->base_path,
- cluster_id_string(msg, server_id));
+ TALLOC_CTX *tmp_ctx = talloc_new(msg);
+ const char *id = cluster_id_string(tmp_ctx, server_id);
+ char *s;
+ if (id == NULL) {
+ return NULL;
+ }
+ s = talloc_asprintf(msg, "%s/msg.%s", msg->base_path, id);
+ talloc_steal(s, tmp_ctx);
+ return s;
}
/*
@@ -261,11 +280,13 @@ static void messaging_send_handler(struct messaging_context *msg)
}
rec->retries = 0;
if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_CTX *tmp_ctx = talloc_new(msg);
DEBUG(1,("messaging: Lost message from %s to %s of type %u - %s\n",
- cluster_id_string(debug_ctx(), rec->header->from),
- cluster_id_string(debug_ctx(), rec->header->to),
+ cluster_id_string(tmp_ctx, rec->header->from),
+ cluster_id_string(tmp_ctx, rec->header->to),
rec->header->msg_type,
nt_errstr(status)));
+ talloc_free(tmp_ctx);
}
DLIST_REMOVE(msg->pending, rec);
talloc_free(rec);
@@ -440,7 +461,7 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void
Send a message to a particular server
*/
NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server,
- uint32_t msg_type, DATA_BLOB *data)
+ uint32_t msg_type, const DATA_BLOB *data)
{
struct messaging_rec *rec;
NTSTATUS status;
@@ -535,7 +556,6 @@ static int messaging_destructor(struct messaging_context *msg)
struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
const char *dir,
struct server_id server_id,
- struct smb_iconv_convenience *iconv_convenience,
struct tevent_context *ev)
{
struct messaging_context *msg;
@@ -564,7 +584,6 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
msg->base_path = talloc_reference(msg, dir);
msg->path = messaging_path(msg, server_id);
msg->server_id = server_id;
- msg->iconv_convenience = iconv_convenience;
msg->idr = idr_init(msg);
msg->dispatch_tree = idr_init(msg);
msg->start_time = timeval_current();
@@ -599,6 +618,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
msg->event.ev = ev;
msg->event.fde = event_add_fd(ev, msg, socket_get_fd(msg->sock),
EVENT_FD_READ, messaging_handler, msg);
+ tevent_fd_set_auto_close(msg->event.fde);
talloc_set_destructor(msg, messaging_destructor);
@@ -614,13 +634,12 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
*/
struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx,
const char *dir,
- struct smb_iconv_convenience *iconv_convenience,
struct tevent_context *ev)
{
struct server_id id;
ZERO_STRUCT(id);
id.id = random() % 0x10000000;
- return messaging_init(mem_ctx, dir, id, iconv_convenience, ev);
+ return messaging_init(mem_ctx, dir, id, ev);
}
/*
a list of registered irpc server functions
@@ -672,24 +691,11 @@ NTSTATUS irpc_register(struct messaging_context *msg_ctx,
static void irpc_handler_reply(struct messaging_context *msg_ctx, struct irpc_message *m)
{
struct irpc_request *irpc;
- enum ndr_err_code ndr_err;
irpc = (struct irpc_request *)idr_find(msg_ctx->idr, m->header.callid);
if (irpc == NULL) return;
- /* parse the reply data */
- ndr_err = irpc->table->calls[irpc->callnum].ndr_pull(m->ndr, NDR_OUT, irpc->r);
- if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- irpc->status = m->header.status;
- talloc_steal(irpc->mem_ctx, m);
- } else {
- irpc->status = ndr_map_error2ntstatus(ndr_err);
- talloc_steal(irpc, m);
- }
- irpc->done = true;
- if (irpc->async.fn) {
- irpc->async.fn(irpc);
- }
+ irpc->incoming.handler(irpc, m);
}
/*
@@ -704,13 +710,14 @@ NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status)
m->header.status = status;
/* setup the reply */
- push = ndr_push_init_ctx(m->ndr, m->msg_ctx->iconv_convenience);
+ push = ndr_push_init_ctx(m->ndr);
if (push == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
m->header.flags |= IRPC_FLAG_REPLY;
+ m->header.creds.token= NULL;
/* construct the packet */
ndr_err = ndr_push_irpc_header(push, NDR_SCALARS|NDR_BUFFERS, &m->header);
@@ -763,6 +770,8 @@ static void irpc_handler_request(struct messaging_context *msg_ctx,
r = talloc_zero_size(m->ndr, i->table->calls[m->header.callnum].struct_size);
if (r == NULL) goto failed;
+ m->ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
+
/* parse the request data */
ndr_err = i->table->calls[i->callnum].ndr_pull(m->ndr, NDR_IN, r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed;
@@ -770,6 +779,7 @@ static void irpc_handler_request(struct messaging_context *msg_ctx,
/* make the call */
m->private_data= i->private_data;
m->defer_reply = false;
+ m->no_reply = false;
m->msg_ctx = msg_ctx;
m->irpc = i;
m->data = r;
@@ -777,6 +787,12 @@ static void irpc_handler_request(struct messaging_context *msg_ctx,
m->header.status = i->fn(m, r);
+ if (m->no_reply) {
+ /* the server function won't ever be replying to this request */
+ talloc_free(m);
+ return;
+ }
+
if (m->defer_reply) {
/* the server function has asked to defer the reply to later */
talloc_steal(msg_ctx, m);
@@ -804,7 +820,7 @@ static void irpc_handler(struct messaging_context *msg_ctx, void *private_data,
m->from = src;
- m->ndr = ndr_pull_init_blob(packet, m, msg_ctx->iconv_convenience);
+ m->ndr = ndr_pull_init_blob(packet, m);
if (m->ndr == NULL) goto failed;
m->ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
@@ -834,133 +850,10 @@ static int irpc_destructor(struct irpc_request *irpc)
irpc->callid = -1;
}
- if (irpc->reject_free) {
- return -1;
- }
return 0;
}
/*
- timeout a irpc request
-*/
-static void irpc_timeout(struct tevent_context *ev, struct tevent_timer *te,
- struct timeval t, void *private_data)
-{
- struct irpc_request *irpc = talloc_get_type(private_data, struct irpc_request);
- irpc->status = NT_STATUS_IO_TIMEOUT;
- irpc->done = true;
- if (irpc->async.fn) {
- irpc->async.fn(irpc);
- }
-}
-
-
-/*
- make a irpc call - async send
-*/
-struct irpc_request *irpc_call_send(struct messaging_context *msg_ctx,
- struct server_id server_id,
- const struct ndr_interface_table *table,
- int callnum, void *r, TALLOC_CTX *ctx)
-{
- struct irpc_header header;
- struct ndr_push *ndr;
- NTSTATUS status;
- DATA_BLOB packet;
- struct irpc_request *irpc;
- enum ndr_err_code ndr_err;
-
- irpc = talloc(msg_ctx, struct irpc_request);
- if (irpc == NULL) goto failed;
-
- irpc->msg_ctx = msg_ctx;
- irpc->table = table;
- irpc->callnum = callnum;
- irpc->callid = idr_get_new(msg_ctx->idr, irpc, UINT16_MAX);
- if (irpc->callid == -1) goto failed;
- irpc->r = r;
- irpc->done = false;
- irpc->async.fn = NULL;
- irpc->mem_ctx = ctx;
- irpc->reject_free = false;
-
- talloc_set_destructor(irpc, irpc_destructor);
-
- /* setup the header */
- header.uuid = table->syntax_id.uuid;
-
- header.if_version = table->syntax_id.if_version;
- header.callid = irpc->callid;
- header.callnum = callnum;
- header.flags = 0;
- header.status = NT_STATUS_OK;
-
- /* construct the irpc packet */
- ndr = ndr_push_init_ctx(irpc, msg_ctx->iconv_convenience);
- if (ndr == NULL) goto failed;
-
- ndr_err = ndr_push_irpc_header(ndr, NDR_SCALARS|NDR_BUFFERS, &header);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed;
-
- ndr_err = table->calls[callnum].ndr_push(ndr, NDR_IN, r);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed;
-
- /* and send it */
- packet = ndr_push_blob(ndr);
- status = messaging_send(msg_ctx, server_id, MSG_IRPC, &packet);
- if (!NT_STATUS_IS_OK(status)) goto failed;
-
- event_add_timed(msg_ctx->event.ev, irpc,
- timeval_current_ofs(IRPC_CALL_TIMEOUT, 0),
- irpc_timeout, irpc);
-
- talloc_free(ndr);
- return irpc;
-
-failed:
- talloc_free(irpc);
- return NULL;
-}
-
-/*
- wait for a irpc reply
-*/
-NTSTATUS irpc_call_recv(struct irpc_request *irpc)
-{
- NTSTATUS status;
-
- NT_STATUS_HAVE_NO_MEMORY(irpc);
-
- irpc->reject_free = true;
-
- while (!irpc->done) {
- if (event_loop_once(irpc->msg_ctx->event.ev) != 0) {
- return NT_STATUS_CONNECTION_DISCONNECTED;
- }
- }
-
- irpc->reject_free = false;
-
- status = irpc->status;
- talloc_free(irpc);
- return status;
-}
-
-/*
- perform a synchronous irpc request
-*/
-NTSTATUS irpc_call(struct messaging_context *msg_ctx,
- struct server_id server_id,
- const struct ndr_interface_table *table,
- int callnum, void *r,
- TALLOC_CTX *mem_ctx)
-{
- struct irpc_request *irpc = irpc_call_send(msg_ctx, server_id,
- table, callnum, r, mem_ctx);
- return irpc_call_recv(irpc);
-}
-
-/*
open the naming database
*/
static struct tdb_wrap *irpc_namedb_open(struct messaging_context *msg_ctx)
@@ -1116,3 +1009,332 @@ struct server_id messaging_get_server_id(struct messaging_context *msg_ctx)
{
return msg_ctx->server_id;
}
+
+struct irpc_bh_state {
+ struct messaging_context *msg_ctx;
+ struct server_id server_id;
+ const struct ndr_interface_table *table;
+ uint32_t timeout;
+ struct security_token *token;
+};
+
+static bool irpc_bh_is_connected(struct dcerpc_binding_handle *h)
+{
+ struct irpc_bh_state *hs = dcerpc_binding_handle_data(h,
+ struct irpc_bh_state);
+
+ if (!hs->msg_ctx) {
+ return false;
+ }
+
+ return true;
+}
+
+static uint32_t irpc_bh_set_timeout(struct dcerpc_binding_handle *h,
+ uint32_t timeout)
+{
+ struct irpc_bh_state *hs = dcerpc_binding_handle_data(h,
+ struct irpc_bh_state);
+ uint32_t old = hs->timeout;
+
+ hs->timeout = timeout;
+
+ return old;
+}
+
+struct irpc_bh_raw_call_state {
+ struct irpc_request *irpc;
+ uint32_t opnum;
+ DATA_BLOB in_data;
+ DATA_BLOB in_packet;
+ DATA_BLOB out_data;
+};
+
+static void irpc_bh_raw_call_incoming_handler(struct irpc_request *irpc,
+ struct irpc_message *m);
+
+static struct tevent_req *irpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct dcerpc_binding_handle *h,
+ const struct GUID *object,
+ uint32_t opnum,
+ uint32_t in_flags,
+ const uint8_t *in_data,
+ size_t in_length)
+{
+ struct irpc_bh_state *hs =
+ dcerpc_binding_handle_data(h,
+ struct irpc_bh_state);
+ struct tevent_req *req;
+ struct irpc_bh_raw_call_state *state;
+ bool ok;
+ struct irpc_header header;
+ struct ndr_push *ndr;
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct irpc_bh_raw_call_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->opnum = opnum;
+ state->in_data.data = discard_const_p(uint8_t, in_data);
+ state->in_data.length = in_length;
+
+ ok = irpc_bh_is_connected(h);
+ if (!ok) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
+ return tevent_req_post(req, ev);
+ }
+
+ state->irpc = talloc_zero(state, struct irpc_request);
+ if (tevent_req_nomem(state->irpc, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ state->irpc->msg_ctx = hs->msg_ctx;
+ state->irpc->callid = idr_get_new(hs->msg_ctx->idr,
+ state->irpc, UINT16_MAX);
+ if (state->irpc->callid == -1) {
+ tevent_req_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
+ return tevent_req_post(req, ev);
+ }
+ state->irpc->incoming.handler = irpc_bh_raw_call_incoming_handler;
+ state->irpc->incoming.private_data = req;
+
+ talloc_set_destructor(state->irpc, irpc_destructor);
+
+ /* setup the header */
+ header.uuid = hs->table->syntax_id.uuid;
+
+ header.if_version = hs->table->syntax_id.if_version;
+ header.callid = state->irpc->callid;
+ header.callnum = state->opnum;
+ header.flags = 0;
+ header.status = NT_STATUS_OK;
+ header.creds.token= hs->token;
+
+ /* construct the irpc packet */
+ ndr = ndr_push_init_ctx(state->irpc);
+ if (tevent_req_nomem(ndr, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ ndr_err = ndr_push_irpc_header(ndr, NDR_SCALARS|NDR_BUFFERS, &header);
+ status = ndr_map_error2ntstatus(ndr_err);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ ndr_err = ndr_push_bytes(ndr, in_data, in_length);
+ status = ndr_map_error2ntstatus(ndr_err);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ /* and send it */
+ state->in_packet = ndr_push_blob(ndr);
+ status = messaging_send(hs->msg_ctx, hs->server_id,
+ MSG_IRPC, &state->in_packet);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ if (hs->timeout != IRPC_CALL_TIMEOUT_INF) {
+ /* set timeout-callback in case caller wants that */
+ ok = tevent_req_set_endtime(req, ev, timeval_current_ofs(hs->timeout, 0));
+ if (!ok) {
+ return tevent_req_post(req, ev);
+ }
+ }
+
+ return req;
+}
+
+static void irpc_bh_raw_call_incoming_handler(struct irpc_request *irpc,
+ struct irpc_message *m)
+{
+ struct tevent_req *req =
+ talloc_get_type_abort(irpc->incoming.private_data,
+ struct tevent_req);
+ struct irpc_bh_raw_call_state *state =
+ tevent_req_data(req,
+ struct irpc_bh_raw_call_state);
+
+ talloc_steal(state, m);
+
+ if (!NT_STATUS_IS_OK(m->header.status)) {
+ tevent_req_nterror(req, m->header.status);
+ return;
+ }
+
+ state->out_data = data_blob_talloc(state,
+ m->ndr->data + m->ndr->offset,
+ m->ndr->data_size - m->ndr->offset);
+ if ((m->ndr->data_size - m->ndr->offset) > 0 && !state->out_data.data) {
+ tevent_req_nomem(NULL, req);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+static NTSTATUS irpc_bh_raw_call_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uint8_t **out_data,
+ size_t *out_length,
+ uint32_t *out_flags)
+{
+ struct irpc_bh_raw_call_state *state =
+ tevent_req_data(req,
+ struct irpc_bh_raw_call_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ *out_data = talloc_move(mem_ctx, &state->out_data.data);
+ *out_length = state->out_data.length;
+ *out_flags = 0;
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
+
+struct irpc_bh_disconnect_state {
+ uint8_t _dummy;
+};
+
+static struct tevent_req *irpc_bh_disconnect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct dcerpc_binding_handle *h)
+{
+ struct irpc_bh_state *hs = dcerpc_binding_handle_data(h,
+ struct irpc_bh_state);
+ struct tevent_req *req;
+ struct irpc_bh_disconnect_state *state;
+ bool ok;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct irpc_bh_disconnect_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ ok = irpc_bh_is_connected(h);
+ if (!ok) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
+ return tevent_req_post(req, ev);
+ }
+
+ hs->msg_ctx = NULL;
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
+
+static NTSTATUS irpc_bh_disconnect_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
+
+static bool irpc_bh_ref_alloc(struct dcerpc_binding_handle *h)
+{
+ return true;
+}
+
+static const struct dcerpc_binding_handle_ops irpc_bh_ops = {
+ .name = "wbint",
+ .is_connected = irpc_bh_is_connected,
+ .set_timeout = irpc_bh_set_timeout,
+ .raw_call_send = irpc_bh_raw_call_send,
+ .raw_call_recv = irpc_bh_raw_call_recv,
+ .disconnect_send = irpc_bh_disconnect_send,
+ .disconnect_recv = irpc_bh_disconnect_recv,
+
+ .ref_alloc = irpc_bh_ref_alloc,
+};
+
+/* initialise a irpc binding handle */
+struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ struct server_id server_id,
+ const struct ndr_interface_table *table)
+{
+ struct dcerpc_binding_handle *h;
+ struct irpc_bh_state *hs;
+
+ h = dcerpc_binding_handle_create(mem_ctx,
+ &irpc_bh_ops,
+ NULL,
+ table,
+ &hs,
+ struct irpc_bh_state,
+ __location__);
+ if (h == NULL) {
+ return NULL;
+ }
+ hs->msg_ctx = msg_ctx;
+ hs->server_id = server_id;
+ hs->table = table;
+ hs->timeout = IRPC_CALL_TIMEOUT;
+
+ dcerpc_binding_handle_set_sync_ev(h, msg_ctx->event.ev);
+
+ return h;
+}
+
+struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ const char *dest_task,
+ const struct ndr_interface_table *table)
+{
+ struct dcerpc_binding_handle *h;
+ struct server_id *sids;
+ struct server_id sid;
+
+ /* find the server task */
+ sids = irpc_servers_byname(msg_ctx, mem_ctx, dest_task);
+ if (sids == NULL) {
+ errno = EADDRNOTAVAIL;
+ return NULL;
+ }
+ if (sids[0].id == 0) {
+ talloc_free(sids);
+ errno = EADDRNOTAVAIL;
+ return NULL;
+ }
+ sid = sids[0];
+ talloc_free(sids);
+
+ h = irpc_binding_handle(mem_ctx, msg_ctx,
+ sid, table);
+ if (h == NULL) {
+ return NULL;
+ }
+
+ return h;
+}
+
+void irpc_binding_handle_add_security_token(struct dcerpc_binding_handle *h,
+ struct security_token *token)
+{
+ struct irpc_bh_state *hs =
+ dcerpc_binding_handle_data(h,
+ struct irpc_bh_state);
+
+ hs->token = token;
+}
diff --git a/source4/lib/messaging/messaging.h b/source4/lib/messaging/messaging.h
index 4ec69c8f34..4bc6d8c509 100644
--- a/source4/lib/messaging/messaging.h
+++ b/source4/lib/messaging/messaging.h
@@ -21,6 +21,8 @@
#ifndef _MESSAGES_H_
#define _MESSAGES_H_
+#include "librpc/gen_ndr/server_id4.h"
+
struct messaging_context;
/* general messages */
@@ -32,6 +34,7 @@ struct messaging_context;
#define MSG_IRPC 6
#define MSG_PVFS_NOTIFY 7
#define MSG_NTVFS_OPLOCK_BREAK 8
+#define MSG_DREPL_ALLOCATE_RID 9
/* temporary messaging endpoints are allocated above this line */
#define MSG_TMP_BASE 1000
@@ -39,4 +42,27 @@ struct messaging_context;
/* taskid for messaging of parent process */
#define SAMBA_PARENT_TASKID 0
+typedef void (*msg_callback_t)(struct messaging_context *msg, void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id, DATA_BLOB *data);
+
+NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server,
+ uint32_t msg_type, const DATA_BLOB *data);
+NTSTATUS messaging_register(struct messaging_context *msg, void *private_data,
+ uint32_t msg_type,
+ msg_callback_t fn);
+NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data,
+ msg_callback_t fn, uint32_t *msg_type);
+struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
+ const char *dir,
+ struct server_id server_id,
+ struct tevent_context *ev);
+struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx,
+ const char *dir,
+ struct tevent_context *ev);
+NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server,
+ uint32_t msg_type, void *ptr);
+void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data);
+struct server_id messaging_get_server_id(struct messaging_context *msg_ctx);
+
#endif
diff --git a/source4/lib/messaging/pymessaging.c b/source4/lib/messaging/pymessaging.c
index 33ccf782e9..358d205b53 100644
--- a/source4/lib/messaging/pymessaging.c
+++ b/source4/lib/messaging/pymessaging.c
@@ -19,27 +19,23 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
#include <Python.h>
+#include "includes.h"
#include "scripting/python/modules.h"
#include "libcli/util/pyerrors.h"
-#include "librpc/rpc/pyrpc.h"
-#include "lib/messaging/irpc.h"
+#include "librpc/rpc/pyrpc_util.h"
+#include "librpc/ndr/libndr.h"
#include "lib/messaging/messaging.h"
#include "lib/events/events.h"
#include "cluster/cluster.h"
#include "param/param.h"
#include "param/pyparam.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/server_id4.h"
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
-PyAPI_DATA(PyTypeObject) messaging_Type;
-PyAPI_DATA(PyTypeObject) irpc_ClientConnectionType;
+void initmessaging(void);
-/* FIXME: This prototype should be in py_irpc.h, or shared otherwise */
-extern const struct PyNdrRpcMethodDef py_ndr_irpc_methods[];
+extern PyTypeObject messaging_Type;
static bool server_id_from_py(PyObject *object, struct server_id *server_id)
{
@@ -65,7 +61,7 @@ typedef struct {
struct messaging_context *msg_ctx;
} messaging_Object;
-PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
{
struct tevent_context *ev;
const char *kwnames[] = { "own_id", "messaging_path", NULL };
@@ -87,7 +83,7 @@ PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwa
ev = s4_event_context_init(ret->mem_ctx);
if (messaging_path == NULL) {
- messaging_path = lp_messaging_path(ret->mem_ctx,
+ messaging_path = lpcfg_messaging_path(ret->mem_ctx,
py_default_loadparm_context(ret->mem_ctx));
} else {
messaging_path = talloc_strdup(ret->mem_ctx, messaging_path);
@@ -102,12 +98,10 @@ PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwa
ret->msg_ctx = messaging_init(ret->mem_ctx,
messaging_path,
server_id,
- py_iconv_convenience(ret->mem_ctx),
ev);
} else {
ret->msg_ctx = messaging_client_init(ret->mem_ctx,
messaging_path,
- py_iconv_convenience(ret->mem_ctx),
ev);
}
@@ -124,7 +118,7 @@ static void py_messaging_dealloc(PyObject *self)
{
messaging_Object *iface = (messaging_Object *)self;
talloc_free(iface->msg_ctx);
- PyObject_Del(self);
+ self->ob_type->tp_free(self);
}
static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwargs)
@@ -138,14 +132,15 @@ static PyObject *py_messaging_send(PyObject *self, PyObject *args, PyObject *kwa
const char *kwnames[] = { "target", "msg_type", "data", NULL };
int length;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ois#|:send",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ois#:send",
discard_const_p(char *, kwnames), &target, &msg_type, &data.data, &length)) {
+
return NULL;
}
data.length = length;
- if (!server_id_from_py(target, &server))
+ if (!server_id_from_py(target, &server))
return NULL;
status = messaging_send(iface->msg_ctx, server, msg_type, &data);
@@ -176,7 +171,7 @@ static PyObject *py_messaging_register(PyObject *self, PyObject *args, PyObject
NTSTATUS status;
const char *kwnames[] = { "callback", "msg_type", NULL };
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:send",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:register",
discard_const_p(char *, kwnames), &callback, &msg_type)) {
return NULL;
}
@@ -207,7 +202,7 @@ static PyObject *py_messaging_deregister(PyObject *self, PyObject *args, PyObjec
PyObject *callback;
const char *kwnames[] = { "callback", "msg_type", NULL };
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:send",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:deregister",
discard_const_p(char *, kwnames), &callback, &msg_type)) {
return NULL;
}
@@ -219,44 +214,6 @@ static PyObject *py_messaging_deregister(PyObject *self, PyObject *args, PyObjec
Py_RETURN_NONE;
}
-static PyObject *py_messaging_add_name(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- messaging_Object *iface = (messaging_Object *)self;
- NTSTATUS status;
- char *name;
- const char *kwnames[] = { "name", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|:send",
- discard_const_p(char *, kwnames), &name)) {
- return NULL;
- }
-
- status = irpc_add_name(iface->msg_ctx, name);
- if (NT_STATUS_IS_ERR(status)) {
- PyErr_SetNTSTATUS(status);
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-
-static PyObject *py_messaging_remove_name(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- messaging_Object *iface = (messaging_Object *)self;
- char *name;
- const char *kwnames[] = { "name", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|:send",
- discard_const_p(char *, kwnames), &name)) {
- return NULL;
- }
-
- irpc_remove_name(iface->msg_ctx, name);
-
- Py_RETURN_NONE;
-}
-
static PyMethodDef py_messaging_methods[] = {
{ "send", (PyCFunction)py_messaging_send, METH_VARARGS|METH_KEYWORDS,
"S.send(target, msg_type, data) -> None\nSend a message" },
@@ -264,8 +221,6 @@ static PyMethodDef py_messaging_methods[] = {
"S.register(callback, msg_type=None) -> msg_type\nRegister a message handler" },
{ "deregister", (PyCFunction)py_messaging_deregister, METH_VARARGS|METH_KEYWORDS,
"S.deregister(callback, msg_type) -> None\nDeregister a message handler" },
- { "add_name", (PyCFunction)py_messaging_add_name, METH_VARARGS|METH_KEYWORDS, "S.add_name(name) -> None\nListen on another name" },
- { "remove_name", (PyCFunction)py_messaging_remove_name, METH_VARARGS|METH_KEYWORDS, "S.remove_name(name) -> None\nStop listening on a name" },
{ NULL, NULL, 0, NULL }
};
@@ -287,7 +242,7 @@ static PyGetSetDef py_messaging_getset[] = {
PyTypeObject messaging_Type = {
PyObject_HEAD_INIT(NULL) 0,
- .tp_name = "irpc.Messaging",
+ .tp_name = "messaging.Messaging",
.tp_basicsize = sizeof(messaging_Object),
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
.tp_new = py_messaging_connect,
@@ -299,278 +254,17 @@ PyTypeObject messaging_Type = {
"If no path is specified, the default path from smb.conf will be used."
};
-
-/*
- state of a irpc 'connection'
-*/
-typedef struct {
- PyObject_HEAD
- const char *server_name;
- struct server_id *dest_ids;
- struct messaging_context *msg_ctx;
- TALLOC_CTX *mem_ctx;
-} irpc_ClientConnectionObject;
-
-/*
- setup a context for talking to a irpc server
- example:
- status = irpc.connect("smb_server");
-*/
-
-PyObject *py_irpc_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
-{
- struct tevent_context *ev;
- const char *kwnames[] = { "server", "own_id", "messaging_path", NULL };
- char *server;
- const char *messaging_path = NULL;
- PyObject *own_id = Py_None;
- irpc_ClientConnectionObject *ret;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oz:connect",
- discard_const_p(char *, kwnames), &server, &own_id, &messaging_path)) {
- return NULL;
- }
-
- ret = PyObject_New(irpc_ClientConnectionObject, &irpc_ClientConnectionType);
- if (ret == NULL)
- return NULL;
-
- ret->mem_ctx = talloc_new(NULL);
-
- ret->server_name = server;
-
- ev = s4_event_context_init(ret->mem_ctx);
-
- if (messaging_path == NULL) {
- messaging_path = lp_messaging_path(ret->mem_ctx,
- py_default_loadparm_context(ret->mem_ctx));
- } else {
- messaging_path = talloc_strdup(ret->mem_ctx, messaging_path);
- }
-
- if (own_id != Py_None) {
- struct server_id server_id;
-
- if (!server_id_from_py(own_id, &server_id))
- return NULL;
-
- ret->msg_ctx = messaging_init(ret->mem_ctx,
- messaging_path,
- server_id,
- py_iconv_convenience(ret->mem_ctx),
- ev);
- } else {
- ret->msg_ctx = messaging_client_init(ret->mem_ctx,
- messaging_path,
- py_iconv_convenience(ret->mem_ctx),
- ev);
- }
-
- if (ret->msg_ctx == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "irpc_connect unable to create a messaging context");
- talloc_free(ret->mem_ctx);
- return NULL;
- }
-
- ret->dest_ids = irpc_servers_byname(ret->msg_ctx, ret->mem_ctx, ret->server_name);
- if (ret->dest_ids == NULL || ret->dest_ids[0].id == 0) {
- talloc_free(ret->mem_ctx);
- PyErr_SetNTSTATUS(NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return NULL;
- } else {
- return (PyObject *)ret;
- }
-}
-
-typedef struct {
- PyObject_HEAD
- struct irpc_request **reqs;
- int count;
- int current;
- TALLOC_CTX *mem_ctx;
- py_data_unpack_fn unpack_fn;
-} irpc_ResultObject;
-
-
-static PyObject *irpc_result_next(irpc_ResultObject *iterator)
-{
- NTSTATUS status;
-
- if (iterator->current >= iterator->count) {
- PyErr_SetString(PyExc_StopIteration, "No more results");
- return NULL;
- }
-
- status = irpc_call_recv(iterator->reqs[iterator->current]);
- iterator->current++;
- if (!NT_STATUS_IS_OK(status)) {
- PyErr_SetNTSTATUS(status);
- return NULL;
- }
-
- return iterator->unpack_fn(iterator->reqs[iterator->current-1]->r);
-}
-
-static PyObject *irpc_result_len(irpc_ResultObject *self)
-{
- return PyLong_FromLong(self->count);
-}
-
-static PyMethodDef irpc_result_methods[] = {
- { "__len__", (PyCFunction)irpc_result_len, METH_NOARGS,
- "Number of elements returned"},
- { NULL }
-};
-
-static void irpc_result_dealloc(PyObject *self)
-{
- talloc_free(((irpc_ResultObject *)self)->mem_ctx);
- PyObject_Del(self);
-}
-
-PyTypeObject irpc_ResultIteratorType = {
- PyObject_HEAD_INIT(NULL) 0,
- .tp_name = "irpc.ResultIterator",
- .tp_basicsize = sizeof(irpc_ResultObject),
- .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- .tp_iternext = (iternextfunc)irpc_result_next,
- .tp_iter = PyObject_SelfIter,
- .tp_methods = irpc_result_methods,
- .tp_dealloc = irpc_result_dealloc,
-};
-
-static PyObject *py_irpc_call(irpc_ClientConnectionObject *p, struct PyNdrRpcMethodDef *method_def, PyObject *args, PyObject *kwargs)
-{
- void *ptr;
- struct irpc_request **reqs;
- int i, count;
- NTSTATUS status;
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- irpc_ResultObject *ret;
-
- /* allocate the C structure */
- ptr = talloc_zero_size(mem_ctx, method_def->table->calls[method_def->opnum].struct_size);
- if (ptr == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- /* convert the mpr object into a C structure */
- if (!method_def->pack_in_data(args, kwargs, ptr)) {
- talloc_free(mem_ctx);
- return NULL;
- }
-
- for (count=0;p->dest_ids[count].id;count++) /* noop */ ;
-
- /* we need to make a call per server */
- reqs = talloc_array(mem_ctx, struct irpc_request *, count);
- if (reqs == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- /* make the actual calls */
- for (i=0;i<count;i++) {
- reqs[i] = irpc_call_send(p->msg_ctx, p->dest_ids[i],
- method_def->table, method_def->opnum, ptr, ptr);
- if (reqs[i] == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- talloc_steal(reqs, reqs[i]);
- }
-
- ret = PyObject_New(irpc_ResultObject, &irpc_ResultIteratorType);
- ret->mem_ctx = mem_ctx;
- ret->reqs = reqs;
- ret->count = count;
- ret->current = 0;
- ret->unpack_fn = method_def->unpack_out_data;
-
- return (PyObject *)ret;
-done:
- talloc_free(mem_ctx);
- PyErr_SetNTSTATUS(status);
- return NULL;
-}
-
-static PyObject *py_irpc_call_wrapper(PyObject *self, PyObject *args, void *wrapped, PyObject *kwargs)
-{
- irpc_ClientConnectionObject *iface = (irpc_ClientConnectionObject *)self;
- struct PyNdrRpcMethodDef *md = wrapped;
-
- return py_irpc_call(iface, md, args, kwargs);
-}
-
-static void py_irpc_dealloc(PyObject *self)
-{
- irpc_ClientConnectionObject *iface = (irpc_ClientConnectionObject *)self;
- talloc_free(iface->mem_ctx);
- PyObject_Del(self);
-}
-
-PyTypeObject irpc_ClientConnectionType = {
- PyObject_HEAD_INIT(NULL) 0,
- .tp_name = "irpc.ClientConnection",
- .tp_basicsize = sizeof(irpc_ClientConnectionObject),
- .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- .tp_new = py_irpc_connect,
- .tp_dealloc = py_irpc_dealloc,
- .tp_doc = "ClientConnection(server, own_id=None, messaging_path=None)\n" \
- "Create a new IRPC client connection to communicate with the servers in the specified path.\n" \
- "If no path is specified, the default path from smb.conf will be used."
-};
-
-static bool irpc_AddNdrRpcMethods(PyTypeObject *ifacetype, const struct PyNdrRpcMethodDef *mds)
-{
- int i;
- for (i = 0; mds[i].name; i++) {
- PyObject *ret;
- struct wrapperbase *wb = calloc(sizeof(struct wrapperbase), 1);
-
- wb->name = discard_const_p(char, mds[i].name);
- wb->flags = PyWrapperFlag_KEYWORDS;
- wb->wrapper = (wrapperfunc)py_irpc_call_wrapper;
- wb->doc = discard_const_p(char, mds[i].doc);
-
- ret = PyDescr_NewWrapper(ifacetype, wb, discard_const_p(void, &mds[i]));
-
- PyDict_SetItemString(ifacetype->tp_dict, mds[i].name,
- (PyObject *)ret);
- }
-
- return true;
-}
-
void initmessaging(void)
{
PyObject *mod;
- PyObject *dep_irpc;
-
- dep_irpc = PyImport_ImportModule("samba.dcerpc.irpc");
- if (dep_irpc == NULL)
- return;
-
- if (PyType_Ready(&irpc_ClientConnectionType) < 0)
- return;
if (PyType_Ready(&messaging_Type) < 0)
return;
- if (PyType_Ready(&irpc_ResultIteratorType) < 0)
- return;
-
- if (!irpc_AddNdrRpcMethods(&irpc_ClientConnectionType, py_ndr_irpc_methods))
- return;
-
mod = Py_InitModule3("messaging", NULL, "Internal RPC");
if (mod == NULL)
return;
- Py_INCREF((PyObject *)&irpc_ClientConnectionType);
- PyModule_AddObject(mod, "ClientConnection", (PyObject *)&irpc_ClientConnectionType);
-
Py_INCREF((PyObject *)&messaging_Type);
PyModule_AddObject(mod, "Messaging", (PyObject *)&messaging_Type);
}
diff --git a/source4/lib/messaging/tests/bindings.py b/source4/lib/messaging/tests/bindings.py
deleted file mode 100644
index c89538ddfa..0000000000
--- a/source4/lib/messaging/tests/bindings.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Unix SMB/CIFS implementation.
-# Copyright © Jelmer Vernooij <jelmer@samba.org> 2008
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-
-from samba.messaging import Messaging
-from unittest import TestCase
-
-class MessagingTests(TestCase):
- def get_context(self, *args, **kwargs):
- kwargs["messaging_path"] = "."
- return Messaging(*args, **kwargs)
-
- def test_register(self):
- x = self.get_context()
- def callback():
- pass
- msg_type = x.register(callback)
- x.deregister(callback, msg_type)
-
- def test_assign_server_id(self):
- x = self.get_context()
- self.assertTrue(isinstance(x.server_id, tuple))
- self.assertEquals(3, len(x.server_id))
-
- def test_ping_speed(self):
- server_ctx = self.get_context((0, 1))
- def ping_callback(src, data):
- server_ctx.send(src, data)
- def exit_callback():
- print "received exit"
- msg_ping = server_ctx.register(ping_callback)
- msg_exit = server_ctx.register(exit_callback)
-
- def pong_callback():
- print "received pong"
- client_ctx = self.get_context((0, 2))
- msg_pong = client_ctx.register(pong_callback)
-
- client_ctx.send((0,1), msg_ping, "testing")
- client_ctx.send((0,1), msg_ping, "")
-
diff --git a/source4/lib/messaging/tests/irpc.c b/source4/lib/messaging/tests/irpc.c
index 3eb23e0f7d..4d0b6b4378 100644
--- a/source4/lib/messaging/tests/irpc.c
+++ b/source4/lib/messaging/tests/irpc.c
@@ -23,6 +23,7 @@
#include "lib/events/events.h"
#include "lib/messaging/irpc.h"
#include "librpc/gen_ndr/ndr_echo.h"
+#include "librpc/gen_ndr/ndr_echo_c.h"
#include "torture/torture.h"
#include "cluster/cluster.h"
#include "param/param.h"
@@ -57,8 +58,8 @@ static void deferred_echodata(struct tevent_context *ev, struct tevent_timer *te
struct timeval t, void *private_data)
{
struct irpc_message *irpc = talloc_get_type(private_data, struct irpc_message);
- struct echo_EchoData *r = irpc->data;
- r->out.out_data = talloc_memdup(r, r->in.in_data, r->in.len);
+ struct echo_EchoData *r = (struct echo_EchoData *)irpc->data;
+ r->out.out_data = (uint8_t *)talloc_memdup(r, r->in.in_data, r->in.len);
if (r->out.out_data == NULL) {
irpc_send_reply(irpc, NT_STATUS_NO_MEMORY);
}
@@ -88,13 +89,18 @@ static bool test_addone(struct torture_context *test, const void *_data,
NTSTATUS status;
const struct irpc_test_data *data = (const struct irpc_test_data *)_data;
uint32_t value = *(const uint32_t *)_value;
+ struct dcerpc_binding_handle *irpc_handle;
+
+ irpc_handle = irpc_binding_handle(test, data->msg_ctx1,
+ cluster_id(0, MSG_ID2),
+ &ndr_table_rpcecho);
+ torture_assert(test, irpc_handle, "no memory");
/* make the call */
r.in.in_data = value;
test_debug = true;
- status = IRPC_CALL(data->msg_ctx1, cluster_id(0, MSG_ID2),
- rpcecho, ECHO_ADDONE, &r, test);
+ status = dcerpc_echo_AddOne_r(irpc_handle, test, &r);
test_debug = false;
torture_assert_ntstatus_ok(test, status, "AddOne failed");
@@ -117,14 +123,18 @@ static bool test_echodata(struct torture_context *tctx,
NTSTATUS status;
const struct irpc_test_data *data = (const struct irpc_test_data *)tcase_data;
TALLOC_CTX *mem_ctx = tctx;
+ struct dcerpc_binding_handle *irpc_handle;
+
+ irpc_handle = irpc_binding_handle(mem_ctx, data->msg_ctx1,
+ cluster_id(0, MSG_ID2),
+ &ndr_table_rpcecho);
+ torture_assert(tctx, irpc_handle, "no memory");
/* make the call */
r.in.in_data = (unsigned char *)talloc_strdup(mem_ctx, "0123456789");
r.in.len = strlen((char *)r.in.in_data);
- status = IRPC_CALL(data->msg_ctx1, cluster_id(0, MSG_ID2),
- rpcecho, ECHO_ECHODATA, &r,
- mem_ctx);
+ status = dcerpc_echo_EchoData_r(irpc_handle, mem_ctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EchoData failed");
/* check the answer */
@@ -141,20 +151,28 @@ static bool test_echodata(struct torture_context *tctx,
return true;
}
+struct irpc_callback_state {
+ struct echo_AddOne r;
+ int *pong_count;
+};
-static void irpc_callback(struct irpc_request *irpc)
+static void irpc_callback(struct tevent_req *subreq)
{
- struct echo_AddOne *r = (struct echo_AddOne *)irpc->r;
- int *pong_count = (int *)irpc->async.private_data;
- NTSTATUS status = irpc_call_recv(irpc);
+ struct irpc_callback_state *s =
+ tevent_req_callback_data(subreq,
+ struct irpc_callback_state);
+ NTSTATUS status;
+
+ status = dcerpc_echo_AddOne_r_recv(subreq, s);
+ TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
printf("irpc call failed - %s\n", nt_errstr(status));
}
- if (*r->out.out_data != r->in.in_data + 1) {
+ if (*s->r.out.out_data != s->r.in.in_data + 1) {
printf("AddOne wrong answer - %u + 1 = %u should be %u\n",
- r->in.in_data, *r->out.out_data, r->in.in_data+1);
+ s->r.in.in_data, *s->r.out.out_data, s->r.in.in_data+1);
}
- (*pong_count)++;
+ (*s->pong_count)++;
}
/*
@@ -168,25 +186,34 @@ static bool test_speed(struct torture_context *tctx,
int pong_count = 0;
const struct irpc_test_data *data = (const struct irpc_test_data *)tcase_data;
struct timeval tv;
- struct echo_AddOne r;
TALLOC_CTX *mem_ctx = tctx;
int timelimit = torture_setting_int(tctx, "timelimit", 10);
+ struct dcerpc_binding_handle *irpc_handle;
- tv = timeval_current();
+ irpc_handle = irpc_binding_handle(mem_ctx, data->msg_ctx1,
+ cluster_id(0, MSG_ID2),
+ &ndr_table_rpcecho);
+ torture_assert(tctx, irpc_handle, "no memory");
- r.in.in_data = 0;
+ tv = timeval_current();
torture_comment(tctx, "Sending echo for %d seconds\n", timelimit);
while (timeval_elapsed(&tv) < timelimit) {
- struct irpc_request *irpc;
+ struct tevent_req *subreq;
+ struct irpc_callback_state *s;
+
+ s = talloc_zero(mem_ctx, struct irpc_callback_state);
+ torture_assert(tctx, s != NULL, "no mem");
+
+ s->pong_count = &pong_count;
- irpc = IRPC_CALL_SEND(data->msg_ctx1, cluster_id(0, MSG_ID2),
- rpcecho, ECHO_ADDONE,
- &r, mem_ctx);
- torture_assert(tctx, irpc != NULL, "AddOne send failed");
+ subreq = dcerpc_echo_AddOne_r_send(mem_ctx,
+ tctx->ev,
+ irpc_handle,
+ &s->r);
+ torture_assert(tctx, subreq != NULL, "AddOne send failed");
- irpc->async.fn = irpc_callback;
- irpc->async.private_data = &pong_count;
+ tevent_req_set_callback(subreq, irpc_callback, s);
ping_count++;
@@ -215,22 +242,20 @@ static bool irpc_setup(struct torture_context *tctx, void **_data)
*_data = data = talloc(tctx, struct irpc_test_data);
- lp_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
+ lpcfg_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
data->ev = tctx->ev;
torture_assert(tctx, data->msg_ctx1 =
messaging_init(tctx,
- lp_messaging_path(tctx, tctx->lp_ctx),
+ lpcfg_messaging_path(tctx, tctx->lp_ctx),
cluster_id(0, MSG_ID1),
- lp_iconv_convenience(tctx->lp_ctx),
data->ev),
"Failed to init first messaging context");
torture_assert(tctx, data->msg_ctx2 =
messaging_init(tctx,
- lp_messaging_path(tctx, tctx->lp_ctx),
+ lpcfg_messaging_path(tctx, tctx->lp_ctx),
cluster_id(0, MSG_ID2),
- lp_iconv_convenience(tctx->lp_ctx),
data->ev),
"Failed to init second messaging context");
@@ -246,7 +271,7 @@ static bool irpc_setup(struct torture_context *tctx, void **_data)
struct torture_suite *torture_local_irpc(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "IRPC");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "irpc");
struct torture_tcase *tcase = torture_suite_add_tcase(suite, "irpc");
int i;
uint32_t *values = talloc_array(tcase, uint32_t, 5);
diff --git a/source4/lib/messaging/tests/messaging.c b/source4/lib/messaging/tests/messaging.c
index f61132caac..82fdf2f73e 100644
--- a/source4/lib/messaging/tests/messaging.c
+++ b/source4/lib/messaging/tests/messaging.c
@@ -67,14 +67,12 @@ static bool test_ping_speed(struct torture_context *tctx)
int timelimit = torture_setting_int(tctx, "timelimit", 10);
uint32_t msg_ping, msg_exit;
- lp_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
+ lpcfg_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
ev = tctx->ev;
msg_server_ctx = messaging_init(tctx,
- lp_messaging_path(tctx, tctx->lp_ctx),
- cluster_id(0, 1),
- lp_iconv_convenience(tctx->lp_ctx),
+ lpcfg_messaging_path(tctx, tctx->lp_ctx), cluster_id(0, 1),
ev);
torture_assert(tctx, msg_server_ctx != NULL, "Failed to init ping messaging context");
@@ -83,9 +81,8 @@ static bool test_ping_speed(struct torture_context *tctx)
messaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit);
msg_client_ctx = messaging_init(tctx,
- lp_messaging_path(tctx, tctx->lp_ctx),
+ lpcfg_messaging_path(tctx, tctx->lp_ctx),
cluster_id(0, 2),
- lp_iconv_convenience(tctx->lp_ctx),
ev);
torture_assert(tctx, msg_client_ctx != NULL,
@@ -139,7 +136,7 @@ static bool test_ping_speed(struct torture_context *tctx)
struct torture_suite *torture_local_messaging(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *s = torture_suite_create(mem_ctx, "MESSAGING");
+ struct torture_suite *s = torture_suite_create(mem_ctx, "messaging");
torture_suite_add_simple_test(s, "ping_speed", test_ping_speed);
return s;
}
diff --git a/source4/lib/messaging/wscript_build b/source4/lib/messaging/wscript_build
new file mode 100644
index 0000000000..b7d4fed95e
--- /dev/null
+++ b/source4/lib/messaging/wscript_build
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+
+
+bld.SAMBA_SUBSYSTEM('MESSAGING',
+ source='messaging.c',
+ public_deps='samba-util tdb-wrap NDR_IRPC UNIX_PRIVS UTIL_TDB cluster ndr samba_socket dcerpc'
+ )
+
+
+bld.SAMBA_PYTHON('python_messaging',
+ source='pymessaging.c',
+ deps='MESSAGING events pyparam_util',
+ realname='samba/messaging.so'
+ )
+
diff --git a/source4/lib/policy/gp_filesys.c b/source4/lib/policy/gp_filesys.c
new file mode 100644
index 0000000000..00d04d5367
--- /dev/null
+++ b/source4/lib/policy/gp_filesys.c
@@ -0,0 +1,647 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Group Policy Object Support
+ * Copyright (C) Wilco Baan Hofman 2008-2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include "includes.h"
+#include "lib/policy/policy.h"
+#include "libcli/raw/smb.h"
+#include "libcli/libcli.h"
+#include "param/param.h"
+#include "libcli/resolve/resolve.h"
+#include "libcli/raw/libcliraw.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#define GP_MAX_DEPTH 25
+
+struct gp_file_entry {
+ bool is_directory;
+ const char *rel_path;
+};
+struct gp_file_list {
+ uint32_t num_files;
+ struct gp_file_entry *files;
+};
+struct gp_list_state {
+ struct smbcli_tree *tree;
+ uint8_t depth;
+ const char *cur_rel_path;
+ const char *share_path;
+
+ struct gp_file_list list;
+};
+
+static NTSTATUS gp_do_list(const char *, struct gp_list_state *);
+
+/* Create a temporary policy directory */
+static const char *gp_tmpdir(TALLOC_CTX *mem_ctx)
+{
+ char *gp_dir = talloc_asprintf(mem_ctx, "%s/policy", tmpdir());
+ struct stat st;
+ int rv;
+
+ if (gp_dir == NULL) return NULL;
+
+ if (stat(gp_dir, &st) != 0) {
+ rv = mkdir(gp_dir, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Failed to create directory %s: %s\n",
+ gp_dir, strerror(errno)));
+ talloc_free(gp_dir);
+ return NULL;
+ }
+ }
+
+ return gp_dir;
+}
+
+/* This function is called by the smbcli_list function */
+static void gp_list_helper (struct clilist_file_info *info, const char *mask,
+ void *list_state_ptr)
+{
+ struct gp_list_state *state = list_state_ptr;
+ const char *rel_path;
+
+ /* Ignore . and .. directory entries */
+ if (strcmp(info->name, ".") == 0 || strcmp(info->name, "..") == 0) {
+ return;
+ }
+
+ /* Safety check against ../.. in filenames which may occur on non-POSIX
+ * platforms */
+ if (strstr(info->name, "../")) {
+ return;
+ }
+
+ rel_path = talloc_asprintf(state, "%s\\%s", state->cur_rel_path, info->name);
+ if (rel_path == NULL) return;
+
+ /* Append entry to file list */
+ state->list.files = talloc_realloc(state, state->list.files,
+ struct gp_file_entry,
+ state->list.num_files + 1);
+ if (state->list.files == NULL) return;
+
+ state->list.files[state->list.num_files].rel_path = rel_path;
+
+ /* Directory */
+ if (info->attrib & FILE_ATTRIBUTE_DIRECTORY) {
+ state->list.files[state->list.num_files].is_directory = true;
+ state->list.num_files++;
+
+ /* Recurse into this directory if the depth is below the maximum */
+ if (state->depth < GP_MAX_DEPTH) {
+ gp_do_list(rel_path, state);
+ }
+
+ return;
+ }
+
+ state->list.files[state->list.num_files].is_directory = false;
+ state->list.num_files++;
+
+ return;
+}
+
+static NTSTATUS gp_do_list (const char *rel_path, struct gp_list_state *state)
+{
+ uint16_t attributes;
+ int rv;
+ char *mask;
+ const char *old_rel_path;
+
+ attributes = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN |
+ FILE_ATTRIBUTE_DIRECTORY;
+
+ /* Update the relative paths, while buffering the parent */
+ old_rel_path = state->cur_rel_path;
+ state->cur_rel_path = rel_path;
+ state->depth++;
+
+ /* Get the current mask */
+ mask = talloc_asprintf(state, "%s%s\\*", state->share_path, rel_path);
+ NT_STATUS_HAVE_NO_MEMORY(mask);
+ rv = smbcli_list(state->tree, mask, attributes, gp_list_helper, state);
+ talloc_free(mask);
+
+ /* Go back to the state of the parent */
+ state->cur_rel_path = old_rel_path;
+ state->depth--;
+
+ if (rv == -1)
+ return NT_STATUS_UNSUCCESSFUL;
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS gp_cli_connect(struct gp_context *gp_ctx)
+{
+ struct smbcli_options options;
+ struct smbcli_session_options session_options;
+
+ if (gp_ctx->cli != NULL)
+ return NT_STATUS_OK;
+
+ gp_ctx->cli = smbcli_state_init(gp_ctx);
+
+ lpcfg_smbcli_options(gp_ctx->lp_ctx, &options);
+ lpcfg_smbcli_session_options(gp_ctx->lp_ctx, &session_options);
+
+
+ return smbcli_full_connection(gp_ctx,
+ &gp_ctx->cli,
+ gp_ctx->active_dc.name,
+ lpcfg_smb_ports(gp_ctx->lp_ctx),
+ "sysvol",
+ NULL,
+ lpcfg_socket_options(gp_ctx->lp_ctx),
+ gp_ctx->credentials,
+ lpcfg_resolve_context(gp_ctx->lp_ctx),
+ gp_ctx->ev_ctx,
+ &options,
+ &session_options,
+ lpcfg_gensec_settings(gp_ctx, gp_ctx->lp_ctx));
+}
+
+static char * gp_get_share_path(TALLOC_CTX *mem_ctx, const char *file_sys_path)
+{
+ unsigned int i, bkslash_cnt;
+
+ /* Get the path from the share down (\\..\..\(this\stuff) */
+ for (i = 0, bkslash_cnt = 0; file_sys_path[i] != '\0'; i++) {
+ if (file_sys_path[i] == '\\')
+ bkslash_cnt++;
+
+ if (bkslash_cnt == 4) {
+ return talloc_strdup(mem_ctx, &file_sys_path[i]);
+ }
+ }
+
+ return NULL;
+}
+
+static NTSTATUS gp_get_file (struct smbcli_tree *tree, const char *remote_src,
+ const char *local_dst)
+{
+ int fh_remote, fh_local;
+ uint8_t *buf;
+ size_t nread = 0;
+ size_t buf_size = 1024;
+ size_t file_size;
+ uint16_t attr;
+
+ /* Open the remote file */
+ fh_remote = smbcli_open(tree, remote_src, O_RDONLY, DENY_NONE);
+ if (fh_remote == -1) {
+ DEBUG(0, ("Failed to open remote file: %s\n", remote_src));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Open the local file */
+ fh_local = open(local_dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fh_local == -1) {
+ DEBUG(0, ("Failed to open local file: %s\n", local_dst));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get the remote file size for error checking */
+ if (NT_STATUS_IS_ERR(smbcli_qfileinfo(tree, fh_remote,
+ &attr, &file_size, NULL, NULL, NULL, NULL, NULL)) &&
+ NT_STATUS_IS_ERR(smbcli_getattrE(tree, fh_remote,
+ &attr, &file_size, NULL, NULL, NULL))) {
+ DEBUG(0, ("Failed to get remote file size: %s\n", smbcli_errstr(tree)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ buf = talloc_zero_array(tree, uint8_t, buf_size);
+ NT_STATUS_HAVE_NO_MEMORY(buf);
+
+ /* Copy the contents of the file */
+ while (1) {
+ int n = smbcli_read(tree, fh_remote, buf, nread, buf_size);
+
+ if (n <= 0) {
+ break;
+ }
+
+ if (write(fh_local, buf, n) != n) {
+ DEBUG(0, ("Short write while copying file.\n"));
+ talloc_free(buf);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ nread += n;
+ }
+
+ /* Bytes read should match the file size, or the copy was incomplete */
+ if (nread != file_size) {
+ DEBUG(0, ("Remote/local file size mismatch after copying file: "
+ "%s (remote %zu, local %zu).\n",
+ remote_src, file_size, nread));
+ talloc_free(buf);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Close the files */
+ smbcli_close(tree, fh_remote);
+ close(fh_local);
+
+ talloc_free(buf);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS gp_get_files(struct smbcli_tree *tree, const char *share_path,
+ const char *local_path, struct gp_file_list *list)
+{
+ uint32_t i;
+ int rv;
+ char *local_rel_path, *full_local_path, *full_remote_path;
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS status;
+
+ mem_ctx = talloc_new(tree);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ for (i = 0; i < list->num_files; i++) {
+
+ /* Get local path by replacing backslashes with slashes */
+ local_rel_path = talloc_strdup(mem_ctx, list->files[i].rel_path);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(local_rel_path, mem_ctx);
+ string_replace(local_rel_path, '\\', '/');
+
+ full_local_path = talloc_asprintf(mem_ctx, "%s%s", local_path,
+ local_rel_path);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(full_local_path, mem_ctx);
+
+ /* If the entry is a directory, create it. */
+ if (list->files[i].is_directory == true) {
+ rv = mkdir(full_local_path, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Failed to create directory %s: %s\n",
+ full_local_path, strerror(errno)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ continue;
+ }
+
+ full_remote_path = talloc_asprintf(mem_ctx, "%s%s", share_path,
+ list->files[i].rel_path);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(full_remote_path, mem_ctx);
+
+ /* Get the file */
+ status = gp_get_file(tree, full_remote_path, full_local_path);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Error getting file.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo,
+ const char **ret_local_path)
+{
+ TALLOC_CTX *mem_ctx;
+ struct gp_list_state *state;
+ NTSTATUS status;
+ struct stat st;
+ int rv;
+ const char *local_path, *share_path;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ if (gp_ctx->cli == NULL) {
+ status = gp_cli_connect(gp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create cli connection to DC\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+ }
+
+ /* Get the remote path to copy from */
+ share_path = gp_get_share_path(mem_ctx, gpo->file_sys_path);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(share_path, mem_ctx);
+
+ /* Get the local path to copy to */
+ local_path = talloc_asprintf(gp_ctx, "%s/%s", gp_tmpdir(mem_ctx), gpo->name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(local_path, mem_ctx);
+
+ /* Prepare the state structure */
+ state = talloc_zero(mem_ctx, struct gp_list_state);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(state, mem_ctx);
+
+ state->tree = gp_ctx->cli->tree;
+ state->share_path = share_path;
+
+ /* Create the GPO dir if it does not exist */
+ if (stat(local_path, &st) != 0) {
+ rv = mkdir(local_path, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Could not create local path\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* Get the file list */
+ status = gp_do_list("", state);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Could not list GPO files on remote server\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* If the list has no entries there is a problem. */
+ if (state->list.num_files == 0) {
+ DEBUG(0, ("File list is has no entries. Is the GPT directory empty?\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Fetch the files */
+ status = gp_get_files(gp_ctx->cli->tree, share_path, local_path, &state->list);
+
+ /* Return the local path to the gpo */
+ *ret_local_path = local_path;
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS push_recursive (struct gp_context *gp_ctx, const char *local_path,
+ const char *remote_path, int depth)
+{
+ DIR *dir;
+ struct dirent *dirent;
+ char *entry_local_path;
+ char *entry_remote_path;
+ int local_fd, remote_fd;
+ int buf[1024];
+ int nread, total_read;
+ struct stat s;
+
+ dir = opendir(local_path);
+ while ((dirent = readdir(dir)) != NULL) {
+ if (strcmp(dirent->d_name, ".") == 0 ||
+ strcmp(dirent->d_name, "..") == 0) {
+ continue;
+ }
+
+ entry_local_path = talloc_asprintf(gp_ctx, "%s/%s", local_path,
+ dirent->d_name);
+ NT_STATUS_HAVE_NO_MEMORY(entry_local_path);
+
+ entry_remote_path = talloc_asprintf(gp_ctx, "%s\\%s",
+ remote_path, dirent->d_name);
+ NT_STATUS_HAVE_NO_MEMORY(entry_remote_path);
+
+ if (stat(dirent->d_name, &s) != 0) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (s.st_mode & S_IFDIR) {
+ DEBUG(6, ("Pushing directory %s to %s on sysvol\n",
+ entry_local_path, entry_remote_path));
+ smbcli_mkdir(gp_ctx->cli->tree, entry_remote_path);
+ if (depth < GP_MAX_DEPTH) {
+ push_recursive(gp_ctx, entry_local_path,
+ entry_remote_path, depth+1);
+ }
+ } else {
+ DEBUG(6, ("Pushing file %s to %s on sysvol\n",
+ entry_local_path, entry_remote_path));
+ remote_fd = smbcli_open(gp_ctx->cli->tree,
+ entry_remote_path,
+ O_WRONLY | O_CREAT,
+ 0);
+ if (remote_fd < 0) {
+ talloc_free(entry_local_path);
+ talloc_free(entry_remote_path);
+ DEBUG(0, ("Failed to create remote file: %s\n",
+ entry_remote_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ local_fd = open(entry_local_path, O_RDONLY);
+ if (local_fd < 0) {
+ talloc_free(entry_local_path);
+ talloc_free(entry_remote_path);
+ DEBUG(0, ("Failed to open local file: %s\n",
+ entry_local_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ total_read = 0;
+ while ((nread = read(local_fd, &buf, sizeof(buf)))) {
+ smbcli_write(gp_ctx->cli->tree, remote_fd, 0,
+ &buf, total_read, nread);
+ total_read += nread;
+ }
+
+ close(local_fd);
+ smbcli_close(gp_ctx->cli->tree, remote_fd);
+ }
+ talloc_free(entry_local_path);
+ talloc_free(entry_remote_path);
+ }
+ closedir(dir);
+
+ return NT_STATUS_OK;
+}
+
+
+
+NTSTATUS gp_push_gpt(struct gp_context *gp_ctx, const char *local_path,
+ const char *file_sys_path)
+{
+ NTSTATUS status;
+ char *share_path;
+
+ if (gp_ctx->cli == NULL) {
+ status = gp_cli_connect(gp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create cli connection to DC\n"));
+ return status;
+ }
+ }
+ share_path = gp_get_share_path(gp_ctx, file_sys_path);
+
+ DEBUG(5, ("Copying %s to %s on sysvol\n", local_path, share_path));
+
+ smbcli_mkdir(gp_ctx->cli->tree, share_path);
+
+ status = push_recursive(gp_ctx, local_path, share_path, 0);
+
+ talloc_free(share_path);
+ return status;
+}
+
+NTSTATUS gp_create_gpt(struct gp_context *gp_ctx, const char *name,
+ const char *file_sys_path)
+{
+ TALLOC_CTX *mem_ctx;
+ const char *tmp_dir, *policy_dir, *tmp_str;
+ int rv;
+ int fd;
+ NTSTATUS status;
+ const char *file_content = "[General]\r\nVersion=0\r\n";
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ tmp_dir = gp_tmpdir(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(tmp_dir);
+ policy_dir = talloc_asprintf(mem_ctx, "%s/%s", tmp_dir, name);
+ NT_STATUS_HAVE_NO_MEMORY(policy_dir);
+
+ /* Create the directories */
+
+ rv = mkdir(policy_dir, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Could not create the policy dir: %s\n", policy_dir));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ tmp_str = talloc_asprintf(mem_ctx, "%s/User", policy_dir);
+ NT_STATUS_HAVE_NO_MEMORY(tmp_str);
+ rv = mkdir(tmp_str, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Could not create the User dir: %s\n", tmp_str));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ tmp_str = talloc_asprintf(mem_ctx, "%s/Machine", policy_dir);
+ NT_STATUS_HAVE_NO_MEMORY(tmp_str);
+ rv = mkdir(tmp_str, 0755);
+ if (rv < 0) {
+ DEBUG(0, ("Could not create the Machine dir: %s\n", tmp_str));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Create a GPT.INI with version 0 */
+
+ tmp_str = talloc_asprintf(mem_ctx, "%s/GPT.INI", policy_dir);
+ NT_STATUS_HAVE_NO_MEMORY(tmp_str);
+ fd = open(tmp_str, O_CREAT | O_WRONLY, 0644);
+ if (fd < 0) {
+ DEBUG(0, ("Could not create the GPT.INI: %s\n", tmp_str));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ rv = write(fd, file_content, strlen(file_content));
+ if (rv != strlen(file_content)) {
+ DEBUG(0, ("Short write in GPT.INI\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ close(fd);
+
+ /* Upload the GPT to the sysvol share on a DC */
+ status = gp_push_gpt(gp_ctx, policy_dir, file_sys_path);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_set_gpt_security_descriptor(struct gp_context *gp_ctx,
+ struct gp_object *gpo,
+ struct security_descriptor *sd)
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS status;
+ union smb_setfileinfo fileinfo;
+ union smb_open io;
+ union smb_close io_close;
+
+ /* Create a connection to sysvol if it is not already there */
+ if (gp_ctx->cli == NULL) {
+ status = gp_cli_connect(gp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create cli connection to DC\n"));
+ return status;
+ }
+ }
+
+ /* Create a forked memory context which can be freed easily */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Open the directory with NTCreate AndX call */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid.fnum = 0;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = gp_get_share_path(mem_ctx, gpo->file_sys_path);
+ status = smb_raw_open(gp_ctx->cli->tree, mem_ctx, &io);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Can't open GPT directory\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Set the security descriptor on the directory */
+ fileinfo.generic.level = RAW_FILEINFO_SEC_DESC;
+ fileinfo.set_secdesc.in.file.fnum = io.ntcreatex.out.file.fnum;
+ fileinfo.set_secdesc.in.secinfo_flags = SECINFO_PROTECTED_DACL |
+ SECINFO_OWNER |
+ SECINFO_GROUP |
+ SECINFO_DACL;
+ fileinfo.set_secdesc.in.sd = sd;
+ status = smb_raw_setfileinfo(gp_ctx->cli->tree, &fileinfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set security descriptor on the GPT\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Close the directory */
+ io_close.close.level = RAW_CLOSE_CLOSE;
+ io_close.close.in.file.fnum = io.ntcreatex.out.file.fnum;
+ io_close.close.in.write_time = 0;
+ status = smb_raw_close(gp_ctx->cli->tree, &io_close);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to close directory\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
diff --git a/source4/lib/policy/gp_ini.c b/source4/lib/policy/gp_ini.c
new file mode 100644
index 0000000000..d16011c722
--- /dev/null
+++ b/source4/lib/policy/gp_ini.c
@@ -0,0 +1,133 @@
+
+/*
+ * Unix SMB/CIFS implementation.
+ * Group Policy Object Support
+ * Copyright (C) Wilco Baan Hofman 2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include "includes.h"
+#include "lib/util/util.h"
+#include "lib/policy/policy.h"
+
+struct gp_parse_context {
+ struct gp_ini_context *ini;
+ int32_t cur_section;
+};
+
+
+static bool gp_add_ini_section(const char *name, void *callback_data)
+{
+ struct gp_parse_context *parse = callback_data;
+ struct gp_ini_context *ini = parse->ini;
+
+ ini->sections = talloc_realloc(ini, ini->sections, struct gp_ini_section, ini->num_sections+1);
+ if (ini->sections == NULL) return false;
+ ini->sections[ini->num_sections].name = talloc_strdup(ini, name);
+ if (ini->sections[ini->num_sections].name == NULL) return false;
+ parse->cur_section = ini->num_sections;
+ ini->num_sections++;
+
+ return true;
+}
+
+static bool gp_add_ini_param(const char *name, const char *value, void *callback_data)
+{
+ struct gp_parse_context *parse = callback_data;
+ struct gp_ini_context *ini = parse->ini;
+ struct gp_ini_section *section;
+
+ if (parse->cur_section == -1) {
+ return false;
+ }
+
+ section = &ini->sections[parse->cur_section];
+
+ section->params = talloc_realloc(ini, ini->sections[parse->cur_section].params, struct gp_ini_param, section->num_params+1);
+ if (section->params == NULL) return false;
+ section->params[section->num_params].name = talloc_strdup(ini, name);
+ if (section->params[section->num_params].name == NULL) return false;
+ section->params[section->num_params].value = talloc_strdup(ini, value);
+ if (section->params[section->num_params].value == NULL) return false;
+ section->num_params++;
+
+ return true;
+}
+
+NTSTATUS gp_parse_ini(TALLOC_CTX *mem_ctx, struct gp_context *gp_ctx, const char *filename, struct gp_ini_context **ret)
+{
+ struct gp_parse_context parse;
+ bool rv;
+
+ parse.ini = talloc_zero(mem_ctx, struct gp_ini_context);
+ NT_STATUS_HAVE_NO_MEMORY(parse.ini);
+ parse.cur_section = -1;
+
+ rv = pm_process(filename, gp_add_ini_section, gp_add_ini_param, &parse);
+ if (!rv) {
+ DEBUG(0, ("Error while processing ini file %s\n", filename));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ *ret = parse.ini;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_get_ini_string(struct gp_ini_context *ini, const char *section, const char *name, char **ret)
+{
+ uint16_t i;
+ int32_t cur_sec = -1;
+ for (i = 0; i < ini->num_sections; i++) {
+ if (strcmp(ini->sections[i].name, section) == 0) {
+ cur_sec = i;
+ break;
+ }
+ }
+
+ if (cur_sec == -1) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ for (i = 0; i < ini->sections[cur_sec].num_params; i++) {
+ if (strcmp(ini->sections[cur_sec].params[i].name, name) == 0) {
+ *ret = ini->sections[cur_sec].params[i].value;
+ return NT_STATUS_OK;
+ }
+ }
+ return NT_STATUS_NOT_FOUND;
+}
+
+NTSTATUS gp_get_ini_uint(struct gp_ini_context *ini, const char *section, const char *name, uint32_t *ret)
+{
+ uint16_t i;
+ int32_t cur_sec = -1;
+ for (i = 0; i < ini->num_sections; i++) {
+ if (strcmp(ini->sections[i].name, section) == 0) {
+ cur_sec = i;
+ break;
+ }
+ }
+
+ if (cur_sec == -1) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ for (i = 0; i < ini->sections[cur_sec].num_params; i++) {
+ if (strcmp(ini->sections[cur_sec].params[i].name, name) == 0) {
+ *ret = atol(ini->sections[cur_sec].params[i].value);
+ return NT_STATUS_OK;
+ }
+ }
+ return NT_STATUS_NOT_FOUND;
+}
diff --git a/source4/lib/policy/gp_ldap.c b/source4/lib/policy/gp_ldap.c
new file mode 100644
index 0000000000..091af2ee16
--- /dev/null
+++ b/source4/lib/policy/gp_ldap.c
@@ -0,0 +1,1038 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Group Policy Object Support
+ * Copyright (C) Jelmer Vernooij 2008
+ * Copyright (C) Wilco Baan Hofman 2008-2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include "includes.h"
+#include "param/param.h"
+#include <ldb.h>
+#include "lib/ldb-samba/ldb_wrap.h"
+#include "auth/credentials/credentials.h"
+#include "../librpc/gen_ndr/nbt.h"
+#include "libcli/libcli.h"
+#include "libnet/libnet.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "../libcli/security/security.h"
+#include "libcli/ldap/ldap_ndr.h"
+#include "../lib/talloc/talloc.h"
+#include "lib/policy/policy.h"
+
+struct gpo_stringmap {
+ const char *str;
+ uint32_t flags;
+};
+static const struct gpo_stringmap gplink_options [] = {
+ { "GPLINK_OPT_DISABLE", GPLINK_OPT_DISABLE },
+ { "GPLINK_OPT_ENFORCE", GPLINK_OPT_ENFORCE },
+ { NULL, 0 }
+};
+static const struct gpo_stringmap gpo_flags [] = {
+ { "GPO_FLAG_USER_DISABLE", GPO_FLAG_USER_DISABLE },
+ { "GPO_FLAG_MACHINE_DISABLE", GPO_FLAG_MACHINE_DISABLE },
+ { NULL, 0 }
+};
+static const struct gpo_stringmap gpo_inheritance [] = {
+ { "GPO_INHERIT", GPO_INHERIT },
+ { "GPO_BLOCK_INHERITANCE", GPO_BLOCK_INHERITANCE },
+ { NULL, 0 }
+};
+
+
+static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret)
+{
+ struct gp_object *gpo = talloc(mem_ctx, struct gp_object);
+ enum ndr_err_code ndr_err;
+ const DATA_BLOB *data;
+
+ NT_STATUS_HAVE_NO_MEMORY(gpo);
+
+ gpo->dn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(msg->dn));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, gpo);
+
+ DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn));
+
+ gpo->display_name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "displayName", ""));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->display_name, gpo);
+
+ gpo->name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "name", ""));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->name, gpo);
+
+ gpo->flags = ldb_msg_find_attr_as_uint(msg, "flags", 0);
+ gpo->version = ldb_msg_find_attr_as_uint(msg, "versionNumber", 0);
+
+ gpo->file_sys_path = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "gPCFileSysPath", ""));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->file_sys_path, gpo);
+
+ /* Pull the security descriptor through the NDR library */
+ data = ldb_msg_find_ldb_val(msg, "nTSecurityDescriptor");
+ gpo->security_descriptor = talloc(gpo, struct security_descriptor);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->security_descriptor, gpo);
+
+ ndr_err = ndr_pull_struct_blob(data,
+ mem_ctx,
+ gpo->security_descriptor,
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ *ret = gpo;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret)
+{
+ unsigned int i, count=0;
+ const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
+
+ NT_STATUS_HAVE_NO_MEMORY(flag_strs);
+
+ flag_strs[0] = NULL;
+
+ for (i = 0; gpo_flags[i].str != NULL; i++) {
+ if (flags & gpo_flags[i].flags) {
+ flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
+ NT_STATUS_HAVE_NO_MEMORY(flag_strs);
+ flag_strs[count] = gpo_flags[i].str;
+ flag_strs[count+1] = NULL;
+ count++;
+ }
+ }
+ *ret = flag_strs;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t options, const char ***ret)
+{
+ unsigned int i, count=0;
+ const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
+
+ NT_STATUS_HAVE_NO_MEMORY(flag_strs);
+ flag_strs[0] = NULL;
+
+ for (i = 0; gplink_options[i].str != NULL; i++) {
+ if (options & gplink_options[i].flags) {
+ flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
+ NT_STATUS_HAVE_NO_MEMORY(flag_strs);
+ flag_strs[count] = gplink_options[i].str;
+ flag_strs[count+1] = NULL;
+ count++;
+ }
+ }
+ *ret = flag_strs;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_init(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct cli_credentials *credentials,
+ struct tevent_context *ev_ctx,
+ struct gp_context **gp_ctx)
+{
+
+ struct libnet_LookupDCs *io;
+ char *url;
+ struct libnet_context *net_ctx;
+ struct ldb_context *ldb_ctx;
+ NTSTATUS rv;
+
+ /* Initialise the libnet context */
+ net_ctx = libnet_context_init(ev_ctx, lp_ctx);
+ net_ctx->cred = credentials;
+
+ /* Prepare libnet lookup structure for looking a DC (PDC is correct). */
+ io = talloc_zero(mem_ctx, struct libnet_LookupDCs);
+ NT_STATUS_HAVE_NO_MEMORY(io);
+ io->in.name_type = NBT_NAME_PDC;
+ io->in.domain_name = lpcfg_workgroup(lp_ctx);
+
+ /* Find Active DC's */
+ rv = libnet_LookupDCs(net_ctx, mem_ctx, io);
+ if (!NT_STATUS_IS_OK(rv)) {
+ DEBUG(0, ("Failed to lookup DCs in domain\n"));
+ return rv;
+ }
+
+ /* Connect to ldap://DC_NAME with all relevant contexts*/
+ url = talloc_asprintf(mem_ctx, "ldap://%s", io->out.dcs[0].name);
+ NT_STATUS_HAVE_NO_MEMORY(url);
+ ldb_ctx = ldb_wrap_connect(mem_ctx, net_ctx->event_ctx, lp_ctx,
+ url, NULL, net_ctx->cred, 0);
+ if (ldb_ctx == NULL) {
+ DEBUG(0, ("Can't connect to DC's LDAP with url %s\n", url));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+
+ *gp_ctx = talloc_zero(mem_ctx, struct gp_context);
+ NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
+
+ (*gp_ctx)->lp_ctx = lp_ctx;
+ (*gp_ctx)->credentials = credentials;
+ (*gp_ctx)->ev_ctx = ev_ctx;
+ (*gp_ctx)->ldb_ctx = ldb_ctx;
+ (*gp_ctx)->active_dc = io->out.dcs[0];
+
+ /* We don't need to keep the libnet context */
+ talloc_free(net_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
+{
+ struct ldb_result *result;
+ int rv;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_dn *dn;
+ struct gp_object **gpo;
+ unsigned int i; /* same as in struct ldb_result */
+ const char **attrs;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Create full ldb dn of the policies base object */
+ dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
+ rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System"));
+ if (!rv) {
+ DEBUG(0, ("Can't append subtree to DN\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
+
+ attrs = talloc_array(mem_ctx, const char *, 7);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
+
+ attrs[0] = "nTSecurityDescriptor";
+ attrs[1] = "versionNumber";
+ attrs[2] = "flags";
+ attrs[3] = "name";
+ attrs[4] = "displayName";
+ attrs[5] = "gPCFileSysPath";
+ attrs[6] = NULL;
+
+ rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, attrs, "(objectClass=groupPolicyContainer)");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo, mem_ctx);
+
+ gpo[result->count] = NULL;
+
+ for (i = 0; i < result->count; i++) {
+ status = parse_gpo(gp_ctx, result->msgs[i], &gpo[i]);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to parse GPO.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+ }
+
+ talloc_free(mem_ctx);
+
+ *ret = gpo;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
+{
+ struct ldb_result *result;
+ struct ldb_dn *dn;
+ struct gp_object *gpo;
+ int rv;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ const char **attrs;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Create an ldb dn struct for the dn string */
+ dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ attrs = talloc_array(mem_ctx, const char *, 7);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
+
+ attrs[0] = "nTSecurityDescriptor";
+ attrs[1] = "versionNumber";
+ attrs[2] = "flags";
+ attrs[3] = "name";
+ attrs[4] = "displayName";
+ attrs[5] = "gPCFileSysPath";
+ attrs[6] = NULL;
+
+ rv = ldb_search(gp_ctx->ldb_ctx,
+ mem_ctx,
+ &result,
+ dn,
+ LDB_SCOPE_BASE,
+ attrs,
+ "objectClass=groupPolicyContainer");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* We expect exactly one record */
+ if (result->count != 1) {
+ DEBUG(0, ("Could not find GPC with dn %s\n", dn_str));
+ talloc_free(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ status = parse_gpo(gp_ctx, result->msgs[0], &gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to parse GPO.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+
+ *ret = gpo;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
+{
+ int start, idx=0;
+ int pos;
+ struct gp_link **gplinks;
+ char *buf, *end;
+ const char *gplink_start = "[LDAP://";
+
+ gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
+ NT_STATUS_HAVE_NO_MEMORY(gplinks);
+
+ gplinks[0] = NULL;
+
+ /* Assuming every gPLink starts with "[LDAP://" */
+ start = strlen(gplink_start);
+
+ for (pos = start; pos < strlen(gplink_str); pos++) {
+ if (gplink_str[pos] == ';') {
+ gplinks = talloc_realloc(mem_ctx, gplinks, struct gp_link *, idx+2);
+ NT_STATUS_HAVE_NO_MEMORY(gplinks);
+ gplinks[idx] = talloc(mem_ctx, struct gp_link);
+ NT_STATUS_HAVE_NO_MEMORY(gplinks[idx]);
+ gplinks[idx]->dn = talloc_strndup(mem_ctx,
+ gplink_str + start,
+ pos - start);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplinks[idx]->dn, gplinks);
+
+ for (start = pos + 1; gplink_str[pos] != ']'; pos++);
+
+ buf = talloc_strndup(gplinks, gplink_str + start, pos - start);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(buf, gplinks);
+ gplinks[idx]->options = (uint32_t) strtoll(buf, &end, 0);
+ talloc_free(buf);
+
+ /* Set the last entry in the array to be NULL */
+ gplinks[idx + 1] = NULL;
+
+ /* Increment the array index, the string position past
+ the next "[LDAP://", and set the start reference */
+ idx++;
+ pos += strlen(gplink_start)+1;
+ start = pos;
+ }
+ }
+
+ *ret = gplinks;
+ return NT_STATUS_OK;
+}
+
+
+NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
+{
+ TALLOC_CTX *mem_ctx;
+ struct ldb_dn *dn;
+ struct ldb_result *result;
+ struct gp_link **gplinks;
+ char *gplink_str;
+ int rv;
+ unsigned int i, j;
+ NTSTATUS status;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ for (i = 0; i < result->count; i++) {
+ for (j = 0; j < result->msgs[i]->num_elements; j++) {
+ struct ldb_message_element *element = &result->msgs[i]->elements[j];
+
+ if (strcmp(element->name, "gPLink") == 0) {
+ SMB_ASSERT(element->num_values > 0);
+ gplink_str = talloc_strdup(mem_ctx, (char *) element->values[0].data);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
+ goto found;
+ }
+ }
+ }
+ gplink_str = talloc_strdup(mem_ctx, "");
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
+
+ found:
+
+ status = parse_gplink(gp_ctx, gplink_str, &gplinks);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to parse gPLink\n"));
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+
+ *ret = gplinks;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
+{
+ TALLOC_CTX *mem_ctx;
+ const char **gpos;
+ struct ldb_result *result;
+ char *sid;
+ struct ldb_dn *dn;
+ struct ldb_message_element *element;
+ bool inherit;
+ const char *attrs[] = { "objectClass", NULL };
+ int rv;
+ NTSTATUS status;
+ unsigned int count = 0;
+ unsigned int i;
+ enum {
+ ACCOUNT_TYPE_USER = 0,
+ ACCOUNT_TYPE_MACHINE = 1
+ } account_type;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ sid = ldap_encode_ndr_dom_sid(mem_ctx,
+ &token->sids[PRIMARY_USER_SID_INDEX]);
+ NT_STATUS_HAVE_NO_MEMORY(sid);
+
+ /* Find the user DN and objectclass via the sid from the security token */
+ rv = ldb_search(gp_ctx->ldb_ctx,
+ mem_ctx,
+ &result,
+ ldb_get_default_basedn(gp_ctx->ldb_ctx),
+ LDB_SCOPE_SUBTREE,
+ attrs,
+ "(&(objectclass=user)(objectSid=%s))", sid);
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
+ ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (result->count != 1) {
+ DEBUG(0, ("Could not find user with sid %s.\n", sid));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
+
+ element = ldb_msg_find_element(result->msgs[0], "objectClass");
+
+ /* We need to know if this account is a user or machine. */
+ account_type = ACCOUNT_TYPE_USER;
+ for (i = 0; i < element->num_values; i++) {
+ if (strcmp((char *)element->values[i].data, "computer") == 0) {
+ account_type = ACCOUNT_TYPE_MACHINE;
+ DEBUG(10, ("This user is a machine\n"));
+ }
+ }
+
+ gpos = talloc_array(gp_ctx, const char *, 1);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
+ gpos[0] = NULL;
+
+ /* Walk through the containers until we hit the root */
+ inherit = 1;
+ dn = ldb_dn_get_parent(mem_ctx, result->msgs[0]->dn);
+ while (ldb_dn_compare_base(ldb_get_default_basedn(gp_ctx->ldb_ctx), dn) == 0) {
+ const char *gpo_attrs[] = { "gPLink", "gPOptions", NULL };
+ struct gp_link **gplinks;
+ enum gpo_inheritance gpoptions;
+
+ DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
+
+ /* Get the gPLink and gPOptions attributes from the container */
+ rv = ldb_search(gp_ctx->ldb_ctx,
+ mem_ctx,
+ &result,
+ dn,
+ LDB_SCOPE_BASE,
+ gpo_attrs,
+ "objectclass=*");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
+ ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Parse the gPLink attribute, put it into a nice struct array */
+ status = parse_gplink(mem_ctx, ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""), &gplinks);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to parse gPLink\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Check all group policy links on this container */
+ for (i = 0; gplinks[i] != NULL; i++) {
+ struct gp_object *gpo;
+ uint32_t access_granted;
+
+ /* If inheritance was blocked at a higher level and this
+ * gplink is not enforced, it should not be applied */
+ if (!inherit && !(gplinks[i]->options & GPLINK_OPT_ENFORCE))
+ continue;
+
+ /* Don't apply disabled links */
+ if (gplinks[i]->options & GPLINK_OPT_DISABLE)
+ continue;
+
+ /* Get GPO information */
+ status = gp_get_gpo_info(gp_ctx, gplinks[i]->dn, &gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to get gpo information for %s\n", gplinks[i]->dn));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* If the account does not have read access, this GPO does not apply
+ * to this account */
+ status = se_access_check(gpo->security_descriptor,
+ token,
+ (SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
+ &access_granted);
+ if (!NT_STATUS_IS_OK(status)) {
+ continue;
+ }
+
+ /* If the account is a user and the GPO has user disabled flag, or
+ * a machine and the GPO has machine disabled flag, this GPO does
+ * not apply to this account */
+ if ((account_type == ACCOUNT_TYPE_USER &&
+ (gpo->flags & GPO_FLAG_USER_DISABLE)) ||
+ (account_type == ACCOUNT_TYPE_MACHINE &&
+ (gpo->flags & GPO_FLAG_MACHINE_DISABLE))) {
+ continue;
+ }
+
+ /* Add the GPO to the list */
+ gpos = talloc_realloc(gp_ctx, gpos, const char *, count+2);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
+ gpos[count] = talloc_strdup(gp_ctx, gplinks[i]->dn);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos[count], mem_ctx);
+ gpos[count+1] = NULL;
+ count++;
+
+ /* Clean up */
+ talloc_free(gpo);
+ }
+
+ /* If inheritance is blocked, then we should only add enforced gPLinks
+ * higher up */
+ gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
+ if (gpoptions == GPO_BLOCK_INHERITANCE) {
+ inherit = 0;
+ }
+ dn = ldb_dn_get_parent(mem_ctx, dn);
+ }
+
+ talloc_free(mem_ctx);
+
+ *ret = gpos;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
+{
+ TALLOC_CTX *mem_ctx;
+ struct ldb_result *result;
+ struct ldb_dn *dn;
+ struct ldb_message *msg;
+ const char *attrs[] = { "gPLink", NULL };
+ const char *gplink_str;
+ int rv;
+ char *start;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (result->count != 1) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
+
+ /* If this GPO link already exists, alter the options, else add it */
+ if ((start = strcasestr(gplink_str, gplink->dn)) != NULL) {
+ start += strlen(gplink->dn);
+ *start = '\0';
+ start++;
+ while (*start != ']' && *start != '\0') {
+ start++;
+ }
+ gplink_str = talloc_asprintf(mem_ctx, "%s;%d%s", gplink_str, gplink->options, start);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
+
+ } else {
+ /* Prepend the new GPO link to the string. This list is backwards in priority. */
+ gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
+ }
+
+
+
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = dn;
+
+ rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_modify(gp_ctx->ldb_ctx, msg);
+ if (rv != 0) {
+ DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
+{
+ TALLOC_CTX *mem_ctx;
+ struct ldb_result *result;
+ struct ldb_dn *dn;
+ struct ldb_message *msg;
+ const char *attrs[] = { "gPLink", NULL };
+ const char *gplink_str, *search_string;
+ int rv;
+ char *p;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (result->count != 1) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
+
+ /* If this GPO link already exists, alter the options, else add it */
+ search_string = talloc_asprintf(mem_ctx, "[LDAP://%s]", gplink_dn);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(search_string, mem_ctx);
+
+ p = strcasestr(gplink_str, search_string);
+ if (p == NULL) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ *p = '\0';
+ p++;
+ while (*p != ']' && *p != '\0') {
+ p++;
+ }
+ p++;
+ gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
+
+
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = dn;
+
+ if (strcmp(gplink_str, "") == 0) {
+ rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ } else {
+ rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+ }
+ rv = ldb_modify(gp_ctx->ldb_ctx, msg);
+ if (rv != 0) {
+ DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
+{
+ TALLOC_CTX *mem_ctx;
+ struct ldb_result *result;
+ struct ldb_dn *dn;
+ const char *attrs[] = { "gPOptions", NULL };
+ int rv;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (result->count != 1) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ *inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
+{
+ char *inheritance_string;
+ struct ldb_message *msg;
+ int rv;
+
+ msg = ldb_msg_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(msg);
+
+ msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
+
+ inheritance_string = talloc_asprintf(msg, "%d", inheritance);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(inheritance_string, msg);
+
+ rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
+ talloc_free(msg);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_modify(gp_ctx->ldb_ctx, msg);
+ if (rv != 0) {
+ DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
+ talloc_free(msg);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ talloc_free(msg);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
+{
+ struct ldb_message *msg;
+ TALLOC_CTX *mem_ctx;
+ int rv;
+ char *dn_str, *flags_str, *version_str;
+ struct ldb_dn *child_dn, *gpo_dn;
+
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* CN={GUID} */
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
+ dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dn_str, mem_ctx);
+
+ child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+ rv = ldb_dn_add_child(msg->dn, child_dn);
+ if (!rv) goto ldb_msg_add_error;
+
+ flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(flags_str, mem_ctx);
+
+ version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(version_str, mem_ctx);
+
+ rv = ldb_msg_add_string(msg, "objectClass", "top");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "objectClass", "container");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "name", gpo->name);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "CN", gpo->name);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "flags", flags_str);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "versionNumber", version_str);
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+
+ rv = ldb_add(gp_ctx->ldb_ctx, msg);
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ gpo_dn = msg->dn;
+
+ /* CN=User */
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
+ child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User");
+ rv = ldb_dn_add_child(msg->dn, child_dn);
+ if (!rv) goto ldb_msg_add_error;
+
+ rv = ldb_msg_add_string(msg, "objectClass", "top");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "objectClass", "container");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "CN", "User");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "name", "User");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+
+ rv = ldb_add(gp_ctx->ldb_ctx, msg);
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* CN=Machine */
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
+ child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine");
+ rv = ldb_dn_add_child(msg->dn, child_dn);
+ if (!rv) goto ldb_msg_add_error;
+
+ rv = ldb_msg_add_string(msg, "objectClass", "top");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "objectClass", "container");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "CN", "Machine");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+ rv = ldb_msg_add_string(msg, "name", "Machine");
+ if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
+
+ rv = ldb_add(gp_ctx->ldb_ctx, msg);
+ if (rv != LDB_SUCCESS) {
+ DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, mem_ctx);
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+
+ ldb_msg_add_error:
+ DEBUG(0, ("LDB Error adding element to ldb message\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
+{
+ TALLOC_CTX *mem_ctx;
+ DATA_BLOB data;
+ enum ndr_err_code ndr_err;
+ struct ldb_message *msg;
+ int rv;
+
+ /* Create a forked memory context to clean up easily */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Push the security descriptor through the NDR library */
+ ndr_err = ndr_push_struct_blob(&data,
+ mem_ctx,
+ sd,
+ (ndr_push_flags_fn_t)ndr_push_security_descriptor);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+
+ /* Create a LDB message */
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
+
+ rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_modify(gp_ctx->ldb_ctx, msg);
+ if (rv != 0) {
+ DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+/* This function sets flags, version and displayName on a GPO */
+NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
+{
+ int rv;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_message *msg;
+ char *version_str, *flags_str;
+
+ mem_ctx = talloc_new(gp_ctx);
+
+ msg = ldb_msg_new(mem_ctx);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
+
+ version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
+
+ rv = ldb_msg_add_string(msg, "flags", flags_str);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed for flags: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_msg_add_string(msg, "version", version_str);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed for version: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
+ if (rv != 0) {
+ DEBUG(0, ("LDB message add string failed for displayName: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
+
+ rv = ldb_modify(gp_ctx->ldb_ctx, msg);
+ if (rv != 0) {
+ DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
diff --git a/source4/lib/policy/gp_manage.c b/source4/lib/policy/gp_manage.c
new file mode 100644
index 0000000000..f2d32431df
--- /dev/null
+++ b/source4/lib/policy/gp_manage.c
@@ -0,0 +1,295 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Group Policy Object Support
+ * Copyright (C) Wilco Baan Hofman 2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include "includes.h"
+#include "../libcli/security/dom_sid.h"
+#include "../libcli/security/security_descriptor.h"
+#include "../librpc/ndr/libndr.h"
+#include "../lib/util/charset/charset.h"
+#include "param/param.h"
+#include "lib/policy/policy.h"
+
+static uint32_t gp_ads_to_dir_access_mask(uint32_t access_mask)
+{
+ uint32_t fs_mask;
+
+ /* Copy the standard access mask */
+ fs_mask = access_mask & 0x001F0000;
+
+ /* When READ_PROP and LIST_CONTENTS are set, read access is granted on the GPT */
+ if (access_mask & SEC_ADS_READ_PROP && access_mask & SEC_ADS_LIST) {
+ fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_LIST | SEC_DIR_READ_ATTRIBUTE |
+ SEC_DIR_READ_EA | SEC_DIR_TRAVERSE;
+ }
+
+ /* When WRITE_PROP is set, full write access is granted on the GPT */
+ if (access_mask & SEC_ADS_WRITE_PROP) {
+ fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_WRITE_ATTRIBUTE |
+ SEC_DIR_WRITE_EA | SEC_DIR_ADD_FILE |
+ SEC_DIR_ADD_SUBDIR;
+ }
+
+ /* Map CREATE_CHILD to add file and add subdir */
+ if (access_mask & SEC_ADS_CREATE_CHILD)
+ fs_mask |= SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR;
+
+ /* Map ADS delete child to dir delete child */
+ if (access_mask & SEC_ADS_DELETE_CHILD)
+ fs_mask |= SEC_DIR_DELETE_CHILD;
+
+ return fs_mask;
+}
+
+NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret)
+{
+ struct security_descriptor *fs_sd;
+ NTSTATUS status;
+ uint32_t i;
+
+ /* Allocate the file system security descriptor */
+ fs_sd = talloc(mem_ctx, struct security_descriptor);
+ NT_STATUS_HAVE_NO_MEMORY(fs_sd);
+
+ /* Copy the basic information from the directory server security descriptor */
+ fs_sd->owner_sid = talloc_memdup(fs_sd, ds_sd->owner_sid, sizeof(struct dom_sid));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(fs_sd->owner_sid, fs_sd);
+
+ fs_sd->group_sid = talloc_memdup(fs_sd, ds_sd->group_sid, sizeof(struct dom_sid));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(fs_sd->group_sid, fs_sd);
+
+ fs_sd->type = ds_sd->type;
+ fs_sd->revision = ds_sd->revision;
+
+ /* Copy the sacl */
+ fs_sd->sacl = security_acl_dup(fs_sd, ds_sd->sacl);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(fs_sd->sacl, fs_sd);
+
+ /* Copy the dacl */
+ fs_sd->dacl = talloc_zero(fs_sd, struct security_acl);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(fs_sd->dacl, fs_sd);
+
+ for (i = 0; i < ds_sd->dacl->num_aces; i++) {
+ char *trustee = dom_sid_string(fs_sd, &ds_sd->dacl->aces[i].trustee);
+ struct security_ace *ace;
+
+ /* Don't add the allow for SID_BUILTIN_PREW2K */
+ if (!(ds_sd->dacl->aces[i].type & SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) &&
+ strcmp(trustee, SID_BUILTIN_PREW2K) == 0) {
+ talloc_free(trustee);
+ continue;
+ }
+
+ /* Copy the ace from the directory server security descriptor */
+ ace = talloc_memdup(fs_sd, &ds_sd->dacl->aces[i], sizeof(struct security_ace));
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ace, fs_sd);
+
+ /* Set specific inheritance flags for within the GPO */
+ ace->flags |= SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT;
+ if (strcmp(trustee, SID_CREATOR_OWNER) == 0) {
+ ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ /* Get a directory access mask from the assigned access mask on the LDAP object */
+ ace->access_mask = gp_ads_to_dir_access_mask(ace->access_mask);
+
+ /* Add the ace to the security descriptor DACL */
+ status = security_descriptor_dacl_add(fs_sd, ace);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to add a dacl to file system security descriptor\n"));
+ return status;
+ }
+
+ /* Clean up the allocated data in this iteration */
+ talloc_free(trustee);
+ }
+
+ *ret = fs_sd;
+ return NT_STATUS_OK;
+}
+
+
+NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret)
+{
+ struct GUID guid_struct;
+ char *guid_str;
+ char *name;
+ struct security_descriptor *sd;
+ TALLOC_CTX *mem_ctx;
+ struct gp_object *gpo;
+ NTSTATUS status;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Create the gpo struct to return later */
+ gpo = talloc(gp_ctx, struct gp_object);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo, mem_ctx);
+
+ /* Generate a GUID */
+ guid_struct = GUID_random();
+ guid_str = GUID_string2(mem_ctx, &guid_struct);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(guid_str, mem_ctx);
+ name = strupper_talloc(mem_ctx, guid_str);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(name, mem_ctx);
+
+ /* Prepare the GPO struct */
+ gpo->dn = NULL;
+ gpo->name = name;
+ gpo->flags = 0;
+ gpo->version = 0;
+ gpo->display_name = talloc_strdup(gpo, display_name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->display_name, mem_ctx);
+
+ gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lpcfg_dnsdomain(gp_ctx->lp_ctx), lpcfg_dnsdomain(gp_ctx->lp_ctx), name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->file_sys_path, mem_ctx);
+
+ /* Create the GPT */
+ status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create GPT\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+
+ /* Create the LDAP GPO, including CN=User and CN=Machine */
+ status = gp_create_ldap_gpo(gp_ctx, gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create LDAP group policy object\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Get the new security descriptor */
+ status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to fetch LDAP group policy object\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Create matching file and DS security descriptors */
+ status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Set the security descriptor on the filesystem for this GPO */
+ status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+
+ *ret = gpo;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
+{
+ TALLOC_CTX *mem_ctx;
+ struct security_descriptor *fs_sd;
+ struct gp_object *gpo;
+ NTSTATUS status;
+
+ /* Create a forked memory context, as a base for everything here */
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Set the ACL on LDAP database */
+ status = gp_set_ads_acl(gp_ctx, dn_str, sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set ACL on ADS\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Get the group policy object information, for filesystem location and merged sd */
+ status = gp_get_gpo_info(gp_ctx, dn_str, &gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set ACL on ADS\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Create matching file and DS security descriptors */
+ status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &fs_sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Set the security descriptor on the filesystem for this GPO */
+ status = gp_set_gpt_security_descriptor(gp_ctx, gpo, fs_sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS gp_push_gpo (struct gp_context *gp_ctx, const char *local_path, struct gp_object *gpo)
+{
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ struct gp_ini_context *ini;
+ char *filename;
+
+ mem_ctx = talloc_new(gp_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ /* Get version from ini file */
+ /* FIXME: The local file system may be case sensitive */
+ filename = talloc_asprintf(mem_ctx, "%s/%s", local_path, "GPT.INI");
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filename, mem_ctx);
+ status = gp_parse_ini(mem_ctx, gp_ctx, local_path, &ini);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to parse GPT.INI.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Push the GPT to the remote sysvol */
+ status = gp_push_gpt(gp_ctx, local_path, gpo->file_sys_path);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to push GPT to DC's sysvol share.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* Write version to LDAP */
+ status = gp_set_ldap_gpo(gp_ctx, gpo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to set GPO options in DC's LDAP.\n"));
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
diff --git a/source4/lib/policy/policy.h b/source4/lib/policy/policy.h
new file mode 100644
index 0000000000..d22c3d6a9d
--- /dev/null
+++ b/source4/lib/policy/policy.h
@@ -0,0 +1,127 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Group Policy Object Support
+ * Copyright (C) Guenther Deschner 2005-2008 (from samba 3 gpo.h)
+ * Copyright (C) Wilco Baan Hofman 2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __POLICY_H__
+#define __POLICY_H__
+#include "libcli/libcli.h"
+
+#define GPLINK_OPT_DISABLE (1 << 0)
+#define GPLINK_OPT_ENFORCE (1 << 1)
+
+
+#define GPO_FLAG_USER_DISABLE (1 << 0)
+#define GPO_FLAG_MACHINE_DISABLE (1 << 1)
+
+struct security_token;
+
+enum gpo_inheritance {
+ GPO_INHERIT = 0,
+ GPO_BLOCK_INHERITANCE = 1,
+};
+
+struct gp_context {
+ struct ldb_context *ldb_ctx;
+ struct loadparm_context *lp_ctx;
+ struct cli_credentials *credentials;
+ struct tevent_context *ev_ctx;
+ struct smbcli_state *cli;
+ struct nbt_dc_name active_dc;
+};
+
+struct gp_object {
+ uint32_t version;
+ uint32_t flags;
+ const char *display_name;
+ const char *name;
+ const char *dn;
+ const char *file_sys_path;
+ struct security_descriptor *security_descriptor;
+};
+
+
+struct gp_link {
+ uint32_t options;
+ const char *dn;
+};
+
+struct gp_ini_param {
+ char *name;
+ char *value;
+};
+
+struct gp_ini_section {
+ char *name;
+ uint16_t num_params;
+ struct gp_ini_param *params;
+};
+
+struct gp_ini_context {
+ uint16_t num_sections;
+ struct gp_ini_section *sections;
+};
+
+NTSTATUS gp_init(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct cli_credentials *creds,
+ struct tevent_context *ev_ctx,
+ struct gp_context **gp_ctx);
+
+
+/* LDAP functions */
+NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret);
+NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *req_dn, struct gp_link ***ret);
+NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret);
+
+NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret);
+NTSTATUS gp_set_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object *gpo);
+NTSTATUS gp_del_gpo(struct gp_context *gp_ctx, const char *dn_str);
+
+
+NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret);
+NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret);
+
+NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink);
+NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gp_dn);
+NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance);
+NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance);
+
+NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo);
+NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd);
+NTSTATUS gp_push_gpo (struct gp_context *gp_ctx, const char *local_path, struct gp_object *gpo);
+NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo);
+
+/* File system functions */
+NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo, const char **path);
+NTSTATUS gp_create_gpt(struct gp_context *gp_ctx, const char *name, const char *file_sys_path);
+NTSTATUS gp_set_gpt_security_descriptor(struct gp_context *gp_ctx, struct gp_object *gpo, struct security_descriptor *sd);
+NTSTATUS gp_push_gpt(struct gp_context *gp_ctx, const char *local_path,
+ const char *file_sys_path);
+
+/* Ini functions */
+NTSTATUS gp_parse_ini(TALLOC_CTX *mem_ctx, struct gp_context *gp_ctx, const char *filename, struct gp_ini_context **ret);
+NTSTATUS gp_get_ini_string(struct gp_ini_context *ini, const char *section, const char *name, char **ret);
+NTSTATUS gp_get_ini_uint(struct gp_ini_context *ini, const char *section, const char *name, uint32_t *ret);
+
+/* Managing functions */
+NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret);
+NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret);
+NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd);
+
+#endif
diff --git a/source4/lib/policy/policy.pc.in b/source4/lib/policy/policy.pc.in
new file mode 100644
index 0000000000..fe5c66d987
--- /dev/null
+++ b/source4/lib/policy/policy.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: policy
+Description: Active Directory Group Policy library
+Requires: talloc
+Requires.private: ldb
+Version: @PACKAGE_VERSION@
+Libs: @LIB_RPATH@ -L${libdir} -lpolicy
+Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
diff --git a/source4/lib/policy/pypolicy.c b/source4/lib/policy/pypolicy.c
new file mode 100644
index 0000000000..7df5081d66
--- /dev/null
+++ b/source4/lib/policy/pypolicy.c
@@ -0,0 +1,133 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Python bindings for libpolicy
+ * Copyright (C) Jelmer Vernooij 2010
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <Python.h>
+#include "includes.h"
+#include "policy.h"
+#include "libcli/util/pyerrors.h"
+
+static PyObject *py_get_gpo_flags(PyObject *self, PyObject *args)
+{
+ int flags;
+ PyObject *py_ret;
+ const char **ret;
+ TALLOC_CTX *mem_ctx;
+ int i;
+ NTSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "i", &flags))
+ return NULL;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ status = gp_get_gpo_flags(mem_ctx, flags, &ret);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetNTSTATUS(status);
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ py_ret = PyList_New(0);
+ for (i = 0; ret[i]; i++) {
+ PyObject *item = PyString_FromString(ret[i]);
+ if (item == NULL) {
+ talloc_free(mem_ctx);
+ Py_DECREF(py_ret);
+ PyErr_NoMemory();
+ return NULL;
+ }
+ PyList_Append(py_ret, item);
+ }
+
+ talloc_free(mem_ctx);
+
+ return py_ret;
+}
+
+static PyObject *py_get_gplink_options(PyObject *self, PyObject *args)
+{
+ int flags;
+ PyObject *py_ret;
+ const char **ret;
+ TALLOC_CTX *mem_ctx;
+ int i;
+ NTSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "i", &flags))
+ return NULL;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ status = gp_get_gplink_options(mem_ctx, flags, &ret);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetNTSTATUS(status);
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ py_ret = PyList_New(0);
+ for (i = 0; ret[i]; i++) {
+ PyObject *item = PyString_FromString(ret[i]);
+ if (item == NULL) {
+ talloc_free(mem_ctx);
+ Py_DECREF(py_ret);
+ PyErr_NoMemory();
+ return NULL;
+ }
+ PyList_Append(py_ret, item);
+ }
+
+ talloc_free(mem_ctx);
+
+ return py_ret;
+}
+
+static PyMethodDef py_policy_methods[] = {
+ { "get_gpo_flags", (PyCFunction)py_get_gpo_flags, METH_VARARGS,
+ "get_gpo_flags(flags) -> list" },
+ { "get_gplink_options", (PyCFunction)py_get_gplink_options, METH_VARARGS,
+ "get_gplink_options(options) -> list" },
+ { NULL }
+};
+
+void initpolicy(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("policy", py_policy_methods, "(Group) Policy manipulation");
+ if (!m)
+ return;
+
+ PyModule_AddObject(m, "GPO_FLAG_USER_DISABLE",
+ PyInt_FromLong(GPO_FLAG_USER_DISABLE));
+ PyModule_AddObject(m, "GPO_MACHINE_USER_DISABLE",
+ PyInt_FromLong(GPO_FLAG_MACHINE_DISABLE));
+ PyModule_AddObject(m, "GPLINK_OPT_DISABLE",
+ PyInt_FromLong(GPLINK_OPT_DISABLE ));
+ PyModule_AddObject(m, "GPLINK_OPT_ENFORCE ",
+ PyInt_FromLong(GPLINK_OPT_ENFORCE ));
+}
diff --git a/source4/lib/policy/tests/python/bindings.py b/source4/lib/policy/tests/python/bindings.py
new file mode 100644
index 0000000000..b872d99cef
--- /dev/null
+++ b/source4/lib/policy/tests/python/bindings.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+# Unix SMB/CIFS implementation.
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+"""Tests for the libpolicy Python bindings.
+
+"""
+
+import unittest
+from samba import policy
+
+class PolicyTests(unittest.TestCase):
+
+ def test_get_gpo_flags(self):
+ self.assertEquals(["GPO_FLAG_USER_DISABLE"],
+ policy.get_gpo_flags(policy.GPO_FLAG_USER_DISABLE))
+
+ def test_get_gplink_options(self):
+ self.assertEquals(["GPLINK_OPT_DISABLE"],
+ policy.get_gplink_options(policy.GPLINK_OPT_DISABLE))
diff --git a/source4/lib/policy/wscript_build b/source4/lib/policy/wscript_build
new file mode 100644
index 0000000000..646b6ccb5d
--- /dev/null
+++ b/source4/lib/policy/wscript_build
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('policy',
+ source='gp_ldap.c gp_filesys.c gp_manage.c gp_ini.c',
+ pc_files='policy.pc',
+ public_deps='ldb samba-net',
+ vnum='0.0.1',
+ pyembed=True
+ )
+
+bld.SAMBA_PYTHON('py_policy',
+ source='pypolicy.c',
+ public_deps='policy pytalloc-util',
+ realname='samba/policy.so'
+ )
diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk
deleted file mode 100644
index adf26b275f..0000000000
--- a/source4/lib/registry/config.mk
+++ /dev/null
@@ -1,110 +0,0 @@
-[SUBSYSTEM::TDR_REGF]
-PUBLIC_DEPENDENCIES = TDR
-
-TDR_REGF_OBJ_FILES = $(libregistrysrcdir)/tdr_regf.o
-
-# Special support for external builddirs
-$(libregistrysrcdir)/regf.c: $(libregistrysrcdir)/tdr_regf.c
-$(libregistrysrcdir)/tdr_regf.h: $(libregistrysrcdir)/tdr_regf.c
-$(libregistrysrcdir)/tdr_regf.c: $(libregistrysrcdir)/regf.idl
- @CPP="$(CPP)" $(PERL) $(pidldir)/pidl $(PIDL_ARGS) \
- --header --outputdir=$(libregistrysrcdir) \
- --tdr-parser -- $(libregistrysrcdir)/regf.idl
-
-clean::
- @-rm -f $(libregistrysrcdir)/regf.h $(libregistrysrcdir)/tdr_regf*
-
-################################################
-# Start SUBSYSTEM registry
-[LIBRARY::registry]
-PUBLIC_DEPENDENCIES = \
- LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \
- RPC_NDR_WINREG LDB_WRAP
-# End MODULE registry_ldb
-################################################
-
-PC_FILES += $(libregistrysrcdir)/registry.pc
-
-registry_VERSION = 0.0.1
-registry_SOVERSION = 0
-
-registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/, interface.o util.o samba.o \
- patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \
- hive.o local.o ldb.o dir.o rpc.o)
-
-PUBLIC_HEADERS += $(libregistrysrcdir)/registry.h
-
-[SUBSYSTEM::registry_common]
-PUBLIC_DEPENDENCIES = registry
-
-registry_common_OBJ_FILES = $(libregistrysrcdir)/tools/common.o
-
-$(eval $(call proto_header_template,$(libregistrysrcdir)/tools/common.h,$(registry_common_OBJ_FILES:.o=.c)))
-
-################################################
-# Start BINARY regdiff
-[BINARY::regdiff]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS
-# End BINARY regdiff
-################################################
-
-regdiff_OBJ_FILES = $(libregistrysrcdir)/tools/regdiff.o
-
-MANPAGES += $(libregistrysrcdir)/man/regdiff.1
-
-################################################
-# Start BINARY regpatch
-[BINARY::regpatch]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \
- registry_common
-# End BINARY regpatch
-################################################
-
-regpatch_OBJ_FILES = $(libregistrysrcdir)/tools/regpatch.o
-
-MANPAGES += $(libregistrysrcdir)/man/regpatch.1
-
-################################################
-# Start BINARY regshell
-[BINARY::regshell]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \
- SMBREADLINE registry_common
-# End BINARY regshell
-################################################
-
-regshell_OBJ_FILES = $(libregistrysrcdir)/tools/regshell.o
-
-MANPAGES += $(libregistrysrcdir)/man/regshell.1
-
-################################################
-# Start BINARY regtree
-[BINARY::regtree]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \
- registry_common
-# End BINARY regtree
-################################################
-
-regtree_OBJ_FILES = $(libregistrysrcdir)/tools/regtree.o
-
-MANPAGES += $(libregistrysrcdir)/man/regtree.1
-
-[SUBSYSTEM::torture_registry]
-PRIVATE_DEPENDENCIES = torture registry
-
-torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o)
-
-$(eval $(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c)))
-
-[PYTHON::py_registry]
-LIBRARY_REALNAME = samba/registry.$(SHLIBEXT)
-PUBLIC_DEPENDENCIES = registry PYTALLOC pycredentials pyparam_util
-
-py_registry_OBJ_FILES = $(libregistrysrcdir)/pyregistry.o
diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c
index 42946bceec..b1f0965f05 100644
--- a/source4/lib/registry/dir.c
+++ b/source4/lib/registry/dir.c
@@ -40,9 +40,11 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,
int ret;
path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
+ W_ERROR_HAVE_NO_MEMORY(path);
ret = mkdir(path, 0700);
if (ret == 0) {
struct dir_key *key = talloc(mem_ctx, struct dir_key);
+ W_ERROR_HAVE_NO_MEMORY(key);
key->key.ops = &reg_backend_dir;
key->path = talloc_steal(key, path);
*result = (struct hive_key *)key;
@@ -76,8 +78,7 @@ static WERROR reg_dir_delete_recursive(const char *name)
continue;
path = talloc_asprintf(name, "%s/%s", name, e->d_name);
- if (!path)
- return WERR_NOMEM;
+ W_ERROR_HAVE_NO_MEMORY(path);
stat(path, &stbuf);
@@ -108,12 +109,16 @@ static WERROR reg_dir_delete_recursive(const char *name)
return WERR_GENERAL_FAILURE;
}
-static WERROR reg_dir_del_key(const struct hive_key *k, const char *name)
+static WERROR reg_dir_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *k,
+ const char *name)
{
struct dir_key *dk = talloc_get_type(k, struct dir_key);
- char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);
+ char *child;
WERROR ret;
+ child = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
+ W_ERROR_HAVE_NO_MEMORY(child);
+
ret = reg_dir_delete_recursive(child);
talloc_free(child);
@@ -136,11 +141,13 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx,
}
fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name);
+ W_ERROR_HAVE_NO_MEMORY(fullpath);
d = opendir(fullpath);
if (d == NULL) {
DEBUG(3,("Unable to open '%s': %s\n", fullpath,
strerror(errno)));
+ talloc_free(fullpath);
return WERR_BADFILE;
}
closedir(d);
@@ -159,7 +166,7 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx,
{
struct dirent *e;
const struct dir_key *dk = talloc_get_type(k, struct dir_key);
- int i = 0;
+ unsigned int i = 0;
DIR *d;
d = opendir(dk->path);
@@ -173,27 +180,30 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx,
char *thispath;
/* Check if file is a directory */
- asprintf(&thispath, "%s/%s", dk->path, e->d_name);
+ thispath = talloc_asprintf(mem_ctx, "%s/%s", dk->path,
+ e->d_name);
+ W_ERROR_HAVE_NO_MEMORY(thispath);
stat(thispath, &stbuf);
if (!S_ISDIR(stbuf.st_mode)) {
- SAFE_FREE(thispath);
+ talloc_free(thispath);
continue;
}
if (i == idx) {
struct stat st;
*name = talloc_strdup(mem_ctx, e->d_name);
+ W_ERROR_HAVE_NO_MEMORY(*name);
*classname = NULL;
stat(thispath, &st);
unix_to_nt_time(last_mod_time, st.st_mtime);
- SAFE_FREE(thispath);
+ talloc_free(thispath);
closedir(d);
return WERR_OK;
}
i++;
- SAFE_FREE(thispath);
+ talloc_free(thispath);
}
}
@@ -211,6 +221,7 @@ WERROR reg_open_directory(TALLOC_CTX *parent_ctx,
return WERR_INVALID_PARAM;
dk = talloc(parent_ctx, struct dir_key);
+ W_ERROR_HAVE_NO_MEMORY(dk);
dk->key.ops = &reg_backend_dir;
dk->path = talloc_strdup(dk, location);
*key = (struct hive_key *)dk;
@@ -270,10 +281,12 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key,
if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {
char *path = talloc_asprintf(ctx, "%s/%s",
dk->path, e->d_name);
+ W_ERROR_HAVE_NO_MEMORY(path);
if (stat(path, &st) < 0) {
DEBUG(0, ("Error statting %s: %s\n", path,
strerror(errno)));
+ talloc_free(path);
continue;
}
@@ -308,10 +321,19 @@ static WERROR reg_dir_set_value(struct hive_key *key, const char *name,
uint32_t type, const DATA_BLOB data)
{
const struct dir_key *dk = talloc_get_type(key, struct dir_key);
- char *path = talloc_asprintf(dk, "%s/%s", dk->path, name);
+ char *path;
+ bool ret;
+
+ path = talloc_asprintf(dk, "%s/%s", dk->path, name);
+ W_ERROR_HAVE_NO_MEMORY(path);
+
+ ret = file_save(path, data.data, data.length);
+
+ talloc_free(path);
- if (!file_save(path, data.data, data.length))
+ if (!ret) {
return WERR_GENERAL_FAILURE;
+ }
/* FIXME: Type */
@@ -323,12 +345,17 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx,
uint32_t *type, DATA_BLOB *data)
{
const struct dir_key *dk = talloc_get_type(key, struct dir_key);
- char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
+ char *path;
size_t size;
char *contents;
+ path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
+ W_ERROR_HAVE_NO_MEMORY(path);
+
contents = file_load(path, &size, 0, mem_ctx);
+
talloc_free(path);
+
if (contents == NULL)
return WERR_BADFILE;
@@ -342,14 +369,14 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx,
}
static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,
- struct hive_key *key, int idx,
+ struct hive_key *key, uint32_t idx,
const char **name,
uint32_t *type, DATA_BLOB *data)
{
const struct dir_key *dk = talloc_get_type(key, struct dir_key);
DIR *d;
struct dirent *e;
- int i;
+ unsigned int i;
d = opendir(dk->path);
if (d == NULL) {
@@ -364,8 +391,10 @@ static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,
continue;
if (i == idx) {
- if (name != NULL)
+ if (name != NULL) {
*name = talloc_strdup(mem_ctx, e->d_name);
+ W_ERROR_HAVE_NO_MEMORY(*name);
+ }
W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key,
*name, type,
data));
@@ -380,17 +409,25 @@ static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,
}
-static WERROR reg_dir_del_value (struct hive_key *key, const char *name)
+static WERROR reg_dir_del_value(TALLOC_CTX *mem_ctx,
+ struct hive_key *key, const char *name)
{
const struct dir_key *dk = talloc_get_type(key, struct dir_key);
- char *path = talloc_asprintf(key, "%s/%s", dk->path, name);
- if (unlink(path) < 0) {
- talloc_free(path);
+ char *path;
+ int ret;
+
+ path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
+ W_ERROR_HAVE_NO_MEMORY(path);
+
+ ret = unlink(path);
+
+ talloc_free(path);
+
+ if (ret < 0) {
if (errno == ENOENT)
return WERR_BADFILE;
return WERR_GENERAL_FAILURE;
}
- talloc_free(path);
return WERR_OK;
}
diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c
index 8bf7c9f8d1..5763dff0d2 100644
--- a/source4/lib/registry/hive.c
+++ b/source4/lib/registry/hive.c
@@ -54,7 +54,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location,
if (!strncmp(peek, "regf", 4)) {
close(fd);
- return reg_open_regf_file(parent_ctx, location, lp_iconv_convenience(lp_ctx), root);
+ return reg_open_regf_file(parent_ctx, location, root);
} else if (!strncmp(peek, "TDB file", 8)) {
close(fd);
return reg_open_ldb_file(parent_ctx, location, session_info,
@@ -91,9 +91,10 @@ _PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx,
desc, key);
}
-_PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name)
+_PUBLIC_ WERROR hive_key_del(TALLOC_CTX *mem_ctx, const struct hive_key *key,
+ const char *name)
{
- return key->ops->del_key(key, name);
+ return key->ops->del_key(mem_ctx, key, name);
}
_PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx,
@@ -163,12 +164,13 @@ WERROR hive_set_sec_desc(struct hive_key *key,
return key->ops->set_sec_desc(key, security);
}
-WERROR hive_key_del_value(struct hive_key *key, const char *name)
+WERROR hive_key_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
+ const char *name)
{
if (key->ops->delete_value == NULL)
return WERR_NOT_SUPPORTED;
- return key->ops->delete_value(key, name);
+ return key->ops->delete_value(mem_ctx, key, name);
}
WERROR hive_key_flush(struct hive_key *key)
diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c
index 81ca2c39bc..07e606d05b 100644
--- a/source4/lib/registry/interface.c
+++ b/source4/lib/registry/interface.c
@@ -44,7 +44,7 @@ const struct reg_predefined_key reg_predefined_keys[] = {
/** Obtain name of specific hkey. */
_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey)
{
- int i;
+ unsigned int i;
for (i = 0; reg_predefined_keys[i].name; i++) {
if (reg_predefined_keys[i].handle == hkey)
return reg_predefined_keys[i].name;
@@ -58,7 +58,7 @@ _PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx,
const char *name,
struct registry_key **key)
{
- int i;
+ unsigned int i;
for (i = 0; reg_predefined_keys[i].name; i++) {
if (!strcasecmp(reg_predefined_keys[i].name, name))
@@ -150,7 +150,7 @@ _PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx,
*/
_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx,
const struct registry_key *key,
- int idx, const char **name,
+ uint32_t idx, const char **name,
const char **keyclass,
NTTIME *last_changed_time)
{
@@ -185,7 +185,8 @@ _PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx,
/**
* Delete a key.
*/
-_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name)
+_PUBLIC_ WERROR reg_key_del(TALLOC_CTX *mem_ctx, struct registry_key *parent,
+ const char *name)
{
if (parent == NULL)
return WERR_INVALID_PARAM;
@@ -193,7 +194,7 @@ _PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name)
if (parent->context->ops->delete_key == NULL)
return WERR_NOT_SUPPORTED;
- return parent->context->ops->delete_key(parent, name);
+ return parent->context->ops->delete_key(mem_ctx, parent, name);
}
/**
@@ -201,7 +202,7 @@ _PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name)
*/
_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx,
struct registry_key *parent,
- const char *name, const char *key_class,
+ const char *path, const char *key_class,
struct security_descriptor *desc,
struct registry_key **newkey)
{
@@ -214,7 +215,7 @@ _PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx,
return WERR_NOT_SUPPORTED;
}
- return parent->context->ops->create_key(mem_ctx, parent, name,
+ return parent->context->ops->create_key(mem_ctx, parent, path,
key_class, desc, newkey);
}
@@ -257,7 +258,8 @@ _PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx,
/**
* Delete a value.
*/
-_PUBLIC_ WERROR reg_del_value(struct registry_key *key, const char *valname)
+_PUBLIC_ WERROR reg_del_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
+ const char *valname)
{
if (key == NULL)
return WERR_INVALID_PARAM;
@@ -265,7 +267,7 @@ _PUBLIC_ WERROR reg_del_value(struct registry_key *key, const char *valname)
if (key->context->ops->delete_value == NULL)
return WERR_NOT_SUPPORTED;
- return key->context->ops->delete_value(key, valname);
+ return key->context->ops->delete_value(mem_ctx, key, valname);
}
/**
diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c
index c558805e04..a6f00aa330 100644
--- a/source4/lib/registry/ldb.c
+++ b/source4/lib/registry/ldb.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
Registry interface
Copyright (C) 2004-2007, Jelmer Vernooij, jelmer@samba.org
- Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
+ Copyright (C) 2008-2010, Matthias Dieter Wallnöfer, mdw@samba.org
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
@@ -20,8 +20,8 @@
#include "includes.h"
#include "registry.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
+#include <ldb.h>
+#include <ldb_errors.h>
#include "ldb_wrap.h"
#include "librpc/gen_ndr/winreg.h"
#include "param/param.h"
@@ -34,10 +34,11 @@ struct ldb_key_data
struct ldb_context *ldb;
struct ldb_dn *dn;
struct ldb_message **subkeys, **values;
- int subkey_count, value_count;
+ unsigned int subkey_count, value_count;
+ const char *classname;
};
-static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
+static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
struct ldb_message *msg,
const char **name, uint32_t *type,
DATA_BLOB *data)
@@ -45,13 +46,14 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
const struct ldb_val *val;
uint32_t value_type;
- if (name != NULL)
+ if (name != NULL) {
*name = talloc_strdup(mem_ctx,
ldb_msg_find_attr_as_string(msg, "value",
- NULL));
+ ""));
+ }
value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
- *type = value_type;
+ *type = value_type;
val = ldb_msg_find_ldb_val(msg, "data");
@@ -59,33 +61,58 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
{
case REG_SZ:
case REG_EXPAND_SZ:
- if (val != NULL)
+ if (val != NULL) {
+ /* The data should be provided as UTF16 string */
convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16,
- val->data, val->length,
- (void **)&data->data, &data->length, false);
- else {
+ val->data, val->length,
+ (void **)&data->data, &data->length, false);
+ } else {
data->data = NULL;
data->length = 0;
}
break;
- case REG_BINARY:
- if (val != NULL)
- *data = data_blob_talloc(mem_ctx, val->data, val->length);
- else {
+ case REG_DWORD:
+ case REG_DWORD_BIG_ENDIAN:
+ if (val != NULL) {
+ /* The data is a plain DWORD */
+ uint32_t tmp = strtoul((char *)val->data, NULL, 0);
+ data->data = talloc_size(mem_ctx, sizeof(uint32_t));
+ if (data->data != NULL) {
+ SIVAL(data->data, 0, tmp);
+ }
+ data->length = sizeof(uint32_t);
+ } else {
data->data = NULL;
data->length = 0;
}
break;
- case REG_DWORD: {
- uint32_t tmp = strtoul((char *)val->data, NULL, 0);
- *data = data_blob_talloc(mem_ctx, &tmp, 4);
+ case REG_QWORD:
+ if (val != NULL) {
+ /* The data is a plain QWORD */
+ uint64_t tmp = strtoull((char *)val->data, NULL, 0);
+ data->data = talloc_size(mem_ctx, sizeof(uint64_t));
+ if (data->data != NULL) {
+ SBVAL(data->data, 0, tmp);
+ }
+ data->length = sizeof(uint64_t);
+ } else {
+ data->data = NULL;
+ data->length = 0;
}
break;
+ case REG_BINARY:
default:
- *data = data_blob_talloc(mem_ctx, val->data, val->length);
+ if (val != NULL) {
+ data->data = talloc_memdup(mem_ctx, val->data,
+ val->length);
+ data->length = val->length;
+ } else {
+ data->data = NULL;
+ data->length = 0;
+ }
break;
}
}
@@ -95,45 +122,128 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
const char *name,
uint32_t type, DATA_BLOB data)
{
- struct ldb_val val;
- struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message);
- char *type_s;
+ struct ldb_message *msg;
+ char *name_dup, *type_str;
+ int ret;
- ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name));
+ msg = talloc_zero(mem_ctx, struct ldb_message);
+ if (msg == NULL) {
+ return NULL;
+ }
+
+ name_dup = talloc_strdup(msg, name);
+ if (name_dup == NULL) {
+ talloc_free(msg);
+ return NULL;
+ }
+
+ ret = ldb_msg_add_string(msg, "value", name_dup);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return NULL;
+ }
switch (type) {
case REG_SZ:
case REG_EXPAND_SZ:
- if (data.data[0] != '\0') {
- convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8,
- (void *)data.data,
- data.length,
- (void **)&val.data, &val.length, false);
- ldb_msg_add_value(msg, "data", &val, NULL);
+ if ((data.length > 0) && (data.data != NULL)) {
+ struct ldb_val *val;
+ bool ret2 = false;
+
+ val = talloc_zero(msg, struct ldb_val);
+ if (val == NULL) {
+ talloc_free(msg);
+ return NULL;
+ }
+
+ /* The data is provided as UTF16 string */
+ ret2 = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8,
+ (void *)data.data, data.length,
+ (void **)&val->data, &val->length,
+ false);
+ if (ret2) {
+ ret = ldb_msg_add_value(msg, "data", val, NULL);
+ } else {
+ /* workaround for non-standard data */
+ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ }
} else {
- ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
}
break;
- case REG_BINARY:
- if (data.length > 0)
- ldb_msg_add_value(msg, "data", &data, NULL);
- else
- ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ case REG_DWORD:
+ case REG_DWORD_BIG_ENDIAN:
+ if ((data.length > 0) && (data.data != NULL)) {
+ if (data.length == sizeof(uint32_t)) {
+ char *conv_str;
+
+ conv_str = talloc_asprintf(msg, "0x%8.8x",
+ IVAL(data.data, 0));
+ if (conv_str == NULL) {
+ talloc_free(msg);
+ return NULL;
+ }
+ ret = ldb_msg_add_string(msg, "data", conv_str);
+ } else {
+ /* workaround for non-standard data */
+ talloc_free(msg);
+ return NULL;
+ }
+ } else {
+ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ }
break;
- case REG_DWORD:
- ldb_msg_add_string(msg, "data",
- talloc_asprintf(mem_ctx, "0x%x",
- IVAL(data.data, 0)));
+ case REG_QWORD:
+ if ((data.length > 0) && (data.data != NULL)) {
+ if (data.length == sizeof(uint64_t)) {
+ char *conv_str;
+
+ conv_str = talloc_asprintf(msg, "0x%16.16llx",
+ (unsigned long long)BVAL(data.data, 0));
+ if (conv_str == NULL) {
+ talloc_free(msg);
+ return NULL;
+ }
+ ret = ldb_msg_add_string(msg, "data", conv_str);
+ } else {
+ /* workaround for non-standard data */
+ talloc_free(msg);
+ return NULL;
+
+ }
+ } else {
+ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ }
break;
+
+ case REG_BINARY:
default:
- ldb_msg_add_value(msg, "data", &data, NULL);
+ if ((data.length > 0) && (data.data != NULL)) {
+ ret = ldb_msg_add_value(msg, "data", &data, NULL);
+ } else {
+ ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
+ }
+ break;
}
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return NULL;
+ }
- type_s = talloc_asprintf(mem_ctx, "%u", type);
- ldb_msg_add_string(msg, "type", type_s);
+ type_str = talloc_asprintf(mem_ctx, "%u", type);
+ if (type_str == NULL) {
+ talloc_free(msg);
+ return NULL;
+ }
+
+ ret = ldb_msg_add_string(msg, "type", type_str);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return NULL;
+ }
return msg;
}
@@ -166,55 +276,47 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
const struct hive_key *from,
const char *path, const char *add)
{
- TALLOC_CTX *local_ctx;
struct ldb_dn *ret;
- char *mypath = talloc_strdup(mem_ctx, path);
+ char *mypath;
char *begin;
struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
struct ldb_context *ldb = kd->ldb;
- local_ctx = talloc_new(mem_ctx);
-
- if (add) {
- ret = ldb_dn_new(mem_ctx, ldb, add);
- } else {
- ret = ldb_dn_new(mem_ctx, ldb, NULL);
+ mypath = talloc_strdup(mem_ctx, path);
+ if (mypath == NULL) {
+ return NULL;
}
+
+ ret = ldb_dn_new(mem_ctx, ldb, add);
if (!ldb_dn_validate(ret)) {
talloc_free(ret);
- talloc_free(local_ctx);
return NULL;
}
- while (mypath) {
- char *keyname;
-
- begin = strrchr(mypath, '\\');
+ if (!ldb_dn_add_base(ret, kd->dn)) {
+ talloc_free(ret);
+ return NULL;
+ }
- if (begin) keyname = begin + 1;
- else keyname = mypath;
+ while (mypath[0] != '\0') {
+ begin = strchr(mypath, '\\');
+ if (begin != NULL) {
+ *begin = '\0';
+ }
- if(strlen(keyname)) {
- if (!ldb_dn_add_base_fmt(ret, "key=%s",
- reg_ldb_escape(local_ctx,
- keyname)))
- {
- talloc_free(local_ctx);
- return NULL;
- }
+ if (!ldb_dn_add_child_fmt(ret, "key=%s",
+ reg_ldb_escape(mem_ctx, mypath))) {
+ talloc_free(ret);
+ return NULL;
}
- if(begin) {
- *begin = '\0';
+ if (begin != NULL) {
+ mypath = begin + 1;
} else {
break;
}
}
- ldb_dn_add_base(ret, kd->dn);
-
- talloc_free(local_ctx);
-
return ret;
}
@@ -224,8 +326,8 @@ static WERROR cache_subkeys(struct ldb_key_data *kd)
struct ldb_result *res;
int ret;
- ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL, NULL, "(key=*)");
-
+ ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
+ NULL, "(key=*)");
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting subkeys for '%s': %s\n",
ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
@@ -247,7 +349,6 @@ static WERROR cache_values(struct ldb_key_data *kd)
ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
NULL, "(value=*)");
-
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting values for '%s': %s\n",
ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
@@ -268,14 +369,13 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
const char **classname,
NTTIME *last_mod_time)
{
- struct ldb_message_element *el;
struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
-
+
/* Initialization */
if (name != NULL)
*name = NULL;
if (classname != NULL)
- *classname = NULL; /* TODO: Store properly */
+ *classname = NULL;
if (last_mod_time != NULL)
*last_mod_time = 0; /* TODO: we need to add this to the
ldb backend properly */
@@ -288,19 +388,20 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
if (idx >= kd->subkey_count)
return WERR_NO_MORE_ITEMS;
- el = ldb_msg_find_element(kd->subkeys[idx], "key");
- SMB_ASSERT(el != NULL);
- SMB_ASSERT(el->num_values != 0);
-
if (name != NULL)
- *name = talloc_strdup(mem_ctx, (char *)el->values[0].data);
+ *name = talloc_strdup(mem_ctx,
+ ldb_msg_find_attr_as_string(kd->subkeys[idx], "key", NULL));
+ if (classname != NULL)
+ *classname = talloc_strdup(mem_ctx,
+ ldb_msg_find_attr_as_string(kd->subkeys[idx], "classname", NULL));
return WERR_OK;
}
-static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
- const char **name, uint32_t *data_type,
- DATA_BLOB *data)
+static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx,
+ const struct hive_key *k,
+ const char **name, uint32_t *data_type,
+ DATA_BLOB *data)
{
struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
struct ldb_context *c = kd->ldb;
@@ -308,7 +409,7 @@ static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
struct ldb_result *res;
int ret;
- ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs, "%s", "");
+ ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs, "(dn=*)");
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting default value for '%s': %s\n",
@@ -316,11 +417,15 @@ static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
return WERR_FOOBAR;
}
- if (res->count == 0 || res->msgs[0]->num_elements == 0)
+ if (res->count == 0 || res->msgs[0]->num_elements == 0) {
+ talloc_free(res);
return WERR_BADFILE;
+ }
- reg_ldb_unpack_value(mem_ctx,
- res->msgs[0], name, data_type, data);
+ if ((data_type != NULL) && (data != NULL)) {
+ reg_ldb_unpack_value(mem_ctx, res->msgs[0], name, data_type,
+ data);
+ }
talloc_free(res);
@@ -328,12 +433,12 @@ static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
}
static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
- int idx, const char **name,
+ uint32_t idx, const char **name,
uint32_t *data_type, DATA_BLOB *data)
{
struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
- /* if default value exists, give it back */
+ /* if the default value exists, give it back */
if (W_ERROR_IS_OK(ldb_get_default_value(mem_ctx, k, name, data_type,
data))) {
if (idx == 0)
@@ -360,66 +465,67 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
DATA_BLOB *data)
{
struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
- struct ldb_context *c = kd->ldb;
- struct ldb_result *res;
- int ret;
- char *query;
+ const char *res_name;
+ uint32_t idx;
- if (strlen(name) == 0) {
- /* default value */
+ /* the default value was requested, give it back */
+ if (name[0] == '\0') {
return ldb_get_default_value(mem_ctx, k, NULL, data_type, data);
- } else {
- /* normal value */
- query = talloc_asprintf(mem_ctx, "(value=%s)", name);
- ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_ONELEVEL, NULL, "%s", query);
- talloc_free(query);
-
- if (ret != LDB_SUCCESS) {
- DEBUG(0, ("Error getting values for '%s': %s\n",
- ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
- return WERR_FOOBAR;
- }
-
- if (res->count == 0)
- return WERR_BADFILE;
+ }
- reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data);
+ /* Do the search if necessary */
+ if (kd->values == NULL) {
+ W_ERROR_NOT_OK_RETURN(cache_values(kd));
+ }
- talloc_free(res);
+ for (idx = 0; idx < kd->value_count; idx++) {
+ res_name = ldb_msg_find_attr_as_string(kd->values[idx], "value",
+ "");
+ if (ldb_attr_cmp(name, res_name) == 0) {
+ reg_ldb_unpack_value(mem_ctx, kd->values[idx], NULL,
+ data_type, data);
+ return WERR_OK;
+ }
}
- return WERR_OK;
+ return WERR_BADFILE;
}
static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
const char *name, struct hive_key **key)
{
struct ldb_result *res;
- struct ldb_dn *ldap_path;
+ struct ldb_dn *ldb_path;
int ret;
struct ldb_key_data *newkd;
struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);
struct ldb_context *c = kd->ldb;
- ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
+ ldb_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
+ W_ERROR_HAVE_NO_MEMORY(ldb_path);
- ret = ldb_search(c, mem_ctx, &res, ldap_path, LDB_SCOPE_BASE, NULL, "(key=*)");
+ ret = ldb_search(c, mem_ctx, &res, ldb_path, LDB_SCOPE_BASE, NULL, "(key=*)");
if (ret != LDB_SUCCESS) {
DEBUG(3, ("Error opening key '%s': %s\n",
- ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
+ ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
return WERR_FOOBAR;
} else if (res->count == 0) {
DEBUG(3, ("Key '%s' not found\n",
- ldb_dn_get_linearized(ldap_path)));
+ ldb_dn_get_linearized(ldb_path)));
talloc_free(res);
return WERR_BADFILE;
}
newkd = talloc_zero(mem_ctx, struct ldb_key_data);
+ W_ERROR_HAVE_NO_MEMORY(newkd);
newkd->key.ops = &reg_backend_ldb;
newkd->ldb = talloc_reference(newkd, kd->ldb);
- newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
+ newkd->dn = ldb_dn_copy(newkd, res->msgs[0]->dn);
+ newkd->classname = talloc_steal(newkd,
+ ldb_msg_find_attr_as_string(res->msgs[0], "classname", NULL));
+
+ talloc_free(res);
*key = (struct hive_key *)newkd;
@@ -441,7 +547,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
return WERR_INVALID_PARAM;
wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx,
- location, session_info, credentials, 0, NULL);
+ location, session_info, credentials, 0);
if (wrap == NULL) {
DEBUG(1, (__FILE__": unable to connect\n"));
@@ -476,20 +582,28 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
struct hive_key **newkey)
{
struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent);
+ struct ldb_dn *ldb_path;
struct ldb_message *msg;
struct ldb_key_data *newkd;
int ret;
+ ldb_path = reg_path_to_ldb(mem_ctx, parent, name, NULL);
+ W_ERROR_HAVE_NO_MEMORY(ldb_path);
+
msg = ldb_msg_new(mem_ctx);
+ W_ERROR_HAVE_NO_MEMORY(msg);
- msg->dn = reg_path_to_ldb(msg, parent, name, NULL);
+ msg->dn = ldb_path;
- ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name));
- if (classname != NULL)
- ldb_msg_add_string(msg, "classname",
- talloc_strdup(mem_ctx, classname));
+ ldb_msg_add_string(msg, "key", name);
+ if (classname != NULL) {
+ ldb_msg_add_string(msg, "classname", classname);
+ }
ret = ldb_add(parentkd->ldb, msg);
+
+ talloc_free(msg);
+
if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
return WERR_ALREADY_EXISTS;
}
@@ -499,12 +613,14 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
return WERR_FOOBAR;
}
- DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn)));
+ DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(ldb_path)));
newkd = talloc_zero(mem_ctx, struct ldb_key_data);
+ W_ERROR_HAVE_NO_MEMORY(newkd);
newkd->ldb = talloc_reference(newkd, parentkd->ldb);
newkd->key.ops = &reg_backend_ldb;
- newkd->dn = talloc_steal(newkd, msg->dn);
+ newkd->dn = talloc_steal(newkd, ldb_path);
+ newkd->classname = talloc_steal(newkd, classname);
*newkey = (struct hive_key *)newkd;
@@ -515,31 +631,31 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
return WERR_OK;
}
-static WERROR ldb_del_value (struct hive_key *key, const char *child)
+static WERROR ldb_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
+ const char *child)
{
int ret;
struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
- TALLOC_CTX *mem_ctx;
struct ldb_message *msg;
struct ldb_dn *childdn;
- if (strlen(child) == 0) {
+ if (child[0] == '\0') {
/* default value */
- mem_ctx = talloc_init("ldb_del_value");
-
msg = talloc_zero(mem_ctx, struct ldb_message);
+ W_ERROR_HAVE_NO_MEMORY(msg);
msg->dn = ldb_dn_copy(msg, kd->dn);
+ W_ERROR_HAVE_NO_MEMORY(msg->dn);
ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_DELETE, NULL);
ret = ldb_modify(kd->ldb, msg);
+
+ talloc_free(msg);
+
if (ret != LDB_SUCCESS) {
DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
- talloc_free(mem_ctx);
return WERR_FOOBAR;
}
-
- talloc_free(mem_ctx);
} else {
/* normal value */
childdn = ldb_dn_copy(kd->ldb, kd->dn);
@@ -569,12 +685,13 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child)
return WERR_OK;
}
-static WERROR ldb_del_key(const struct hive_key *key, const char *name)
+static WERROR ldb_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *key,
+ const char *name)
{
- int i, ret;
+ unsigned int i;
+ int ret;
struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
- struct ldb_dn *ldap_path;
- TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key");
+ struct ldb_dn *ldb_path;
struct ldb_context *c = parentkd->ldb;
struct ldb_result *res_keys;
struct ldb_result *res_vals;
@@ -584,35 +701,29 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name)
/* Verify key exists by opening it */
werr = ldb_open_key(mem_ctx, key, name, &hk);
if (!W_ERROR_IS_OK(werr)) {
- talloc_free(mem_ctx);
return werr;
}
- ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
- if (!ldap_path) {
- talloc_free(mem_ctx);
- return WERR_FOOBAR;
- }
+ ldb_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
+ W_ERROR_HAVE_NO_MEMORY(ldb_path);
/* Search for subkeys */
- ret = ldb_search(c, mem_ctx, &res_keys, ldap_path, LDB_SCOPE_ONELEVEL,
+ ret = ldb_search(c, mem_ctx, &res_keys, ldb_path, LDB_SCOPE_ONELEVEL,
NULL, "(key=*)");
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting subkeys for '%s': %s\n",
- ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
- talloc_free(mem_ctx);
+ ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
return WERR_FOOBAR;
}
/* Search for values */
- ret = ldb_search(c, mem_ctx, &res_vals, ldap_path, LDB_SCOPE_ONELEVEL,
+ ret = ldb_search(c, mem_ctx, &res_vals, ldb_path, LDB_SCOPE_ONELEVEL,
NULL, "(value=*)");
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting values for '%s': %s\n",
- ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
- talloc_free(mem_ctx);
+ ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
return WERR_FOOBAR;
}
@@ -621,7 +732,6 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name)
if (ret != LDB_SUCCESS) {
DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
- talloc_free(mem_ctx);
return WERR_FOOBAR;
}
@@ -630,12 +740,12 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name)
/* Delete any subkeys */
for (i = 0; i < res_keys->count; i++)
{
- werr = ldb_del_key(hk, ldb_msg_find_attr_as_string(
+ werr = ldb_del_key(mem_ctx, hk,
+ ldb_msg_find_attr_as_string(
res_keys->msgs[i],
"key", NULL));
if (!W_ERROR_IS_OK(werr)) {
ret = ldb_transaction_cancel(c);
- talloc_free(mem_ctx);
return werr;
}
}
@@ -643,25 +753,26 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name)
/* Delete any values */
for (i = 0; i < res_vals->count; i++)
{
- werr = ldb_del_value(hk, ldb_msg_find_attr_as_string(
+ werr = ldb_del_value(mem_ctx, hk,
+ ldb_msg_find_attr_as_string(
res_vals->msgs[i],
"value", NULL));
if (!W_ERROR_IS_OK(werr)) {
ret = ldb_transaction_cancel(c);
- talloc_free(mem_ctx);
return werr;
}
}
}
+ talloc_free(res_keys);
+ talloc_free(res_vals);
/* Delete the key itself */
- ret = ldb_delete(c, ldap_path);
+ ret = ldb_delete(c, ldb_path);
if (ret != LDB_SUCCESS)
{
DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
ret = ldb_transaction_cancel(c);
- talloc_free(mem_ctx);
return WERR_FOOBAR;
}
@@ -672,12 +783,9 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name)
{
DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
ret = ldb_transaction_cancel(c);
- talloc_free(mem_ctx);
return WERR_FOOBAR;
}
- talloc_free(mem_ctx);
-
/* reset cache */
talloc_free(parentkd->subkeys);
parentkd->subkeys = NULL;
@@ -691,15 +799,19 @@ static WERROR ldb_set_value(struct hive_key *parent,
{
struct ldb_message *msg;
struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
+ unsigned int i;
int ret;
TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
+ W_ERROR_HAVE_NO_MEMORY(msg);
+
msg->dn = ldb_dn_copy(msg, kd->dn);
-
- if (strlen(name) > 0) {
+ W_ERROR_HAVE_NO_MEMORY(msg->dn);
+
+ if (name[0] != '\0') {
/* For a default value, we add/overwrite the attributes to/of the hive.
- For a normal value, we create new childs. */
+ For a normal value, we create a new child. */
if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
reg_ldb_escape(mem_ctx, name)))
{
@@ -708,16 +820,31 @@ static WERROR ldb_set_value(struct hive_key *parent,
}
}
- ret = ldb_add(kd->ldb, msg);
- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- int i;
- for (i = 0; i < msg->num_elements; i++) {
- if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE)
- msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+ /* Try first a "modify" and if this doesn't work do try an "add" */
+ for (i = 0; i < msg->num_elements; i++) {
+ if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) {
+ msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
}
- ret = ldb_modify(kd->ldb, msg);
+ }
+ ret = ldb_modify(kd->ldb, msg);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ i = 0;
+ while (i < msg->num_elements) {
+ if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE) {
+ ldb_msg_remove_element(msg, &msg->elements[i]);
+ } else {
+ ++i;
+ }
+ }
+ ret = ldb_add(kd->ldb, msg);
+ }
+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ /* ignore this -> the value didn't exist and also now doesn't */
+ ret = LDB_SUCCESS;
}
+ talloc_free(msg);
+
if (ret != LDB_SUCCESS) {
DEBUG(1, ("ldb_set_value: %s\n", ldb_errstring(kd->ldb)));
talloc_free(mem_ctx);
@@ -743,6 +870,9 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
uint32_t *max_valbufsize)
{
struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
+ uint32_t default_value_type = REG_NONE;
+ DATA_BLOB default_value = { NULL, 0 };
+ WERROR werr;
/* Initialization */
if (classname != NULL)
@@ -760,28 +890,43 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
if (max_valbufsize != NULL)
*max_valbufsize = 0;
+ /* We need this to get the default value (if it exists) for counting
+ * the values under the key and for finding out the longest value buffer
+ * size. If no default value exists the DATA_BLOB "default_value" will
+ * remain { NULL, 0 }. */
+ werr = ldb_get_default_value(mem_ctx, key, NULL, &default_value_type,
+ &default_value);
+ if ((!W_ERROR_IS_OK(werr)) && (!W_ERROR_EQUAL(werr, WERR_BADFILE))) {
+ return werr;
+ }
+
if (kd->subkeys == NULL) {
W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
}
-
if (kd->values == NULL) {
W_ERROR_NOT_OK_RETURN(cache_values(kd));
}
+ if (classname != NULL) {
+ *classname = kd->classname;
+ }
+
if (num_subkeys != NULL) {
*num_subkeys = kd->subkey_count;
}
if (num_values != NULL) {
*num_values = kd->value_count;
+ /* also consider the default value if it exists */
+ if (default_value.data != NULL) {
+ ++(*num_values);
+ }
}
if (max_subkeynamelen != NULL) {
- int i;
+ unsigned int i;
struct ldb_message_element *el;
- *max_subkeynamelen = 0;
-
for (i = 0; i < kd->subkey_count; i++) {
el = ldb_msg_find_element(kd->subkeys[i], "key");
*max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length);
@@ -789,15 +934,15 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
}
if (max_valnamelen != NULL || max_valbufsize != NULL) {
- int i;
+ unsigned int i;
struct ldb_message_element *el;
W_ERROR_NOT_OK_RETURN(cache_values(kd));
- if (max_valbufsize != NULL)
- *max_valbufsize = 0;
-
- if (max_valnamelen != NULL)
- *max_valnamelen = 0;
+ /* also consider the default value if it exists */
+ if ((max_valbufsize != NULL) && (default_value.data != NULL)) {
+ *max_valbufsize = MAX(*max_valbufsize,
+ default_value.length);
+ }
for (i = 0; i < kd->value_count; i++) {
if (max_valnamelen != NULL) {
@@ -808,8 +953,8 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
if (max_valbufsize != NULL) {
uint32_t data_type;
DATA_BLOB data;
- reg_ldb_unpack_value(mem_ctx,
- kd->values[i], NULL,
+ reg_ldb_unpack_value(mem_ctx,
+ kd->values[i], NULL,
&data_type, &data);
*max_valbufsize = MAX(*max_valbufsize, data.length);
talloc_free(data.data);
@@ -817,6 +962,8 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
}
}
+ talloc_free(default_value.data);
+
return WERR_OK;
}
diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c
index a3aee06b13..98791743ae 100644
--- a/source4/lib/registry/local.c
+++ b/source4/lib/registry/local.c
@@ -57,9 +57,11 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx,
parent_path.elements = elements;
local_key = talloc(ctx, struct local_key);
- local_key->hive_key = talloc_steal(local_key, hive);
- local_key->global.context = talloc_reference(local_key, ctx);
- local_key->path = parent_path;
+ if (local_key != NULL) {
+ local_key->hive_key = talloc_reference(local_key, hive);
+ local_key->global.context = talloc_reference(local_key, ctx);
+ local_key->path = parent_path;
+ }
return (struct registry_key *)local_key;
}
@@ -70,9 +72,7 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx,
const char *path,
struct registry_key **result)
{
- char *orig = talloc_strdup(mem_ctx, path),
- *curbegin = orig,
- *curend = strchr(orig, '\\');
+ char *orig, *curbegin, *curend;
struct local_key *local_parent = talloc_get_type(parent,
struct local_key);
struct hive_key *curkey = local_parent->hive_key;
@@ -80,9 +80,19 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx,
const char **elements = NULL;
int el;
+ if (path == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ orig = talloc_strdup(mem_ctx, path);
+ W_ERROR_HAVE_NO_MEMORY(orig);
+ curbegin = orig;
+ curend = strchr(orig, '\\');
+
if (local_parent->path.elements != NULL) {
elements = talloc_array(mem_ctx, const char *,
str_list_length(local_parent->path.elements) + 1);
+ W_ERROR_HAVE_NO_MEMORY(elements);
for (el = 0; local_parent->path.elements[el] != NULL; el++) {
elements[el] = talloc_reference(elements,
local_parent->path.elements[el]);
@@ -97,7 +107,9 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx,
if (curend != NULL)
*curend = '\0';
elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
+ W_ERROR_HAVE_NO_MEMORY(elements);
elements[el] = talloc_strdup(elements, curbegin);
+ W_ERROR_HAVE_NO_MEMORY(elements[el]);
el++;
elements[el] = NULL;
error = hive_get_key_by_name(mem_ctx, curkey,
@@ -158,51 +170,75 @@ static WERROR local_enum_key(TALLOC_CTX *mem_ctx,
}
static WERROR local_create_key(TALLOC_CTX *mem_ctx,
- struct registry_key *parent_key,
- const char *name,
+ struct registry_key *parent,
+ const char *path,
const char *key_class,
struct security_descriptor *security,
- struct registry_key **key)
+ struct registry_key **result)
{
- struct local_key *local_parent;
- struct hive_key *hivekey;
- const char **elements;
- int i;
- const char *last_part;
+ char *orig, *curbegin, *curend;
+ struct local_key *local_parent = talloc_get_type(parent,
+ struct local_key);
+ struct hive_key *curkey = local_parent->hive_key;
+ WERROR error;
+ const char **elements = NULL;
+ int el;
- last_part = strrchr(name, '\\');
- if (last_part == NULL) {
- last_part = name;
- local_parent = (struct local_key *)parent_key;
- } else {
- W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key,
- talloc_strndup(mem_ctx, name, last_part-name),
- (struct registry_key **)&local_parent));
- last_part++;
+ if (path == NULL) {
+ return WERR_INVALID_PARAM;
}
- W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key,
- last_part, key_class, security,
- &hivekey));
+ orig = talloc_strdup(mem_ctx, path);
+ W_ERROR_HAVE_NO_MEMORY(orig);
+ curbegin = orig;
+ curend = strchr(orig, '\\');
if (local_parent->path.elements != NULL) {
- elements = talloc_array(hivekey, const char *,
- str_list_length(local_parent->path.elements)+2);
- for (i = 0; local_parent->path.elements[i] != NULL; i++) {
- elements[i] = talloc_reference(elements,
- local_parent->path.elements[i]);
+ elements = talloc_array(mem_ctx, const char *,
+ str_list_length(local_parent->path.elements) + 1);
+ W_ERROR_HAVE_NO_MEMORY(elements);
+ for (el = 0; local_parent->path.elements[el] != NULL; el++) {
+ elements[el] = talloc_reference(elements,
+ local_parent->path.elements[el]);
}
+ elements[el] = NULL;
} else {
- elements = talloc_array(hivekey, const char *, 2);
- i = 0;
+ elements = NULL;
+ el = 0;
}
- elements[i] = talloc_strdup(elements, name);
- elements[i+1] = NULL;
+ while (curbegin != NULL && *curbegin) {
+ if (curend != NULL)
+ *curend = '\0';
+ elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
+ W_ERROR_HAVE_NO_MEMORY(elements);
+ elements[el] = talloc_strdup(elements, curbegin);
+ W_ERROR_HAVE_NO_MEMORY(elements[el]);
+ el++;
+ elements[el] = NULL;
+ error = hive_get_key_by_name(mem_ctx, curkey,
+ curbegin, &curkey);
+ if (W_ERROR_EQUAL(error, WERR_BADFILE)) {
+ error = hive_key_add_name(mem_ctx, curkey, curbegin,
+ key_class, security,
+ &curkey);
+ }
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(2, ("Open/Creation of key %s failed: %s\n",
+ curbegin, win_errstr(error)));
+ talloc_free(orig);
+ return error;
+ }
+ if (curend == NULL)
+ break;
+ curbegin = curend + 1;
+ curend = strchr(curbegin, '\\');
+ }
+ talloc_free(orig);
- *key = reg_import_hive_key(local_parent->global.context, hivekey,
- local_parent->path.predefined_key,
- elements);
+ *result = reg_import_hive_key(local_parent->global.context, curkey,
+ local_parent->path.predefined_key,
+ talloc_steal(curkey, elements));
return WERR_OK;
}
@@ -212,6 +248,10 @@ static WERROR local_set_value(struct registry_key *key, const char *name,
{
struct local_key *local = (struct local_key *)key;
+ if (name == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
return hive_key_set_value(local->hive_key, name, type, data);
}
@@ -221,6 +261,10 @@ static WERROR local_get_value(TALLOC_CTX *mem_ctx,
{
const struct local_key *local = (const struct local_key *)key;
+ if (name == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
return hive_get_value(mem_ctx, local->hive_key, name, type, data);
}
@@ -236,18 +280,28 @@ static WERROR local_enum_value(TALLOC_CTX *mem_ctx,
name, type, data);
}
-static WERROR local_delete_key(struct registry_key *key, const char *name)
+static WERROR local_delete_key(TALLOC_CTX *mem_ctx, struct registry_key *key,
+ const char *name)
{
const struct local_key *local = (const struct local_key *)key;
- return hive_key_del(local->hive_key, name);
+ if (name == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ return hive_key_del(mem_ctx, local->hive_key, name);
}
-static WERROR local_delete_value(struct registry_key *key, const char *name)
+static WERROR local_delete_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
+ const char *name)
{
const struct local_key *local = (const struct local_key *)key;
- return hive_key_del_value(local->hive_key, name);
+ if (name == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ return hive_key_del_value(mem_ctx, local->hive_key, name);
}
static WERROR local_flush_key(struct registry_key *key)
@@ -327,15 +381,18 @@ WERROR reg_mount_hive(struct registry_context *rctx,
{
struct registry_local *reg_local = talloc_get_type(rctx,
struct registry_local);
- struct mountpoint *mp = talloc(rctx, struct mountpoint);
- int i = 0;
+ struct mountpoint *mp;
+ unsigned int i = 0;
+ mp = talloc(rctx, struct mountpoint);
+ W_ERROR_HAVE_NO_MEMORY(mp);
mp->path.predefined_key = key_id;
mp->prev = mp->next = NULL;
mp->key = hive_key;
if (elements != NULL && str_list_length(elements) != 0) {
mp->path.elements = talloc_array(mp, const char *,
str_list_length(elements));
+ W_ERROR_HAVE_NO_MEMORY(mp->path.elements);
for (i = 0; elements[i] != NULL; i++) {
mp->path.elements[i] = talloc_reference(mp->path.elements,
elements[i]);
diff --git a/source4/lib/registry/man/regdiff.1.xml b/source4/lib/registry/man/regdiff.1.xml
index 7bcaa1502c..59ef459795 100644
--- a/source4/lib/registry/man/regdiff.1.xml
+++ b/source4/lib/registry/man/regdiff.1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="regdiff.1">
<refmeta>
diff --git a/source4/lib/registry/man/regpatch.1.xml b/source4/lib/registry/man/regpatch.1.xml
index d9dcdcbf80..7293f5dafa 100644
--- a/source4/lib/registry/man/regpatch.1.xml
+++ b/source4/lib/registry/man/regpatch.1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="regpatch.1">
<refmeta>
diff --git a/source4/lib/registry/man/regshell.1.xml b/source4/lib/registry/man/regshell.1.xml
index 9f16d8cc24..ed91b1b69a 100644
--- a/source4/lib/registry/man/regshell.1.xml
+++ b/source4/lib/registry/man/regshell.1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="regshell.1">
<refmeta>
diff --git a/source4/lib/registry/man/regtree.1.xml b/source4/lib/registry/man/regtree.1.xml
index 93f15e1fb2..197091c46b 100644
--- a/source4/lib/registry/man/regtree.1.xml
+++ b/source4/lib/registry/man/regtree.1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="regtree.1">
<refmeta>
diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c
index 24d86abf48..061d0fe52d 100644
--- a/source4/lib/registry/patchfile.c
+++ b/source4/lib/registry/patchfile.c
@@ -4,7 +4,7 @@
Copyright (C) Jelmer Vernooij 2004-2007
Copyright (C) Wilco Baan Hofman 2006
- Copyright (C) Matthias Dieter Wallnöfer 2008
+ Copyright (C) Matthias Dieter Wallnöfer 2008-2010
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
@@ -26,12 +26,10 @@
_PUBLIC_ WERROR reg_preg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
_PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
@@ -44,7 +42,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
const struct reg_diff_callbacks *callbacks,
void *callback_data)
{
- int i;
+ unsigned int i;
struct registry_key *t1 = NULL, *t2 = NULL;
char *tmppath;
const char *keyname1;
@@ -86,7 +84,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
}
if (!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_BADFILE)) {
- DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ DEBUG(0, ("Error occurred while getting subkey by name: %s\n",
win_errstr(error2)));
talloc_free(mem_ctx);
return error2;
@@ -95,13 +93,18 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
/* if "error2" is going to be "WERR_BADFILE", then newkey */
/* didn't have such a subkey and therefore add a del diff */
tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1);
+ if (tmppath == NULL) {
+ DEBUG(0, ("Out of memory\n"));
+ talloc_free(mem_ctx);
+ return WERR_NOMEM;
+ }
if (!W_ERROR_IS_OK(error2))
callbacks->del_key(callback_data, tmppath);
/* perform here also the recursive invocation */
error1 = reg_open_key(mem_ctx, oldkey, keyname1, &t1);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ DEBUG(0, ("Error occurred while getting subkey by name: %s\n",
win_errstr(error1)));
talloc_free(mem_ctx);
return error1;
@@ -154,14 +157,19 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
return error2;
}
- /* oldkey didn't have such a subkey, add add diff */
+ /* oldkey didn't have such a subkey, add a add diff */
tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1);
+ if (tmppath == NULL) {
+ DEBUG(0, ("Out of memory\n"));
+ talloc_free(mem_ctx);
+ return WERR_NOMEM;
+ }
callbacks->add_key(callback_data, tmppath);
/* perform here also the recursive invocation */
error1 = reg_open_key(mem_ctx, newkey, keyname1, &t2);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ DEBUG(0, ("Error occurred while getting subkey by name: %s\n",
win_errstr(error1)));
talloc_free(mem_ctx);
return error1;
@@ -175,7 +183,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
for(i = 0; i < new_num_values; i++) {
const char *name;
uint32_t type1, type2;
- DATA_BLOB contents1, contents2;
+ DATA_BLOB contents1 = { NULL, 0 }, contents2 = { NULL, 0 };
error1 = reg_key_get_value_by_index(mem_ctx, newkey, i,
&name, &type1, &contents1);
@@ -202,19 +210,27 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
}
if (W_ERROR_IS_OK(error2)
- && (data_blob_cmp(&contents1, &contents2) == 0)
- && (type1 == type2))
+ && (data_blob_cmp(&contents1, &contents2) == 0)
+ && (type1 == type2)) {
+ talloc_free(discard_const_p(char, name));
+ talloc_free(contents1.data);
+ talloc_free(contents2.data);
continue;
+ }
callbacks->set_value(callback_data, path, name,
type1, contents1);
+
+ talloc_free(discard_const_p(char, name));
+ talloc_free(contents1.data);
+ talloc_free(contents2.data);
}
/* Values that were deleted */
for (i = 0; i < old_num_values; i++) {
const char *name;
uint32_t type;
- DATA_BLOB contents;
+ DATA_BLOB contents = { NULL, 0 };
error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name,
&type, &contents);
@@ -231,8 +247,11 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
else
error2 = WERR_BADFILE;
- if (W_ERROR_IS_OK(error2))
+ if (W_ERROR_IS_OK(error2)) {
+ talloc_free(discard_const_p(char, name));
+ talloc_free(contents.data);
continue;
+ }
if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) {
DEBUG(0, ("Error occurred while getting value by name: %s\n",
@@ -242,6 +261,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
}
callbacks->del_value(callback_data, path, name);
+
+ talloc_free(discard_const_p(char, name));
+ talloc_free(contents.data);
}
talloc_free(mem_ctx);
@@ -256,7 +278,7 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1,
const struct reg_diff_callbacks *callbacks,
void *callback_data)
{
- int i;
+ unsigned int i;
WERROR error;
for (i = 0; reg_predefined_keys[i].name; i++) {
@@ -280,6 +302,21 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1,
continue;
}
+ /* if "r1" is NULL (old hive) and "r2" isn't (new hive) then
+ * the hive doesn't exist yet and we have to generate an add
+ * diff */
+ if ((r1 == NULL) && (r2 != NULL)) {
+ callbacks->add_key(callback_data,
+ reg_predefined_keys[i].name);
+ }
+ /* if "r1" isn't NULL (old hive) and "r2" is (new hive) then
+ * the hive shouldn't exist anymore and we have to generate a
+ * del diff */
+ if ((r1 != NULL) && (r2 == NULL)) {
+ callbacks->del_key(callback_data,
+ reg_predefined_keys[i].name);
+ }
+
error = reg_generate_diff_key(r1, r2,
reg_predefined_keys[i].name, callbacks,
callback_data);
@@ -299,7 +336,6 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1,
* Load diff file
*/
_PUBLIC_ WERROR reg_diff_load(const char *filename,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data)
{
@@ -333,10 +369,10 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename,
#endif
if (strncmp(hdr, "PReg", 4) == 0) {
/* Must be a GPO Registry.pol file */
- return reg_preg_diff_load(fd, iconv_convenience, callbacks, callback_data);
+ return reg_preg_diff_load(fd, callbacks, callback_data);
} else {
/* Must be a normal .REG file */
- return reg_dotreg_diff_load(fd, iconv_convenience, callbacks, callback_data);
+ return reg_dotreg_diff_load(fd, callbacks, callback_data);
}
}
@@ -352,6 +388,7 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name)
/* Recursively create the path */
buf = talloc_strdup(ctx, key_name);
+ W_ERROR_HAVE_NO_MEMORY(buf);
buf_ptr = buf;
while (*buf_ptr++ != '\0' ) {
@@ -366,9 +403,12 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name)
return error;
}
*buf_ptr++ = '\\';
+ talloc_free(tmp);
}
}
+ talloc_free(buf);
+
/* Add the key */
error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp);
@@ -378,6 +418,8 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name)
key_name, win_errstr(error)));
return error;
}
+ talloc_free(tmp);
+
return WERR_OK;
}
@@ -387,7 +429,7 @@ static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name)
/* We can't proof here for success, because a common superkey could */
/* have been deleted before the subkey's (diff order). This removed */
- /* therefore all childs recursively and the "WERR_BADFILE" result is */
+ /* therefore all children recursively and the "WERR_BADFILE" result is */
/* expected. */
reg_key_del_abs(ctx, key_name);
@@ -419,6 +461,8 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path,
return error;
}
+ talloc_free(tmp);
+
return WERR_OK;
}
@@ -437,12 +481,13 @@ static WERROR reg_diff_apply_del_value(void *_ctx, const char *key_name,
return error;
}
- error = reg_del_value(tmp, value_name);
+ error = reg_del_value(ctx, tmp, value_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error deleting value '%s'\n", value_name));
return error;
}
+ talloc_free(tmp);
return WERR_OK;
}
@@ -452,7 +497,7 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name)
struct registry_context *ctx = (struct registry_context *)_ctx;
struct registry_key *key;
WERROR error;
- const char* value_name;
+ const char *value_name;
error = reg_open_key_abs(ctx, ctx, key_name, &key);
@@ -466,13 +511,16 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name)
while (W_ERROR_IS_OK(reg_key_get_value_by_index(
ctx, key, 0, &value_name, NULL, NULL))) {
- error = reg_del_value(key, value_name);
+ error = reg_del_value(ctx, key, value_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error deleting value '%s'\n", value_name));
return error;
}
+ talloc_free(discard_const_p(char, value_name));
}
+ talloc_free(key);
+
return WERR_OK;
}
@@ -480,7 +528,6 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name)
* Apply diff to a registry context
*/
_PUBLIC_ WERROR reg_diff_apply(struct registry_context *ctx,
- struct smb_iconv_convenience *iconv_convenience,
const char *filename)
{
struct reg_diff_callbacks callbacks;
@@ -492,6 +539,5 @@ _PUBLIC_ WERROR reg_diff_apply(struct registry_context *ctx,
callbacks.del_all_values = reg_diff_apply_del_all_values;
callbacks.done = NULL;
- return reg_diff_load(filename, iconv_convenience,
- &callbacks, ctx);
+ return reg_diff_load(filename, &callbacks, ctx);
}
diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c
index 3b5708978d..8fac00ba44 100644
--- a/source4/lib/registry/patchfile_dotreg.c
+++ b/source4/lib/registry/patchfile_dotreg.c
@@ -3,7 +3,7 @@
Reading .REG files
Copyright (C) Jelmer Vernooij 2004-2007
- Copyright (C) Wilco Baan Hofman 2006-2008
+ Copyright (C) Wilco Baan Hofman 2006-2010
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
@@ -20,7 +20,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* FIXME Newer .REG files, created by Windows XP and above use unicode UCS-2 */
+/* FIXME:
+ * - Newer .REG files, created by Windows XP and above use unicode UCS-2
+ * - @="" constructions should write value with empty name.
+*/
#include "includes.h"
#include "lib/registry/registry.h"
@@ -35,9 +38,65 @@
struct dotreg_data {
int fd;
- struct smb_iconv_convenience *iconv_convenience;
};
+/*
+ * This is basically a copy of data_blob_hex_string_upper, but with comma's
+ * between the bytes in hex.
+ */
+static char *dotreg_data_blob_hex_string(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
+{
+ size_t i;
+ char *hex_string;
+
+ hex_string = talloc_array(mem_ctx, char, (blob->length*3)+1);
+ if (!hex_string) {
+ return NULL;
+ }
+
+ for (i = 0; i < blob->length; i++)
+ slprintf(&hex_string[i*3], 4, "%02X,", blob->data[i]);
+
+ /* Remove last comma and NULL-terminate the string */
+ hex_string[(blob->length*3)-1] = '\0';
+ return hex_string;
+}
+
+/*
+ * This is basically a copy of reg_val_data_string, except that this function
+ * has no 0x for dwords, everything else is regarded as binary, and binary
+ * strings are represented with bytes comma-separated.
+ */
+static char *reg_val_dotreg_string(TALLOC_CTX *mem_ctx, uint32_t type,
+ const DATA_BLOB data)
+{
+ char *ret = NULL;
+
+ if (data.length == 0)
+ return talloc_strdup(mem_ctx, "");
+
+ switch (type) {
+ case REG_EXPAND_SZ:
+ case REG_SZ:
+ convert_string_talloc(mem_ctx,
+ CH_UTF16, CH_UNIX, data.data, data.length,
+ (void **)&ret, NULL, false);
+ break;
+ case REG_DWORD:
+ case REG_DWORD_BIG_ENDIAN:
+ SMB_ASSERT(data.length == sizeof(uint32_t));
+ ret = talloc_asprintf(mem_ctx, "%08x",
+ IVAL(data.data, 0));
+ break;
+ default: /* default means treat as binary */
+ case REG_BINARY:
+ ret = dotreg_data_blob_hex_string(mem_ctx, &data);
+ break;
+ }
+
+ return ret;
+}
+
static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name)
{
struct dotreg_data *data = (struct dotreg_data *)_data;
@@ -61,10 +120,39 @@ static WERROR reg_dotreg_diff_set_value(void *_data, const char *path,
uint32_t value_type, DATA_BLOB value)
{
struct dotreg_data *data = (struct dotreg_data *)_data;
+ char *data_string = reg_val_dotreg_string(NULL,
+ value_type, value);
+ char *data_incl_type;
+
+ W_ERROR_HAVE_NO_MEMORY(data_string);
+
+ switch (value_type) {
+ case REG_SZ:
+ data_incl_type = talloc_asprintf(data_string, "\"%s\"",
+ data_string);
+ break;
+ case REG_DWORD:
+ data_incl_type = talloc_asprintf(data_string,
+ "dword:%s", data_string);
+ break;
+ case REG_BINARY:
+ data_incl_type = talloc_asprintf(data_string, "hex:%s",
+ data_string);
+ break;
+ default:
+ data_incl_type = talloc_asprintf(data_string, "hex(%x):%s",
+ value_type, data_string);
+ break;
+ }
+
+ if (value_name[0] == '\0') {
+ fdprintf(data->fd, "@=%s\n", data_incl_type);
+ } else {
+ fdprintf(data->fd, "\"%s\"=%s\n",
+ value_name, data_incl_type);
+ }
- fdprintf(data->fd, "\"%s\"=%s:%s\n",
- value_name, str_regtype(value_type),
- reg_val_data_string(NULL, data->iconv_convenience, value_type, value));
+ talloc_free(data_string);
return WERR_OK;
}
@@ -99,7 +187,6 @@ static WERROR reg_dotreg_diff_del_all_values(void *callback_data,
* Save registry diff
*/
_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
- struct smb_iconv_convenience *iconv_convenience,
struct reg_diff_callbacks **callbacks,
void **callback_data)
{
@@ -108,8 +195,6 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
data = talloc_zero(ctx, struct dotreg_data);
*callback_data = data;
- data->iconv_convenience = iconv_convenience;
-
if (filename) {
data->fd = open(filename, O_CREAT|O_WRONLY, 0755);
if (data->fd < 0) {
@@ -138,7 +223,6 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
* Load diff file
*/
_PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data)
{
@@ -147,7 +231,12 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
TALLOC_CTX *mem_ctx = talloc_init("reg_dotreg_diff_load");
WERROR error;
uint32_t value_type;
- DATA_BLOB value;
+ DATA_BLOB data;
+ bool result;
+ char *type_str = NULL;
+ char *data_str;
+ char *value;
+ bool continue_next_line = 0;
line = afdgets(fd, mem_ctx, 0);
if (!line) {
@@ -158,6 +247,11 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
}
while ((line = afdgets(fd, mem_ctx, 0))) {
+ /* Remove '\r' if it's a Windows text file */
+ if (line[strlen(line)-1] == '\r') {
+ line[strlen(line)-1] = '\0';
+ }
+
/* Ignore comments and empty lines */
if (strlen(line) == 0 || line[0] == ';') {
talloc_free(line);
@@ -171,17 +265,20 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
/* Start of key */
if (line[0] == '[') {
- p = strchr_m(line, ']');
- if (p[strlen(p)-1] != ']') {
- DEBUG(0, ("Missing ']'\n"));
- return WERR_GENERAL_FAILURE;
+ if (line[strlen(line)-1] != ']') {
+ DEBUG(0, ("Missing ']' on line: %s\n", line));
+ talloc_free(line);
+ continue;
}
+
/* Deleting key */
if (line[1] == '-') {
curkey = talloc_strndup(line, line+2, strlen(line)-3);
+ W_ERROR_HAVE_NO_MEMORY(curkey);
error = callbacks->del_key(callback_data,
curkey);
+
if (!W_ERROR_IS_OK(error)) {
DEBUG(0,("Error deleting key %s\n",
curkey));
@@ -194,6 +291,7 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
continue;
}
curkey = talloc_strndup(mem_ctx, line+1, strlen(line)-2);
+ W_ERROR_HAVE_NO_MEMORY(curkey);
error = callbacks->add_key(callback_data, curkey);
if (!W_ERROR_IS_OK(error)) {
@@ -207,59 +305,130 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd,
}
/* Deleting/Changing value */
- p = strchr_m(line, '=');
- if (p == NULL) {
- DEBUG(0, ("Malformed line\n"));
- talloc_free(line);
- continue;
- }
+ if (continue_next_line) {
+ continue_next_line = 0;
- *p = '\0'; p++;
+ /* Continued data start with two whitespaces */
+ if (line[0] != ' ' || line[1] != ' ') {
+ DEBUG(0, ("Malformed line: %s\n", line));
+ talloc_free(line);
+ continue;
+ }
+ p = line + 2;
- if (curkey == NULL) {
- DEBUG(0, ("Value change without key\n"));
- talloc_free(line);
- continue;
- }
+ /* Continue again if line ends with a backslash */
+ if (line[strlen(line)-1] == '\\') {
+ line[strlen(line)-1] = '\0';
+ continue_next_line = 1;
+ data_str = talloc_strdup_append(data_str, p);
+ talloc_free(line);
+ continue;
+ }
+ data_str = talloc_strdup_append(data_str, p);
+ } else {
+ p = strchr_m(line, '=');
+ if (p == NULL) {
+ DEBUG(0, ("Malformed line: %s\n", line));
+ talloc_free(line);
+ continue;
+ }
- /* Delete value */
- if (strcmp(p, "-") == 0) {
- error = callbacks->del_value(callback_data,
- curkey, line);
- if (!W_ERROR_IS_OK(error)) {
- DEBUG(0, ("Error deleting value %s in key %s\n",
- line, curkey));
- talloc_free(mem_ctx);
- return error;
+ *p = '\0'; p++;
+
+
+ if (curkey == NULL) {
+ DEBUG(0, ("Value change without key\n"));
+ talloc_free(line);
+ continue;
}
- talloc_free(line);
- continue;
- }
+ /* Values should be double-quoted */
+ if (line[0] != '"') {
+ DEBUG(0, ("Malformed line\n"));
+ talloc_free(line);
+ continue;
+ }
- q = strchr_m(p, ':');
- if (q) {
- *q = '\0';
- q++;
- }
+ /* Chop of the quotes and store as value */
+ value = talloc_strndup(mem_ctx, line+1,strlen(line)-2);
- reg_string_to_val(line, iconv_convenience,
- q?p:"REG_SZ", q?q:p,
- &value_type, &value);
+ /* Delete value */
+ if (p[0] == '-') {
+ error = callbacks->del_value(callback_data,
+ curkey, value);
- error = callbacks->set_value(callback_data, curkey, line,
- value_type, value);
+ /* Ignore if key does not exist (WERR_BADFILE)
+ * Consistent with Windows behaviour */
+ if (!W_ERROR_IS_OK(error) &&
+ !W_ERROR_EQUAL(error, WERR_BADFILE)) {
+ DEBUG(0, ("Error deleting value %s in key %s\n",
+ value, curkey));
+ talloc_free(mem_ctx);
+ return error;
+ }
+
+ talloc_free(line);
+ talloc_free(value);
+ continue;
+ }
+
+ /* Do not look for colons in strings */
+ if (p[0] == '"') {
+ q = NULL;
+ data_str = talloc_strndup(mem_ctx, p+1,strlen(p)-2);
+ } else {
+ /* Split the value type from the data */
+ q = strchr_m(p, ':');
+ if (q) {
+ *q = '\0';
+ q++;
+ type_str = talloc_strdup(mem_ctx, p);
+ data_str = talloc_strdup(mem_ctx, q);
+ } else {
+ data_str = talloc_strdup(mem_ctx, p);
+ }
+ }
+
+ /* Backslash before the CRLF means continue on next line */
+ if (data_str[strlen(data_str)-1] == '\\') {
+ data_str[strlen(data_str)-1] = '\0';
+ talloc_free(line);
+ continue_next_line = 1;
+ continue;
+ }
+ }
+ DEBUG(9, ("About to write %s with type %s, length %ld: %s\n", value, type_str, (long) strlen(data_str), data_str));
+ result = reg_string_to_val(value,
+ type_str?type_str:"REG_SZ", data_str,
+ &value_type, &data);
+ if (!result) {
+ DEBUG(0, ("Error converting string to value for line:\n%s\n",
+ line));
+ return WERR_GENERAL_FAILURE;
+ }
+
+ error = callbacks->set_value(callback_data, curkey, value,
+ value_type, data);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error setting value for %s in %s\n",
- line, curkey));
+ value, curkey));
talloc_free(mem_ctx);
return error;
}
+ /* Clean up buffers */
+ if (type_str != NULL) {
+ talloc_free(type_str);
+ type_str = NULL;
+ }
+ talloc_free(data_str);
+ talloc_free(value);
talloc_free(line);
}
close(fd);
+ talloc_free(mem_ctx);
+
return WERR_OK;
}
diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c
index 30a9aea2a5..28b56dd7e9 100644
--- a/source4/lib/registry/patchfile_preg.c
+++ b/source4/lib/registry/patchfile_preg.c
@@ -33,7 +33,7 @@ static WERROR preg_read_utf16(int fd, char *c)
{
uint16_t v;
- if (read(fd, &v, 2) < 2) {
+ if (read(fd, &v, sizeof(uint16_t)) < sizeof(uint16_t)) {
return WERR_GENERAL_FAILURE;
}
push_codepoint(c, v);
@@ -41,13 +41,12 @@ static WERROR preg_read_utf16(int fd, char *c)
}
static WERROR preg_write_utf16(int fd, const char *string)
{
- codepoint_t v;
- uint16_t i;
- size_t size;
+ uint16_t v;
+ size_t i, size;
for (i = 0; i < strlen(string); i+=size) {
v = next_codepoint(&string[i], &size);
- if (write(fd, &v, 2) < 2) {
+ if (write(fd, &v, sizeof(uint16_t)) < sizeof(uint16_t)) {
return WERR_GENERAL_FAILURE;
}
}
@@ -88,15 +87,26 @@ static WERROR reg_preg_diff_del_key(void *_data, const char *key_name)
struct preg_data *data = (struct preg_data *)_data;
char *parent_name;
DATA_BLOB blob;
-
- parent_name = talloc_strndup(data->ctx, key_name, strrchr(key_name, '\\')-key_name);
- blob.data = (uint8_t *)talloc_strndup(data->ctx, key_name+(strrchr(key_name, '\\')-key_name)+1,
- strlen(key_name)-(strrchr(key_name, '\\')-key_name));
+ WERROR werr;
+
+ parent_name = talloc_strndup(data->ctx, key_name,
+ strrchr(key_name, '\\')-key_name);
+ W_ERROR_HAVE_NO_MEMORY(parent_name);
+ blob.data = (uint8_t*)talloc_strndup(data->ctx,
+ key_name+(strrchr(key_name, '\\')-key_name)+1,
+ strlen(key_name)-(strrchr(key_name, '\\')-key_name));
+ W_ERROR_HAVE_NO_MEMORY(blob.data);
blob.length = strlen((char *)blob.data)+1;
/* FIXME: These values should be accumulated to be written at done(). */
- return reg_preg_diff_set_value(data, parent_name, "**DeleteKeys", REG_SZ, blob);
+ werr = reg_preg_diff_set_value(data, parent_name, "**DeleteKeys",
+ REG_SZ, blob);
+
+ talloc_free(parent_name);
+ talloc_free(blob.data);
+
+ return werr;
}
static WERROR reg_preg_diff_del_value(void *_data, const char *key_name,
@@ -105,25 +115,40 @@ static WERROR reg_preg_diff_del_value(void *_data, const char *key_name,
struct preg_data *data = (struct preg_data *)_data;
char *val;
DATA_BLOB blob;
+ WERROR werr;
val = talloc_asprintf(data->ctx, "**Del.%s", value_name);
-
+ W_ERROR_HAVE_NO_MEMORY(val);
blob.data = (uint8_t *)talloc(data->ctx, uint32_t);
- *(uint32_t *)blob.data = 0;
- blob.length = 4;
- return reg_preg_diff_set_value(data, key_name, val, REG_DWORD, blob);
+ W_ERROR_HAVE_NO_MEMORY(blob.data);
+ SIVAL(blob.data, 0, 0);
+ blob.length = sizeof(uint32_t);
+
+ werr = reg_preg_diff_set_value(data, key_name, val, REG_DWORD, blob);
+
+ talloc_free(val);
+ talloc_free(blob.data);
+
+ return werr;
}
static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name)
{
struct preg_data *data = (struct preg_data *)_data;
DATA_BLOB blob;
+ WERROR werr;
blob.data = (uint8_t *)talloc(data->ctx, uint32_t);
- *(uint32_t *)blob.data = 0;
- blob.length = 4;
+ W_ERROR_HAVE_NO_MEMORY(blob.data);
+ SIVAL(blob.data, 0, 0);
+ blob.length = sizeof(uint32_t);
+
+ werr = reg_preg_diff_set_value(data, key_name, "**DelVals.", REG_DWORD,
+ blob);
+
+ talloc_free(blob.data);
- return reg_preg_diff_set_value(data, key_name, "**DelVals.", REG_DWORD, blob);
+ return werr;
}
static WERROR reg_preg_diff_done(void *_data)
@@ -139,7 +164,6 @@ static WERROR reg_preg_diff_done(void *_data)
* Save registry diff
*/
_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
- struct smb_iconv_convenience *ic,
struct reg_diff_callbacks **callbacks,
void **callback_data)
{
@@ -164,8 +188,8 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
}
strncpy(preg_header.hdr, "PReg", 4);
- SIVAL(&preg_header, 4, 1);
- write(data->fd, (uint8_t *)&preg_header,8);
+ SIVAL(&preg_header.version, 0, 1);
+ write(data->fd, (uint8_t *)&preg_header, sizeof(preg_header));
data->ctx = ctx;
@@ -184,7 +208,6 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
* Load diff file
*/
_PUBLIC_ WERROR reg_preg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data)
{
@@ -205,7 +228,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
buf_ptr = buf;
/* Read first 8 bytes (the header) */
- if (read(fd, &preg_header, 8) != 8) {
+ if (read(fd, &preg_header, sizeof(preg_header)) != sizeof(preg_header)) {
DEBUG(0, ("Could not read PReg file: %s\n",
strerror(errno)));
ret = WERR_GENERAL_FAILURE;
@@ -254,7 +277,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
value_name = talloc_strdup(mem_ctx, buf);
/* Get the type */
- if (read(fd, &value_type, 4) < 4) {
+ if (read(fd, &value_type, sizeof(uint32_t)) < sizeof(uint32_t)) {
DEBUG(0, ("Error while reading PReg\n"));
ret = WERR_GENERAL_FAILURE;
goto cleanup;
@@ -269,12 +292,15 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
ret = WERR_GENERAL_FAILURE;
goto cleanup;
}
+
/* Get data length */
- if (read(fd, &length, 4) < 4) {
+ if (read(fd, &length, sizeof(uint32_t)) < sizeof(uint32_t)) {
DEBUG(0, ("Error while reading PReg\n"));
ret = WERR_GENERAL_FAILURE;
goto cleanup;
}
+ length = IVAL(&length, 0);
+
/* Read past delimiter */
buf_ptr = buf;
if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) &&
@@ -283,6 +309,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
ret = WERR_GENERAL_FAILURE;
goto cleanup;
}
+
/* Get the data */
buf_ptr = buf;
if (length < buf_size &&
diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c
index f68bfd15ef..b93258a856 100644
--- a/source4/lib/registry/pyregistry.c
+++ b/source4/lib/registry/pyregistry.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+ Copyright (C) Wilco Baan Hofman <wilco@baanhofman.nl> 2010
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
@@ -17,23 +18,18 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include <tevent.h>
#include <Python.h>
+#include "includes.h"
#include "libcli/util/pyerrors.h"
#include "lib/registry/registry.h"
-#include "scripting/python/modules.h" /* for py_iconv_convenience() */
-#include <pytalloc.h>
+#include "lib/talloc/pytalloc.h"
+#include "lib/events/events.h"
#include "auth/credentials/pycredentials.h"
#include "param/pyparam.h"
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
-PyAPI_DATA(PyTypeObject) PyRegistryKey;
-PyAPI_DATA(PyTypeObject) PyRegistry;
-PyAPI_DATA(PyTypeObject) PyHiveKey;
+extern PyTypeObject PyRegistryKey;
+extern PyTypeObject PyRegistry;
+extern PyTypeObject PyHiveKey;
/*#define PyRegistryKey_AsRegistryKey(obj) py_talloc_get_type(obj, struct registry_key)*/
#define PyRegistry_AsRegistryContext(obj) ((struct registry_context *)py_talloc_get_ptr(obj))
@@ -95,7 +91,7 @@ static PyObject *py_diff_apply(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
- result = reg_diff_apply(ctx, py_iconv_convenience(NULL), filename);
+ result = reg_diff_apply(ctx, filename);
PyErr_WERROR_IS_ERR_RAISE(result);
Py_RETURN_NONE;
@@ -163,7 +159,6 @@ PyTypeObject PyRegistry = {
.tp_methods = registry_methods,
.tp_new = registry_new,
.tp_basicsize = sizeof(py_talloc_Object),
- .tp_dealloc = py_talloc_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
};
@@ -176,7 +171,7 @@ static PyObject *py_hive_key_del(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- result = hive_key_del(key, name);
+ result = hive_key_del(NULL, key, name);
PyErr_WERROR_IS_ERR_RAISE(result);
@@ -203,7 +198,7 @@ static PyObject *py_hive_key_del_value(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- result = hive_key_del_value(key, name);
+ result = hive_key_del_value(NULL, key, name);
PyErr_WERROR_IS_ERR_RAISE(result);
@@ -224,7 +219,7 @@ static PyObject *py_hive_key_set_value(PyObject *self, PyObject *args)
if (value.data != NULL)
result = hive_key_set_value(key, name, type, value);
else
- result = hive_key_del_value(key, name);
+ result = hive_key_del_value(NULL, key, name);
PyErr_WERROR_IS_ERR_RAISE(result);
@@ -243,25 +238,70 @@ static PyMethodDef hive_key_methods[] = {
{ NULL }
};
-static PyObject *hive_open(PyTypeObject *type, PyObject *args, PyObject *kwargs)
-{
- /* reg_open_hive */
+static PyObject *hive_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
Py_RETURN_NONE;
}
+static PyObject *py_open_hive(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "location", "lp_ctx", "session_info", "credentials", NULL };
+ WERROR result;
+ struct loadparm_context *lp_ctx;
+ PyObject *py_lp_ctx, *py_session_info, *py_credentials;
+ struct auth_session_info *session_info;
+ struct cli_credentials *credentials;
+ char *location;
+ struct hive_key *hive_key;
+ TALLOC_CTX *mem_ctx;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO",
+ discard_const_p(char *, kwnames),
+ &location,
+ &py_lp_ctx, &py_session_info,
+ &py_credentials))
+ return NULL;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
+ if (lp_ctx == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ credentials = cli_credentials_from_py_object(py_credentials);
+ if (credentials == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Expected credentials");
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+ session_info = NULL;
+
+ result = reg_open_hive(NULL, location, session_info, credentials,
+ tevent_context_init(NULL),
+ lp_ctx, &hive_key);
+ talloc_free(mem_ctx);
+ PyErr_WERROR_IS_ERR_RAISE(result);
+
+ return py_talloc_steal(&PyHiveKey, hive_key);
+}
+
PyTypeObject PyHiveKey = {
.tp_name = "HiveKey",
.tp_methods = hive_key_methods,
- .tp_new = hive_open,
+ .tp_new = hive_new,
.tp_basicsize = sizeof(py_talloc_Object),
- .tp_dealloc = py_talloc_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
};
PyTypeObject PyRegistryKey = {
.tp_name = "RegistryKey",
.tp_basicsize = sizeof(py_talloc_Object),
- .tp_dealloc = py_talloc_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
};
@@ -270,23 +310,35 @@ static PyObject *py_open_samba(PyObject *self, PyObject *args, PyObject *kwargs)
const char *kwnames[] = { "lp_ctx", "session_info", NULL };
struct registry_context *reg_ctx;
WERROR result;
- struct loadparm_context *lp_ctx;
+ struct loadparm_context *lp_ctx;
PyObject *py_lp_ctx, *py_session_info, *py_credentials;
struct auth_session_info *session_info;
- struct cli_credentials *credentials;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO", discard_const_p(char *, kwnames),
- &py_lp_ctx, &py_session_info, &py_credentials))
+ struct cli_credentials *credentials;
+ TALLOC_CTX *mem_ctx;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO",
+ discard_const_p(char *, kwnames),
+ &py_lp_ctx, &py_session_info,
+ &py_credentials))
return NULL;
- lp_ctx = lp_from_py_object(py_lp_ctx);
- if (lp_ctx == NULL) {
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
+ if (lp_ctx == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+ talloc_free(mem_ctx);
return NULL;
- }
+ }
credentials = cli_credentials_from_py_object(py_credentials);
if (credentials == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected credentials");
+ talloc_free(mem_ctx);
return NULL;
}
@@ -294,11 +346,12 @@ static PyObject *py_open_samba(PyObject *self, PyObject *args, PyObject *kwargs)
result = reg_open_samba(NULL, &reg_ctx, NULL,
lp_ctx, session_info, credentials);
+ talloc_free(mem_ctx);
if (!W_ERROR_IS_OK(result)) {
PyErr_SetWERROR(result);
return NULL;
}
-
+
return py_talloc_steal(&PyRegistry, reg_ctx);
}
@@ -338,34 +391,43 @@ static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwar
PyObject *py_session_info = Py_None, *py_credentials = Py_None, *py_lp_ctx = Py_None;
WERROR result;
char *location;
- struct loadparm_context *lp_ctx;
- struct cli_credentials *credentials;
+ struct loadparm_context *lp_ctx;
+ struct cli_credentials *credentials;
struct hive_key *key;
struct auth_session_info *session_info;
+ TALLOC_CTX *mem_ctx;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO",
- discard_const_p(char *, kwnames),
- &location,
- &py_session_info, &py_credentials,
- &py_lp_ctx))
+ discard_const_p(char *, kwnames),
+ &location, &py_session_info,
+ &py_credentials, &py_lp_ctx))
+ return NULL;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
return NULL;
+ }
- lp_ctx = lp_from_py_object(py_lp_ctx);
- if (lp_ctx == NULL) {
+ lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
+ if (lp_ctx == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+ talloc_free(mem_ctx);
return NULL;
- }
+ }
credentials = cli_credentials_from_py_object(py_credentials);
if (credentials == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected credentials");
+ talloc_free(mem_ctx);
return NULL;
}
session_info = NULL; /* FIXME */
result = reg_open_ldb_file(NULL, location, session_info, credentials,
- tevent_context_init(NULL), lp_ctx, &key);
+ s4_event_context_init(NULL), lp_ctx, &key);
+ talloc_free(mem_ctx);
PyErr_WERROR_IS_ERR_RAISE(result);
return py_talloc_steal(&PyHiveKey, key);
@@ -400,6 +462,7 @@ static PyMethodDef py_registry_methods[] = {
{ "open_directory", py_open_directory, METH_VARARGS, "open_dir(location) -> key" },
{ "create_directory", py_create_directory, METH_VARARGS, "create_dir(location) -> key" },
{ "open_ldb", (PyCFunction)py_open_ldb_file, METH_VARARGS|METH_KEYWORDS, "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key" },
+ { "open_hive", (PyCFunction)py_open_hive, METH_VARARGS|METH_KEYWORDS, "open_hive(location, session_info=None, credentials=None, loadparm_context=None) -> key" },
{ "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> str" },
{ "get_predef_name", py_get_predef_name, METH_VARARGS, "get_predef_name(hkey) -> str" },
{ NULL }
@@ -408,6 +471,14 @@ static PyMethodDef py_registry_methods[] = {
void initregistry(void)
{
PyObject *m;
+ PyTypeObject *talloc_type = PyTalloc_GetObjectType();
+
+ if (talloc_type == NULL)
+ return;
+
+ PyHiveKey.tp_base = talloc_type;
+ PyRegistry.tp_base = talloc_type;
+ PyRegistryKey.tp_base = talloc_type;
if (PyType_Ready(&PyHiveKey) < 0)
return;
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c
index c5a74c7911..5ca7b7c66c 100644
--- a/source4/lib/registry/regf.c
+++ b/source4/lib/registry/regf.c
@@ -2,7 +2,7 @@
Samba CIFS implementation
Registry backend for REGF files
Copyright (C) 2005-2007 Jelmer Vernooij, jelmer@samba.org
- Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl
+ Copyright (C) 2006-2010 Wilco Baan Hofman, wilco@baanhofman.nl
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
@@ -49,10 +49,10 @@ struct regf_data {
int fd;
struct hbin_block **hbins;
struct regf_hdr *header;
- struct smb_iconv_convenience *iconv_convenience;
+ time_t last_write;
};
-static WERROR regf_save_hbin(struct regf_data *data);
+static WERROR regf_save_hbin(struct regf_data *data, bool flush);
struct regf_key_data {
struct hive_key key;
@@ -64,7 +64,7 @@ struct regf_key_data {
static struct hbin_block *hbin_by_offset(const struct regf_data *data,
uint32_t offset, uint32_t *rel_offset)
{
- int i;
+ unsigned int i;
for (i = 0; data->hbins[i]; i++) {
if (offset >= data->hbins[i]->offset_from_first &&
@@ -86,7 +86,7 @@ static struct hbin_block *hbin_by_offset(const struct regf_data *data,
static uint32_t regf_hdr_checksum(const uint8_t *buffer)
{
uint32_t checksum = 0, x;
- int i;
+ unsigned int i;
for (i = 0; i < 0x01FB; i+= 4) {
x = IVAL(buffer, i);
@@ -111,7 +111,7 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset)
hbin = hbin_by_offset(data, offset, &rel_offset);
if (hbin == NULL) {
- DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset));
+ DEBUG(1, ("Can't find HBIN at 0x%04x\n", offset));
return ret;
}
@@ -134,7 +134,7 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset)
static bool hbin_get_tdr(struct regf_data *regf, uint32_t offset,
TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p)
{
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
pull->data = hbin_get(regf, offset);
if (!pull->data.data) {
@@ -159,9 +159,9 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size,
uint32_t *offset)
{
DATA_BLOB ret;
- uint32_t rel_offset = -1; /* Relative offset ! */
+ uint32_t rel_offset = (uint32_t) -1; /* Relative offset ! */
struct hbin_block *hbin = NULL;
- int i;
+ unsigned int i;
*offset = 0;
@@ -217,6 +217,8 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size,
if (data->hbins[i] == NULL) {
DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n",
size));
+
+ /* Add extra hbin block */
data->hbins = talloc_realloc(data, data->hbins,
struct hbin_block *, i+2);
hbin = talloc(data->hbins, struct hbin_block);
@@ -225,17 +227,22 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size,
data->hbins[i] = hbin;
data->hbins[i+1] = NULL;
+ /* Set hbin data */
hbin->HBIN_ID = talloc_strdup(hbin, "hbin");
hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next);
hbin->offset_to_next = 0x1000;
hbin->unknown[0] = 0;
- hbin->unknown[0] = 0;
+ hbin->unknown[1] = 0;
unix_to_nt_time(&hbin->last_change, time(NULL));
hbin->block_size = hbin->offset_to_next;
hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20);
+ /* Update the regf header */
+ data->header->last_block += hbin->offset_to_next;
- rel_offset = 0x0;
+ /* Set the next block to it's proper size and set the
+ * rel_offset for this block */
SIVAL(hbin->data, size, hbin->block_size - size - 0x20);
+ rel_offset = 0x0;
}
/* Set size and mark as used */
@@ -261,13 +268,18 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob)
memcpy(dest.data, blob.data, blob.length);
+ /* Make sure that we have no tailing garbage in the block */
+ if (dest.length > blob.length) {
+ memset(dest.data + blob.length, 0, dest.length - blob.length);
+ }
+
return ret;
}
static uint32_t hbin_store_tdr(struct regf_data *data,
tdr_push_fn_t push_fn, void *p)
{
- struct tdr_push *push = tdr_push_init(data, data->iconv_convenience);
+ struct tdr_push *push = tdr_push_init(data);
uint32_t ret;
if (NT_STATUS_IS_ERR(push_fn(push, p))) {
@@ -310,7 +322,7 @@ static void hbin_free (struct regf_data *data, uint32_t offset)
size = -size;
/* If the next block is free, merge into big free block */
- if (rel_offset + size < hbin->offset_to_next) {
+ if (rel_offset + size < hbin->offset_to_next - 0x20) {
next_size = IVALS(hbin->data, rel_offset+size);
if (next_size > 0) {
size += next_size;
@@ -335,7 +347,7 @@ static uint32_t hbin_store_resize(struct regf_data *data,
int32_t orig_size;
int32_t needed_size;
int32_t possible_size;
- int i;
+ unsigned int i;
SMB_ASSERT(orig_offset > 0);
@@ -394,7 +406,7 @@ static uint32_t hbin_store_tdr_resize(struct regf_data *regf,
tdr_push_fn_t push_fn,
uint32_t orig_offset, void *p)
{
- struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience);
+ struct tdr_push *push = tdr_push_init(regf);
uint32_t ret;
if (NT_STATUS_IS_ERR(push_fn(push, p))) {
@@ -450,6 +462,7 @@ static WERROR regf_get_info(TALLOC_CTX *mem_ctx,
*classname = talloc_strndup(mem_ctx,
(char*)data.data,
private_data->nk->clsname_length);
+ W_ERROR_HAVE_NO_MEMORY(*classname);
} else
*classname = NULL;
}
@@ -484,7 +497,7 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx,
if (!hbin_get_tdr(regf, offset, nk,
(tdr_pull_fn_t)tdr_pull_nk_block, nk)) {
- DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
+ DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n", offset));
return NULL;
}
@@ -499,7 +512,7 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx,
static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
- int idx, const char **name,
+ uint32_t idx, const char **name,
uint32_t *data_type, DATA_BLOB *data)
{
const struct regf_key_data *private_data =
@@ -514,7 +527,8 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
tmp = hbin_get(regf, private_data->nk->values_offset);
if (!tmp.data) {
- DEBUG(0, ("Unable to find value list\n"));
+ DEBUG(0, ("Unable to find value list at 0x%x\n",
+ private_data->nk->values_offset));
return WERR_GENERAL_FAILURE;
}
@@ -529,22 +543,26 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
if (!hbin_get_tdr(regf, vk_offset, vk,
(tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
- DEBUG(0, ("Unable to get VK block at %d\n", vk_offset));
+ DEBUG(0, ("Unable to get VK block at 0x%x\n", vk_offset));
talloc_free(vk);
return WERR_GENERAL_FAILURE;
}
/* FIXME: name character set ?*/
- if (name != NULL)
+ if (name != NULL) {
*name = talloc_strndup(ctx, vk->data_name, vk->name_length);
+ W_ERROR_HAVE_NO_MEMORY(*name);
+ }
if (data_type != NULL)
*data_type = vk->data_type;
if (vk->data_length & 0x80000000) {
- vk->data_length &=~0x80000000;
- data->data = (uint8_t *)talloc_memdup(ctx, (uint8_t *)&vk->data_offset, vk->data_length);
- data->length = vk->data_length;
+ /* this is data of type "REG_DWORD" or "REG_DWORD_BIG_ENDIAN" */
+ data->data = talloc_size(ctx, sizeof(uint32_t));
+ W_ERROR_HAVE_NO_MEMORY(data->data);
+ SIVAL(data->data, 0, vk->data_offset);
+ data->length = sizeof(uint32_t);
} else {
*data = hbin_get(regf, vk->data_offset);
}
@@ -562,7 +580,7 @@ static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx,
struct hive_key *key, const char *name,
uint32_t *type, DATA_BLOB *data)
{
- int i;
+ unsigned int i;
const char *vname;
WERROR error;
@@ -597,15 +615,21 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
if (idx >= nk->num_subkeys)
return WERR_NO_MORE_ITEMS;
+ /* Make sure that we don't crash if the key is empty */
+ if (nk->subkeys_offset == -1) {
+ return WERR_NO_MORE_ITEMS;
+ }
+
data = hbin_get(private_data->hive, nk->subkeys_offset);
if (!data.data) {
- DEBUG(0, ("Unable to find subkey list\n"));
+ DEBUG(0, ("Unable to find subkey list at 0x%x\n",
+ nk->subkeys_offset));
return WERR_GENERAL_FAILURE;
}
if (!strncmp((char *)data.data, "li", 2)) {
struct li_block li;
- struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive);
DEBUG(10, ("Subkeys in LI list\n"));
pull->data = data;
@@ -626,7 +650,7 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
- struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive);
DEBUG(10, ("Subkeys in LF list\n"));
pull->data = data;
@@ -647,7 +671,7 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
key_off = lf.hr[idx].nk_offset;
} else if (!strncmp((char *)data.data, "lh", 2)) {
struct lh_block lh;
- struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive);
DEBUG(10, ("Subkeys in LH list\n"));
pull->data = data;
@@ -667,7 +691,7 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
key_off = lh.hr[idx].nk_offset;
} else if (!strncmp((char *)data.data, "ri", 2)) {
struct ri_block ri;
- struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(ctx);
uint16_t i;
uint16_t sublist_count = 0;
@@ -768,6 +792,7 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
*classname = talloc_strndup(ctx,
(char*)db.data,
ret->nk->clsname_length);
+ W_ERROR_HAVE_NO_MEMORY(*classname);
} else
*classname = NULL;
}
@@ -800,7 +825,7 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx,
return WERR_GENERAL_FAILURE;
}
- pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ pull = tdr_pull_init(ctx);
pull->data = subkey_data;
@@ -835,6 +860,11 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
struct nk_block *nk = private_data->nk;
uint32_t key_off = 0;
+ /* Make sure that we don't crash if the key is empty */
+ if (nk->subkeys_offset == -1) {
+ return WERR_BADFILE;
+ }
+
data = hbin_get(private_data->hive, nk->subkeys_offset);
if (!data.data) {
DEBUG(0, ("Unable to find subkey list\n"));
@@ -843,7 +873,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
if (!strncmp((char *)data.data, "li", 2)) {
struct li_block li;
- struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(ctx);
uint16_t i;
DEBUG(10, ("Subkeys in LI list\n"));
@@ -874,7 +904,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_BADFILE;
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
- struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(ctx);
uint16_t i;
DEBUG(10, ("Subkeys in LF list\n"));
@@ -909,7 +939,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_BADFILE;
} else if (!strncmp((char *)data.data, "lh", 2)) {
struct lh_block lh;
- struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(ctx);
uint16_t i;
uint32_t hash;
@@ -946,7 +976,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_BADFILE;
} else if (!strncmp((char *)data.data, "ri", 2)) {
struct ri_block ri;
- struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(ctx);
uint16_t i, j;
DEBUG(10, ("Subkeys in RI list\n"));
@@ -1051,7 +1081,7 @@ static WERROR regf_set_sec_desc(struct hive_key *key,
(tdr_pull_fn_t) tdr_pull_nk_block, &root);
/* Push the security descriptor to a blob */
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL,
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf,
sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {
DEBUG(0, ("Unable to push security descriptor\n"));
return WERR_GENERAL_FAILURE;
@@ -1204,7 +1234,7 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key,
data.data = sk.sec_desc;
data.length = sk.rec_size;
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, NULL, *sd,
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, *sd,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) {
DEBUG(0, ("Error parsing security descriptor\n"));
return WERR_GENERAL_FAILURE;
@@ -1288,8 +1318,10 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
}
if (!strncmp((char *)data.data, "li", 2)) {
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
struct li_block li;
+ struct nk_block sub_nk;
+ int32_t i, j;
pull->data = data;
@@ -1306,10 +1338,30 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
return WERR_BADFILE;
}
+ /*
+ * Find the position to store the pointer
+ * Extensive testing reveils that at least on windows 7 subkeys
+ * *MUST* be stored in alphabetical order
+ */
+ for (i = 0; i < li.key_count; i++) {
+ /* Get the nk */
+ hbin_get_tdr(regf, li.nk_offset[i], regf,
+ (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
+ if (strcasecmp(name, sub_nk.key_name) < 0) {
+ break;
+ }
+ }
+
li.nk_offset = talloc_realloc(regf, li.nk_offset,
uint32_t, li.key_count+1);
W_ERROR_HAVE_NO_MEMORY(li.nk_offset);
- li.nk_offset[li.key_count] = key_offset;
+
+ /* Move everything behind this offset */
+ for (j = li.key_count - 1; j >= i; j--) {
+ li.nk_offset[j+1] = li.nk_offset[j];
+ }
+
+ li.nk_offset[i] = key_offset;
li.key_count++;
*ret = hbin_store_tdr_resize(regf,
(tdr_push_fn_t)tdr_push_li_block,
@@ -1317,8 +1369,10 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(li.nk_offset);
} else if (!strncmp((char *)data.data, "lf", 2)) {
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
struct lf_block lf;
+ struct nk_block sub_nk;
+ int32_t i, j;
pull->data = data;
@@ -1330,11 +1384,31 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(pull);
SMB_ASSERT(!strncmp(lf.header, "lf", 2));
+ /*
+ * Find the position to store the hash record
+ * Extensive testing reveils that at least on windows 7 subkeys
+ * *MUST* be stored in alphabetical order
+ */
+ for (i = 0; i < lf.key_count; i++) {
+ /* Get the nk */
+ hbin_get_tdr(regf, lf.hr[i].nk_offset, regf,
+ (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
+ if (strcasecmp(name, sub_nk.key_name) < 0) {
+ break;
+ }
+ }
+
lf.hr = talloc_realloc(regf, lf.hr, struct hash_record,
lf.key_count+1);
W_ERROR_HAVE_NO_MEMORY(lf.hr);
- lf.hr[lf.key_count].nk_offset = key_offset;
- lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4);
+
+ /* Move everything behind this hash record */
+ for (j = lf.key_count - 1; j >= i; j--) {
+ lf.hr[j+1] = lf.hr[j];
+ }
+
+ lf.hr[i].nk_offset = key_offset;
+ lf.hr[i].hash = talloc_strndup(lf.hr, name, 4);
W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash);
lf.key_count++;
*ret = hbin_store_tdr_resize(regf,
@@ -1343,8 +1417,10 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(lf.hr);
} else if (!strncmp((char *)data.data, "lh", 2)) {
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
struct lh_block lh;
+ struct nk_block sub_nk;
+ int32_t i, j;
pull->data = data;
@@ -1356,11 +1432,31 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(pull);
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
+ /*
+ * Find the position to store the hash record
+ * Extensive testing reveils that at least on windows 7 subkeys
+ * *MUST* be stored in alphabetical order
+ */
+ for (i = 0; i < lh.key_count; i++) {
+ /* Get the nk */
+ hbin_get_tdr(regf, lh.hr[i].nk_offset, regf,
+ (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
+ if (strcasecmp(name, sub_nk.key_name) < 0) {
+ break;
+ }
+ }
+
lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash,
lh.key_count+1);
W_ERROR_HAVE_NO_MEMORY(lh.hr);
- lh.hr[lh.key_count].nk_offset = key_offset;
- lh.hr[lh.key_count].base37 = regf_create_lh_hash(name);
+
+ /* Move everything behind this hash record */
+ for (j = lh.key_count - 1; j >= i; j--) {
+ lh.hr[j+1] = lh.hr[j];
+ }
+
+ lh.hr[i].nk_offset = key_offset;
+ lh.hr[i].base37 = regf_create_lh_hash(name);
lh.key_count++;
*ret = hbin_store_tdr_resize(regf,
(tdr_push_fn_t)tdr_push_lh_block,
@@ -1392,7 +1488,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
if (strncmp((char *)data.data, "li", 2) == 0) {
struct li_block li;
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
uint16_t i;
bool found_offset = false;
@@ -1436,7 +1532,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
list_offset, &li);
} else if (strncmp((char *)data.data, "lf", 2) == 0) {
struct lf_block lf;
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
uint16_t i;
bool found_offset = false;
@@ -1482,7 +1578,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
list_offset, &lf);
} else if (strncmp((char *)data.data, "lh", 2) == 0) {
struct lh_block lh;
- struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
+ struct tdr_pull *pull = tdr_pull_init(regf);
uint16_t i;
bool found_offset = false;
@@ -1537,7 +1633,8 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
return WERR_OK;
}
-static WERROR regf_del_value (struct hive_key *key, const char *name)
+static WERROR regf_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
+ const char *name)
{
struct regf_key_data *private_data = (struct regf_key_data *)key;
struct regf_data *regf = private_data->hive;
@@ -1546,7 +1643,7 @@ static WERROR regf_del_value (struct hive_key *key, const char *name)
uint32_t vk_offset;
bool found_offset = false;
DATA_BLOB values;
- uint32_t i;
+ unsigned int i;
if (nk->values_offset == -1) {
return WERR_BADFILE;
@@ -1591,11 +1688,12 @@ static WERROR regf_del_value (struct hive_key *key, const char *name)
hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block,
private_data->offset, nk);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
-static WERROR regf_del_key(const struct hive_key *parent, const char *name)
+static WERROR regf_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
+ const char *name)
{
const struct regf_key_data *private_data =
(const struct regf_key_data *)parent;
@@ -1622,7 +1720,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
if (key->nk->subkeys_offset != -1) {
char *sk_name;
struct hive_key *sk = (struct hive_key *)key;
- int i = key->nk->num_subkeys;
+ unsigned int i = key->nk->num_subkeys;
while (i--) {
/* Get subkey information. */
error = regf_get_subkey_by_index(parent_nk, sk, 0,
@@ -1634,7 +1732,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
}
/* Delete subkey. */
- error = regf_del_key(sk, sk_name);
+ error = regf_del_key(NULL, sk, sk_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't delete key '%s'.\n", sk_name));
return error;
@@ -1648,7 +1746,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
char *val_name;
struct hive_key *sk = (struct hive_key *)key;
DATA_BLOB data;
- int i = key->nk->num_values;
+ unsigned int i = key->nk->num_values;
while (i--) {
/* Get value information. */
error = regf_get_value(parent_nk, sk, 0,
@@ -1660,7 +1758,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
}
/* Delete value. */
- error = regf_del_value(sk, val_name);
+ error = regf_del_value(NULL, sk, val_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't delete value '%s'.\n", val_name));
return error;
@@ -1689,7 +1787,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
}
hbin_free(private_data->hive, key->offset);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
@@ -1716,7 +1814,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
nk.unknown_offset = -1;
nk.num_values = 0;
nk.values_offset = -1;
- memset(nk.unk3, 0, 5);
+ memset(nk.unk3, 0, sizeof(nk.unk3));
nk.clsname_offset = -1; /* FIXME: fill in */
nk.clsname_length = 0;
nk.key_name = name;
@@ -1727,7 +1825,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
if (!hbin_get_tdr(regf, regf->header->data_offset, root,
(tdr_pull_fn_t)tdr_pull_nk_block, root)) {
- DEBUG(0, ("Unable to find HBIN data for offset %d\n",
+ DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n",
regf->header->data_offset));
return WERR_GENERAL_FAILURE;
}
@@ -1752,7 +1850,8 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,
*ret = (struct hive_key *)regf_get_key(ctx, regf, offset);
- return regf_save_hbin(private_data->hive);
+ DEBUG(9, ("Storing key %s\n", name));
+ return regf_save_hbin(private_data->hive, 0);
}
static WERROR regf_set_value(struct hive_key *key, const char *name,
@@ -1763,7 +1862,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
struct nk_block *nk = private_data->nk;
struct vk_block vk;
uint32_t i;
- uint32_t tmp_vk_offset, vk_offset, old_vk_offset = -1;
+ uint32_t tmp_vk_offset, vk_offset, old_vk_offset = (uint32_t) -1;
DATA_BLOB values;
ZERO_STRUCT(vk);
@@ -1777,7 +1876,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
if (!hbin_get_tdr(regf, tmp_vk_offset, private_data,
(tdr_pull_fn_t)tdr_pull_vk_block,
&vk)) {
- DEBUG(0, ("Unable to get VK block at %d\n",
+ DEBUG(0, ("Unable to get VK block at 0x%x\n",
tmp_vk_offset));
return WERR_GENERAL_FAILURE;
}
@@ -1786,11 +1885,9 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
break;
}
}
- /* Free data, if any */
- if (!(vk.data_length & 0x80000000)) {
- hbin_free(regf, vk.data_offset);
- }
}
+
+ /* If it's new, create the vk struct, if it's old, free the old data. */
if (old_vk_offset == -1) {
vk.header = "vk";
vk.name_length = strlen(name);
@@ -1801,13 +1898,23 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
vk.data_name = NULL;
vk.flag = 0;
}
+ } else {
+ /* Free data, if any */
+ if (!(vk.data_length & 0x80000000)) {
+ hbin_free(regf, vk.data_offset);
+ }
}
+
/* Set the type and data */
vk.data_length = data.length;
vk.data_type = type;
- if (type == REG_DWORD) {
+ if ((type == REG_DWORD) || (type == REG_DWORD_BIG_ENDIAN)) {
+ if (vk.data_length != sizeof(uint32_t)) {
+ DEBUG(0, ("DWORD or DWORD_BIG_ENDIAN value with size other than 4 byte!\n"));
+ return WERR_NOT_SUPPORTED;
+ }
vk.data_length |= 0x80000000;
- vk.data_offset = *(uint32_t *)data.data;
+ vk.data_offset = IVAL(data.data, 0);
} else {
/* Store data somewhere */
vk.data_offset = hbin_store(regf, data);
@@ -1863,16 +1970,23 @@ static WERROR regf_set_value(struct hive_key *key, const char *name,
hbin_store_tdr_resize(regf,
(tdr_push_fn_t) tdr_push_nk_block,
private_data->offset, nk);
- return regf_save_hbin(private_data->hive);
+ return regf_save_hbin(private_data->hive, 0);
}
-static WERROR regf_save_hbin(struct regf_data *regf)
+static WERROR regf_save_hbin(struct regf_data *regf, bool flush)
{
- struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience);
- int i;
+ struct tdr_push *push = tdr_push_init(regf);
+ unsigned int i;
W_ERROR_HAVE_NO_MEMORY(push);
+ /* Only write once every 5 seconds, or when flush is set */
+ if (!flush && regf->last_write + 5 >= time(NULL)) {
+ return WERR_OK;
+ }
+
+ regf->last_write = time(NULL);
+
if (lseek(regf->fd, 0, SEEK_SET) == -1) {
DEBUG(0, ("Error lseeking in regf file\n"));
return WERR_GENERAL_FAILURE;
@@ -1886,7 +2000,7 @@ static WERROR regf_save_hbin(struct regf_data *regf)
regf->header->chksum = regf_hdr_checksum(push->data.data);
talloc_free(push);
- if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience,
+ if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd,
(tdr_push_fn_t)tdr_push_regf_hdr,
regf->header))) {
DEBUG(0, ("Error writing registry file header\n"));
@@ -1899,7 +2013,7 @@ static WERROR regf_save_hbin(struct regf_data *regf)
}
for (i = 0; regf->hbins[i]; i++) {
- if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience,
+ if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd,
(tdr_push_fn_t)tdr_push_hbin_block,
regf->hbins[i]))) {
DEBUG(0, ("Error writing HBIN block\n"));
@@ -1911,7 +2025,6 @@ static WERROR regf_save_hbin(struct regf_data *regf)
}
WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
- struct smb_iconv_convenience *iconv_convenience,
const char *location,
int minor_version, struct hive_key **key)
{
@@ -1926,8 +2039,6 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
- regf->iconv_convenience = iconv_convenience;
-
W_ERROR_HAVE_NO_MEMORY(regf);
DEBUG(5, ("Attempting to create registry file\n"));
@@ -1962,7 +2073,7 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
regf->hbins[0] = NULL;
nk.header = "nk";
- nk.type = REG_SUB_KEY;
+ nk.type = REG_ROOT_KEY;
unix_to_nt_time(&nk.last_change, time(NULL));
nk.uk1 = 0;
nk.parent_offset = -1;
@@ -1996,7 +2107,7 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
NULL);
/* Push the security descriptor to a blob */
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL,
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf,
sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {
DEBUG(0, ("Unable to push security descriptor\n"));
return WERR_GENERAL_FAILURE;
@@ -2027,31 +2138,62 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
*key = (struct hive_key *)regf_get_key(parent_ctx, regf,
regf->header->data_offset);
- error = regf_save_hbin(regf);
+ error = regf_save_hbin(regf, 1);
if (!W_ERROR_IS_OK(error)) {
return error;
}
/* We can drop our own reference now that *key will have created one */
- talloc_free(regf);
+ talloc_unlink(NULL, regf);
+
+ return WERR_OK;
+}
+
+static WERROR regf_flush_key(struct hive_key *key)
+{
+ struct regf_key_data *private_data = (struct regf_key_data *)key;
+ struct regf_data *regf = private_data->hive;
+ WERROR error;
+
+ error = regf_save_hbin(regf, 1);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(0, ("Failed to flush regf to disk\n"));
+ return error;
+ }
return WERR_OK;
}
+static int regf_destruct(struct regf_data *regf)
+{
+ WERROR error;
+
+ /* Write to disk */
+ error = regf_save_hbin(regf, 1);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(0, ("Failed to flush registry to disk\n"));
+ return -1;
+ }
+
+ /* Close file descriptor */
+ close(regf->fd);
+
+ return 0;
+}
+
WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
- struct smb_iconv_convenience *iconv_convenience, struct hive_key **key)
+ struct hive_key **key)
{
struct regf_data *regf;
struct regf_hdr *regf_hdr;
struct tdr_pull *pull;
- int i;
+ unsigned int i;
regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data);
-
- regf->iconv_convenience = iconv_convenience;
-
W_ERROR_HAVE_NO_MEMORY(regf);
+ talloc_set_destructor(regf, regf_destruct);
+
DEBUG(5, ("Attempting to load registry file\n"));
/* Get the header */
@@ -2064,7 +2206,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
return WERR_GENERAL_FAILURE;
}
- pull = tdr_pull_init(regf, regf->iconv_convenience);
+ pull = tdr_pull_init(regf);
pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, 0, regf);
@@ -2162,4 +2304,5 @@ static struct hive_operations reg_backend_regf = {
.set_value = regf_set_value,
.del_key = regf_del_key,
.delete_value = regf_del_value,
+ .flush_key = regf_flush_key
};
diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl
index ffd7072b7a..064aaf09ce 100644
--- a/source4/lib/registry/regf.idl
+++ b/source4/lib/registry/regf.idl
@@ -24,7 +24,7 @@ interface regf
[noprint] struct regf_version {
[value(1)] uint32 major;
- [value(3)] uint32 minor;
+ uint32 minor;
[value(0)] uint32 release;
[value(1)] uint32 build;
};
@@ -74,8 +74,8 @@ interface regf
};
[noprint] enum reg_key_type {
- REG_ROOT_KEY = 0x20,
- REG_SUB_KEY = 0x2C,
+ REG_ROOT_KEY = 0x2C,
+ REG_SUB_KEY = 0x20,
REG_SYM_LINK = 0x10
};
diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h
index a97d9f6184..8fc025777b 100644
--- a/source4/lib/registry/registry.h
+++ b/source4/lib/registry/registry.h
@@ -23,7 +23,6 @@
struct registry_context;
struct loadparm_context;
-struct smb_iconv_convenience;
#include <talloc.h>
#include "libcli/util/werror.h"
@@ -70,14 +69,15 @@ struct hive_operations {
* Add a new key.
*/
WERROR (*add_key) (TALLOC_CTX *ctx,
- const struct hive_key *parent_key, const char *name,
+ const struct hive_key *parent_key, const char *path,
const char *classname,
struct security_descriptor *desc,
struct hive_key **key);
/**
* Remove an existing key.
*/
- WERROR (*del_key) (const struct hive_key *key, const char *name);
+ WERROR (*del_key) (TALLOC_CTX *mem_ctx,
+ const struct hive_key *key, const char *name);
/**
* Force write of a key to disk.
@@ -88,7 +88,7 @@ struct hive_operations {
* Retrieve a registry value with a specific index.
*/
WERROR (*enum_value) (TALLOC_CTX *mem_ctx,
- struct hive_key *key, int idx,
+ struct hive_key *key, uint32_t idx,
const char **name, uint32_t *type,
DATA_BLOB *data);
@@ -108,7 +108,8 @@ struct hive_operations {
/**
* Remove a value.
*/
- WERROR (*delete_value) (struct hive_key *key, const char *name);
+ WERROR (*delete_value) (TALLOC_CTX *mem_ctx,
+ struct hive_key *key, const char *name);
/* Security Descriptors */
@@ -166,7 +167,8 @@ WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key,
const char *name, const char *classname,
struct security_descriptor *desc,
struct hive_key **key);
-WERROR hive_key_del(const struct hive_key *key, const char *name);
+WERROR hive_key_del(TALLOC_CTX *mem_ctx,
+ const struct hive_key *key, const char *name);
WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx,
const struct hive_key *key, const char *name,
struct hive_key **subkey);
@@ -193,7 +195,8 @@ WERROR hive_get_sec_desc(TALLOC_CTX *mem_ctx,
WERROR hive_set_sec_desc(struct hive_key *key,
const struct security_descriptor *security);
-WERROR hive_key_del_value(struct hive_key *key, const char *name);
+WERROR hive_key_del_value(TALLOC_CTX *mem_ctx,
+ struct hive_key *key, const char *name);
WERROR hive_key_flush(struct hive_key *key);
@@ -202,8 +205,7 @@ WERROR hive_key_flush(struct hive_key *key);
WERROR reg_open_directory(TALLOC_CTX *parent_ctx,
const char *location, struct hive_key **key);
WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
- const char *location, struct smb_iconv_convenience *iconv_convenience,
- struct hive_key **key);
+ const char *location, struct hive_key **key);
WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
struct auth_session_info *session_info,
struct cli_credentials *credentials,
@@ -215,7 +217,6 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
WERROR reg_create_directory(TALLOC_CTX *parent_ctx,
const char *location, struct hive_key **key);
WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
- struct smb_iconv_convenience *iconv_convenience,
const char *location,
int major_version,
struct hive_key **key);
@@ -304,9 +305,11 @@ struct registry_operations {
struct security_descriptor *security,
struct registry_key **key);
- WERROR (*delete_key) (struct registry_key *key, const char *name);
+ WERROR (*delete_key) (TALLOC_CTX *mem_ctx,
+ struct registry_key *key, const char *name);
- WERROR (*delete_value) (struct registry_key *key, const char *name);
+ WERROR (*delete_value) (TALLOC_CTX *mem_ctx,
+ struct registry_key *key, const char *name);
WERROR (*enum_key) (TALLOC_CTX *mem_ctx,
const struct registry_key *key, uint32_t idx,
@@ -411,7 +414,7 @@ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx,
uint32_t *max_valbufsize);
WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx,
const struct registry_key *key,
- int idx,
+ uint32_t idx,
const char **name,
const char **classname,
NTTIME *last_mod_time);
@@ -424,7 +427,8 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx,
const char *name,
uint32_t *type,
DATA_BLOB *data);
-WERROR reg_key_del(struct registry_key *parent, const char *name);
+WERROR reg_key_del(TALLOC_CTX *mem_ctx,
+ struct registry_key *parent, const char *name);
WERROR reg_key_add_name(TALLOC_CTX *mem_ctx,
struct registry_key *parent, const char *name,
const char *classname,
@@ -434,7 +438,8 @@ WERROR reg_val_set(struct registry_key *key, const char *value,
uint32_t type, DATA_BLOB data);
WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key,
struct security_descriptor **secdesc);
-WERROR reg_del_value(struct registry_key *key, const char *valname);
+WERROR reg_del_value(TALLOC_CTX *mem_ctx,
+ struct registry_key *key, const char *valname);
WERROR reg_key_flush(struct registry_key *key);
WERROR reg_create_key(TALLOC_CTX *mem_ctx,
struct registry_key *parent,
@@ -445,10 +450,15 @@ WERROR reg_create_key(TALLOC_CTX *mem_ctx,
/* Utility functions */
const char *str_regtype(int type);
-char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t type, const DATA_BLOB data);
-char *reg_val_description(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const char *name,
+bool push_reg_sz(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *s);
+bool push_reg_multi_sz(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **a);
+bool pull_reg_sz(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char **s);
+bool pull_reg_multi_sz(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char ***a);
+int regtype_by_string(const char *str);
+char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, const DATA_BLOB data);
+char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name,
uint32_t type, const DATA_BLOB data);
-bool reg_string_to_val(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const char *type_str,
+bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str,
const char *data_str, uint32_t *type, DATA_BLOB *data);
WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle,
const char *name, struct registry_key **result);
@@ -485,18 +495,16 @@ struct reg_diff_callbacks {
};
WERROR reg_diff_apply(struct registry_context *ctx,
- struct smb_iconv_convenience *ic, const char *filename);
+ const char *filename);
WERROR reg_generate_diff(struct registry_context *ctx1,
struct registry_context *ctx2,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
- struct smb_iconv_convenience *iconv_convenience,
struct reg_diff_callbacks **callbacks,
void **callback_data);
WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
- struct smb_iconv_convenience *ic,
struct reg_diff_callbacks **callbacks,
void **callback_data);
WERROR reg_generate_diff_key(struct registry_key *oldkey,
@@ -505,17 +513,14 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
WERROR reg_diff_load(const char *filename,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
WERROR reg_dotreg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
WERROR reg_preg_diff_load(int fd,
- struct smb_iconv_convenience *iconv_convenience,
const struct reg_diff_callbacks *callbacks,
void *callback_data);
diff --git a/source4/lib/registry/registry.pc.in b/source4/lib/registry/registry.pc.in
index d981a45b2c..e9239317e2 100644
--- a/source4/lib/registry/registry.pc.in
+++ b/source4/lib/registry/registry.pc.in
@@ -7,6 +7,6 @@ Name: registry
Description: Windows-style registry library
Requires: talloc
Requires.private: ldb
-Version: 0.0.1
-Libs: -L${libdir} -lregistry
+Version: @PACKAGE_VERSION@
+Libs: @LIB_RPATH@ -L${libdir} -lregistry
Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c
index 0cb6b118a5..f1e14c1b86 100644
--- a/source4/lib/registry/rpc.c
+++ b/source4/lib/registry/rpc.c
@@ -27,8 +27,7 @@
struct rpc_key {
struct registry_key key;
struct policy_handle pol;
- struct dcerpc_pipe *pipe;
-
+ struct dcerpc_binding_handle *binding_handle;
const char* classname;
uint32_t num_subkeys;
uint32_t max_subkeylen;
@@ -43,6 +42,7 @@ struct rpc_key {
struct rpc_registry_context {
struct registry_context context;
struct dcerpc_pipe *pipe;
+ struct dcerpc_binding_handle *binding_handle;
};
static struct registry_operations reg_backend_rpc;
@@ -51,7 +51,7 @@ static struct registry_operations reg_backend_rpc;
* This is the RPC backend for the registry library.
*/
-#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
+#define openhive(u) static WERROR open_ ## u(struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
{ \
struct winreg_Open ## u r; \
NTSTATUS status; \
@@ -61,7 +61,7 @@ static struct registry_operations reg_backend_rpc;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \
r.out.handle = hnd;\
\
- status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
+ status = dcerpc_winreg_Open ## u ## _r(b, mem_ctx, &r); \
\
if (!NT_STATUS_IS_OK(status)) { \
DEBUG(1, ("OpenHive failed - %s\n", nt_errstr(status))); \
@@ -81,7 +81,7 @@ openhive(HKCC)
static struct {
uint32_t hkey;
- WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *,
+ WERROR (*open) (struct dcerpc_binding_handle *b, TALLOC_CTX *,
struct policy_handle *h);
} known_hives[] = {
{ HKEY_LOCAL_MACHINE, open_HKLM },
@@ -117,12 +117,13 @@ static WERROR rpc_get_predefined_key(struct registry_context *ctx,
}
mykeydata = talloc_zero(ctx, struct rpc_key);
+ W_ERROR_HAVE_NO_MEMORY(mykeydata);
mykeydata->key.context = ctx;
- mykeydata->pipe = talloc_reference(mykeydata, rctx->pipe);
+ mykeydata->binding_handle = rctx->binding_handle;
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
*k = (struct registry_key *)mykeydata;
- return known_hives[n].open(mykeydata->pipe, mykeydata, &(mykeydata->pol));
+ return known_hives[n].open(mykeydata->binding_handle, mykeydata, &mykeydata->pol);
}
#if 0
@@ -160,8 +161,9 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
NTSTATUS status;
mykeydata = talloc_zero(mem_ctx, struct rpc_key);
+ W_ERROR_HAVE_NO_MEMORY(mykeydata);
mykeydata->key.context = parentkeydata->key.context;
- mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe);
+ mykeydata->binding_handle = parentkeydata->binding_handle;
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
*key = (struct registry_key *)mykeydata;
@@ -170,11 +172,11 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
ZERO_STRUCT(r);
r.in.parent_handle = &parentkeydata->pol;
r.in.keyname.name = name;
- r.in.unknown = 0x00000000;
+ r.in.options = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
- status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_OpenKey_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("OpenKey failed - %s\n", nt_errstr(status)));
@@ -212,24 +214,24 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx,
r.in.handle = &mykeydata->pol;
r.in.enum_index = n;
r.in.name = &name;
- r.in.type = type;
+ r.in.type = (enum winreg_Type *) type;
r.in.value = &value;
r.in.size = &val_size;
r.in.length = &zero;
r.out.name = &name;
- r.out.type = type;
+ r.out.type = (enum winreg_Type *) type;
r.out.value = &value;
r.out.size = &val_size;
r.out.length = &zero;
- status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_EnumValue_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("EnumValue failed - %s\n", nt_errstr(status)));
return ntstatus_to_werror(status);
}
- *value_name = talloc_reference(mem_ctx, r.out.name->name);
+ *value_name = talloc_steal(mem_ctx, r.out.name->name);
*type = *(r.out.type);
*data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length);
@@ -261,16 +263,16 @@ static WERROR rpc_get_value_by_name(TALLOC_CTX *mem_ctx,
ZERO_STRUCT(r);
r.in.handle = &mykeydata->pol;
r.in.value_name = &name;
- r.in.type = type;
+ r.in.type = (enum winreg_Type *) type;
r.in.data = &value;
r.in.data_size = &val_size;
r.in.data_length = &zero;
- r.out.type = type;
+ r.out.type = (enum winreg_Type *) type;
r.out.data = &value;
r.out.data_size = &val_size;
r.out.data_length = &zero;
- status = dcerpc_winreg_QueryValue(mykeydata->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_QueryValue_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("QueryValue failed - %s\n", nt_errstr(status)));
@@ -311,7 +313,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx,
r.out.keyclass = &classbuf;
r.out.last_changed_time = &change_time;
- status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_EnumKey_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("EnumKey failed - %s\n", nt_errstr(status)));
@@ -319,9 +321,9 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx,
}
if (name != NULL)
- *name = talloc_reference(mem_ctx, r.out.name->name);
+ *name = talloc_steal(mem_ctx, r.out.name->name);
if (keyclass != NULL)
- *keyclass = talloc_reference(mem_ctx, r.out.keyclass->name);
+ *keyclass = talloc_steal(mem_ctx, r.out.keyclass->name);
if (last_changed_time != NULL)
*last_changed_time = *(r.out.last_changed_time);
@@ -329,7 +331,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx,
}
static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
- struct registry_key *parent, const char *name,
+ struct registry_key *parent, const char *path,
const char *key_class,
struct security_descriptor *sec,
struct registry_key **key)
@@ -342,7 +344,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
ZERO_STRUCT(r);
r.in.handle = &parentkd->pol;
- r.in.name.name = name;
+ r.in.name.name = path;
r.in.keyclass.name = NULL;
r.in.options = 0;
r.in.access_mask = 0x02000000;
@@ -351,7 +353,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
r.out.new_handle = &rpck->pol;
r.out.action_taken = NULL;
- status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_CreateKey_r(parentkd->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(rpck);
@@ -359,7 +361,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
return ntstatus_to_werror(status);
}
- rpck->pipe = talloc_reference(rpck, parentkd->pipe);
+ rpck->binding_handle = parentkd->binding_handle;
*key = (struct registry_key *)rpck;
return r.out.result;
@@ -387,32 +389,30 @@ static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k)
r.out.secdescsize = &mykeydata->secdescsize;
r.out.last_changed_time = &mykeydata->last_changed_time;
- status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r);
+ status = dcerpc_winreg_QueryInfoKey_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status)));
return ntstatus_to_werror(status);
}
- mykeydata->classname = talloc_reference(mem_ctx, r.out.classname->name);
+ mykeydata->classname = talloc_steal(mem_ctx, r.out.classname->name);
return r.out.result;
}
-static WERROR rpc_del_key(struct registry_key *parent, const char *name)
+static WERROR rpc_del_key(TALLOC_CTX *mem_ctx, struct registry_key *parent,
+ const char *name)
{
NTSTATUS status;
struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
struct winreg_DeleteKey r;
- TALLOC_CTX *mem_ctx = talloc_init("del_key");
ZERO_STRUCT(r);
r.in.handle = &mykeydata->pol;
r.in.key.name = name;
- status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r);
-
- talloc_free(mem_ctx);
+ status = dcerpc_winreg_DeleteKey_r(mykeydata->binding_handle, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("DeleteKey failed - %s\n", nt_errstr(status)));
@@ -473,7 +473,6 @@ static struct registry_operations reg_backend_rpc = {
.create_key = rpc_add_key,
.delete_key = rpc_del_key,
.get_key_info = rpc_get_info,
- .get_predefined_key = rpc_get_predefined_key,
};
_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx,
@@ -489,6 +488,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx,
dcerpc_init(lp_ctx);
rctx = talloc(NULL, struct rpc_registry_context);
+ W_ERROR_HAVE_NO_MEMORY(rctx);
/* Default to local smbd if no connection is specified */
if (!location) {
@@ -497,10 +497,8 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx,
status = dcerpc_pipe_connect(rctx /* TALLOC_CTX */,
&p, location,
- &ndr_table_winreg,
+ &ndr_table_winreg,
credentials, ev, lp_ctx);
- rctx->pipe = p;
-
if(NT_STATUS_IS_ERR(status)) {
DEBUG(1, ("Unable to open '%s': %s\n", location,
nt_errstr(status)));
@@ -509,6 +507,9 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx,
return ntstatus_to_werror(status);
}
+ rctx->pipe = p;
+ rctx->binding_handle = p->binding_handle;
+
*ctx = (struct registry_context *)rctx;
(*ctx)->ops = &reg_backend_rpc;
diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c
index fc59bdfdfa..f798496dbe 100644
--- a/source4/lib/registry/samba.c
+++ b/source4/lib/registry/samba.c
@@ -38,8 +38,9 @@ static WERROR mount_samba_hive(struct registry_context *ctx,
const char *location;
location = talloc_asprintf(ctx, "%s/%s.ldb",
- lp_private_dir(lp_ctx),
+ lpcfg_private_dir(lp_ctx),
name);
+ W_ERROR_HAVE_NO_MEMORY(location);
error = reg_open_hive(ctx, location, auth_info, creds, event_ctx, lp_ctx, &hive);
@@ -47,6 +48,8 @@ static WERROR mount_samba_hive(struct registry_context *ctx,
error = reg_open_ldb_file(ctx, location, auth_info,
creds, event_ctx, lp_ctx, &hive);
+ talloc_free(discard_const_p(char, location));
+
if (!W_ERROR_IS_OK(error))
return error;
diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py
deleted file mode 100644
index 8c3233ef1e..0000000000
--- a/source4/lib/registry/tests/bindings.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/python
-
-# Unix SMB/CIFS implementation.
-# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-
-import os
-import unittest
-from samba import registry
-import samba.tests
-
-class HelperTests(unittest.TestCase):
- def test_predef_to_name(self):
- self.assertEquals("HKEY_LOCAL_MACHINE",
- registry.get_predef_name(0x80000002))
-
- def test_str_regtype(self):
- self.assertEquals("REG_DWORD", registry.str_regtype(4))
-
-
-
-class HiveTests(samba.tests.TestCaseInTempDir):
- def setUp(self):
- super(HiveTests, self).setUp()
- self.hive_path = os.path.join(self.tempdir, "ldb_new.ldb")
- self.hive = registry.open_ldb(self.hive_path)
-
- def tearDown(self):
- del self.hive
- os.unlink(self.hive_path)
-
- def test_ldb_new(self):
- self.assertTrue(self.hive is not None)
-
- #def test_flush(self):
- # self.hive.flush()
-
- #def test_del_value(self):
- # self.hive.del_value("FOO")
-
-
-class RegistryTests(unittest.TestCase):
- def test_new(self):
- self.registry = registry.Registry()
diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c
index 3dba7293bc..5568171f75 100644
--- a/source4/lib/registry/tests/diff.c
+++ b/source4/lib/registry/tests/diff.c
@@ -52,14 +52,11 @@ static bool test_generate_diff(struct torture_context *tctx, void *tcase_data)
static bool test_diff_load(struct torture_context *tctx, void *tcase_data)
{
struct diff_tcase_data *td = tcase_data;
- struct smb_iconv_convenience *ic;
struct reg_diff_callbacks *callbacks;
void *data;
WERROR error;
- ic = lp_iconv_convenience(tctx->lp_ctx);
-
- error = reg_diff_load(td->filename, iconv_convenience, callbacks, data);
+ error = reg_diff_load(td->filename, callbacks, data);
torture_assert_werr_ok(tctx, error, "reg_diff_load");
return true;
@@ -71,7 +68,7 @@ static bool test_diff_apply(struct torture_context *tctx, void *tcase_data)
struct registry_key *key;
WERROR error;
- error = reg_diff_apply(td->r1_ctx, lp_iconv_convenience(tctx->lp_ctx), td->filename);
+ error = reg_diff_apply(td->r1_ctx, td->filename);
torture_assert_werr_ok(tctx, error, "reg_diff_apply");
error = td->r1_ctx->ops->get_predefined_key(td->r1_ctx, HKEY_LOCAL_MACHINE, &key);
@@ -227,10 +224,11 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data)
error = r2_ctx->ops->create_key(r2_ctx, newkey, "Explorer", NULL, NULL, &newkey);
torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\Policies\\Explorer failed");
-
- blob.data = (void *)talloc(r2_ctx, uint32_t);
- SIVAL(blob.data, 0, 0x03ffffff);
- blob.length = sizeof(uint32_t);
+ blob.data = talloc_array(r2_ctx, uint8_t, 4);
+ /* set "0x03FFFFFF" in little endian format */
+ blob.data[0] = 0xFF; blob.data[1] = 0xFF;
+ blob.data[2] = 0xFF; blob.data[3] = 0x03;
+ blob.length = 4;
r1_ctx->ops->set_value(newkey, "NoDrives", REG_DWORD, blob);
@@ -246,16 +244,14 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data)
static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data)
{
struct diff_tcase_data *td;
- struct smb_iconv_convenience *ic;
WERROR error;
diff_setup_tcase(tctx, data);
td = *data;
- ic = lp_iconv_convenience(tctx->lp_ctx);
-
td->filename = talloc_asprintf(tctx, "%s/test.pol", td->tempdir);
- error = reg_preg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data);
+ error = reg_preg_diff_save(tctx, td->filename, &td->callbacks,
+ &td->callback_data);
torture_assert_werr_ok(tctx, error, "reg_preg_diff_save");
return true;
@@ -264,16 +260,14 @@ static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data)
static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data)
{
struct diff_tcase_data *td;
- struct smb_iconv_convenience *ic;
WERROR error;
diff_setup_tcase(tctx, data);
td = *data;
- ic = lp_iconv_convenience(tctx->lp_ctx);
-
td->filename = talloc_asprintf(tctx, "%s/test.reg", td->tempdir);
- error = reg_dotreg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data);
+ error = reg_dotreg_diff_save(tctx, td->filename, &td->callbacks,
+ &td->callback_data);
torture_assert_werr_ok(tctx, error, "reg_dotreg_diff_save");
return true;
@@ -282,7 +276,7 @@ static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data)
struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx)
{
struct torture_tcase *tcase;
- struct torture_suite *suite = torture_suite_create(mem_ctx, "DIFF");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "diff");
tcase = torture_suite_add_tcase(suite, "PReg");
torture_tcase_set_fixture(tcase, diff_setup_preg_tcase, NULL);
diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c
index 3de7602e53..2e0863c17a 100644
--- a/source4/lib/registry/tests/generic.c
+++ b/source4/lib/registry/tests/generic.c
@@ -31,10 +31,30 @@ struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx);
static bool test_str_regtype(struct torture_context *ctx)
{
+ torture_assert_str_equal(ctx, str_regtype(0),
+ "REG_NONE", "REG_NONE failed");
torture_assert_str_equal(ctx, str_regtype(1),
"REG_SZ", "REG_SZ failed");
+ torture_assert_str_equal(ctx, str_regtype(2),
+ "REG_EXPAND_SZ", "REG_EXPAND_SZ failed");
+ torture_assert_str_equal(ctx, str_regtype(3),
+ "REG_BINARY", "REG_BINARY failed");
torture_assert_str_equal(ctx, str_regtype(4),
"REG_DWORD", "REG_DWORD failed");
+ torture_assert_str_equal(ctx, str_regtype(5),
+ "REG_DWORD_BIG_ENDIAN", "REG_DWORD_BIG_ENDIAN failed");
+ torture_assert_str_equal(ctx, str_regtype(6),
+ "REG_LINK", "REG_LINK failed");
+ torture_assert_str_equal(ctx, str_regtype(7),
+ "REG_MULTI_SZ", "REG_MULTI_SZ failed");
+ torture_assert_str_equal(ctx, str_regtype(8),
+ "REG_RESOURCE_LIST", "REG_RESOURCE_LIST failed");
+ torture_assert_str_equal(ctx, str_regtype(9),
+ "REG_FULL_RESOURCE_DESCRIPTOR", "REG_FULL_RESOURCE_DESCRIPTOR failed");
+ torture_assert_str_equal(ctx, str_regtype(10),
+ "REG_RESOURCE_REQUIREMENTS_LIST", "REG_RESOURCE_REQUIREMENTS_LIST failed");
+ torture_assert_str_equal(ctx, str_regtype(11),
+ "REG_QWORD", "REG_QWORD failed");
return true;
}
@@ -42,25 +62,45 @@ static bool test_str_regtype(struct torture_context *ctx)
static bool test_reg_val_data_string_dword(struct torture_context *ctx)
{
- uint32_t d = 0x20;
- DATA_BLOB db = { (uint8_t *)&d, sizeof(d) };
- torture_assert_str_equal(ctx, "0x20",
- reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_DWORD, db),
+ uint8_t d[] = { 0x20, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
+ torture_assert_str_equal(ctx, "0x00000020",
+ reg_val_data_string(ctx, REG_DWORD, db),
"dword failed");
return true;
}
+static bool test_reg_val_data_string_dword_big_endian(struct torture_context *ctx)
+{
+ uint8_t d[] = { 0x20, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
+ torture_assert_str_equal(ctx, "0x00000020",
+ reg_val_data_string(ctx, REG_DWORD_BIG_ENDIAN, db),
+ "dword failed");
+ return true;
+}
+
+static bool test_reg_val_data_string_qword(struct torture_context *ctx)
+{
+ uint8_t d[] = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 8 };
+ torture_assert_str_equal(ctx, "0x0000000000000020",
+ reg_val_data_string(ctx, REG_QWORD, db),
+ "qword failed");
+ return true;
+}
+
static bool test_reg_val_data_string_sz(struct torture_context *ctx)
{
DATA_BLOB db;
- convert_string_talloc_convenience(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16,
+ convert_string_talloc(ctx, CH_UTF8, CH_UTF16,
"bla", 3, (void **)&db.data, &db.length, false);
torture_assert_str_equal(ctx, "bla",
- reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db),
+ reg_val_data_string(ctx, REG_SZ, db),
"sz failed");
db.length = 4;
torture_assert_str_equal(ctx, "bl",
- reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db),
+ reg_val_data_string(ctx, REG_SZ, db),
"sz failed");
return true;
}
@@ -70,7 +110,7 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx)
uint8_t x[] = { 0x1, 0x2, 0x3, 0x4 };
DATA_BLOB db = { x, 4 };
torture_assert_str_equal(ctx, "01020304",
- reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_BINARY, db),
+ reg_val_data_string(ctx, REG_BINARY, db),
"binary failed");
return true;
}
@@ -80,7 +120,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx)
{
DATA_BLOB db = { NULL, 0 };
torture_assert_str_equal(ctx, "",
- reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_BINARY, db),
+ reg_val_data_string(ctx, REG_BINARY, db),
"empty failed");
return true;
}
@@ -88,12 +128,12 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx)
static bool test_reg_val_description(struct torture_context *ctx)
{
DATA_BLOB data;
- convert_string_talloc_convenience(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16,
+ convert_string_talloc(ctx, CH_UTF8, CH_UTF16,
"stationary traveller",
strlen("stationary traveller"),
(void **)&data.data, &data.length, false);
torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller",
- reg_val_description(ctx, lp_iconv_convenience(ctx->lp_ctx), "camel", REG_SZ, data),
+ reg_val_description(ctx, "camel", REG_SZ, data),
"reg_val_description failed");
return true;
}
@@ -102,23 +142,27 @@ static bool test_reg_val_description(struct torture_context *ctx)
static bool test_reg_val_description_nullname(struct torture_context *ctx)
{
DATA_BLOB data;
- convert_string_talloc_convenience(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16,
+ convert_string_talloc(ctx, CH_UTF8, CH_UTF16,
"west berlin",
strlen("west berlin"),
(void **)&data.data, &data.length, false);
torture_assert_str_equal(ctx, "<No Name> = REG_SZ : west berlin",
- reg_val_description(ctx, lp_iconv_convenience(ctx->lp_ctx), NULL, REG_SZ, data),
+ reg_val_description(ctx, NULL, REG_SZ, data),
"description with null name failed");
return true;
}
struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "registry");
torture_suite_add_simple_test(suite, "str_regtype",
test_str_regtype);
torture_suite_add_simple_test(suite, "reg_val_data_string dword",
test_reg_val_data_string_dword);
+ torture_suite_add_simple_test(suite, "reg_val_data_string dword_big_endian",
+ test_reg_val_data_string_dword_big_endian);
+ torture_suite_add_simple_test(suite, "reg_val_data_string qword",
+ test_reg_val_data_string_qword);
torture_suite_add_simple_test(suite, "reg_val_data_string sz",
test_reg_val_data_string_sz);
torture_suite_add_simple_test(suite, "reg_val_data_string binary",
diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c
index edc97c2468..71d3f0a3f8 100644
--- a/source4/lib/registry/tests/hive.c
+++ b/source4/lib/registry/tests/hive.c
@@ -32,7 +32,7 @@ static bool test_del_nonexistant_key(struct torture_context *tctx,
const void *test_data)
{
const struct hive_key *root = (const struct hive_key *)test_data;
- WERROR error = hive_key_del(root, "bla");
+ WERROR error = hive_key_del(tctx, root, "bla");
torture_assert_werr_equal(tctx, error, WERR_BADFILE,
"invalid return code");
@@ -69,15 +69,14 @@ static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data)
struct hive_key *root = (struct hive_key *)test_data;
WERROR error;
struct hive_key *subkey;
- char data[4];
- SIVAL(data, 0, 42);
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
error = hive_key_add_name(tctx, root, "Nested Keyll", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_set_value(root, "Answer", REG_DWORD,
- data_blob_talloc(tctx, data, sizeof(data)));
+ error = hive_key_set_value(root, "Answer", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
/* This is a new backend. There should be no subkeys and no
@@ -107,7 +106,7 @@ static bool test_add_subkey(struct torture_context *tctx,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_del(root, "Nested Key");
+ error = hive_key_del(mem_ctx, root, "Nested Key");
torture_assert_werr_ok(tctx, error, "reg_key_del");
return true;
@@ -121,8 +120,8 @@ static bool test_del_recursive(struct torture_context *tctx,
struct hive_key *subkey2;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
- char data[4];
- SIVAL(data, 0, 42);
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
/* Create a new key under the root */
error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL,
@@ -135,12 +134,11 @@ static bool test_del_recursive(struct torture_context *tctx,
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
/* Create a new value under "Child Key" */
- error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD,
- data_blob_talloc(mem_ctx, data, sizeof(data)));
+ error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
/* Deleting "Parent Key" will also delete "Child Key" and the value. */
- error = hive_key_del(root, "Parent Key");
+ error = hive_key_del(mem_ctx, root, "Parent Key");
torture_assert_werr_ok(tctx, error, "hive_key_del");
return true;
@@ -166,10 +164,10 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data)
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_del(root, "Nested Key");
+ error = hive_key_del(mem_ctx, root, "Nested Key");
torture_assert_werr_ok(tctx, error, "reg_key_del");
- error = hive_key_del(root, "Nested Key");
+ error = hive_key_del(mem_ctx, root, "Nested Key");
torture_assert_werr_equal(tctx, error, WERR_BADFILE, "reg_key_del");
return true;
@@ -182,15 +180,14 @@ static bool test_set_value(struct torture_context *tctx,
struct hive_key *subkey;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
- char data[4];
- SIVAL(data, 0, 42);
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_set_value(subkey, "Answer", REG_DWORD,
- data_blob_talloc(mem_ctx, data, sizeof(data)));
+ error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
return true;
@@ -202,32 +199,28 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data)
struct hive_key *subkey;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
- char data[4];
uint32_t type;
- DATA_BLOB value;
-
- SIVAL(data, 0, 42);
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 }, data;
error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value);
+ error = hive_get_value(mem_ctx, subkey, "Answer", &type, &data);
torture_assert_werr_equal(tctx, error, WERR_BADFILE,
"getting missing value");
- error = hive_key_set_value(subkey, "Answer", REG_DWORD,
- data_blob_talloc(mem_ctx, data, sizeof(data)));
+ error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
- error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value);
+ error = hive_get_value(mem_ctx, subkey, "Answer", &type, &data);
torture_assert_werr_ok(tctx, error, "getting value");
- torture_assert_int_equal(tctx, value.length, 4, "value length");
+ torture_assert_int_equal(tctx, data.length, 4, "value length");
torture_assert_int_equal(tctx, type, REG_DWORD, "value type");
- torture_assert_mem_equal(tctx, &data, value.data, sizeof(uint32_t),
- "value data");
+ torture_assert_mem_equal(tctx, data.data, db.data, 4, "value data");
return true;
}
@@ -238,27 +231,24 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data)
struct hive_key *subkey;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
- char data[4];
uint32_t type;
- DATA_BLOB value;
-
- SIVAL(data, 0, 42);
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 };
error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_set_value(subkey, "Answer", REG_DWORD,
- data_blob_talloc(mem_ctx, data, sizeof(data)));
+ error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
- error = hive_key_del_value(subkey, "Answer");
+ error = hive_key_del_value(mem_ctx, subkey, "Answer");
torture_assert_werr_ok(tctx, error, "deleting value");
- error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value);
+ error = hive_get_value(mem_ctx, subkey, "Answer", &type, &db);
torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value");
- error = hive_key_del_value(subkey, "Answer");
+ error = hive_key_del_value(mem_ctx, subkey, "Answer");
torture_assert_werr_equal(tctx, error, WERR_BADFILE,
"deleting value");
@@ -272,35 +262,31 @@ static bool test_list_values(struct torture_context *tctx,
struct hive_key *subkey;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
- char data[4];
uint32_t type;
- DATA_BLOB value;
+ uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
+ DATA_BLOB db = { d, 4 }, data;
const char *name;
- int data_val = 42;
- SIVAL(data, 0, data_val);
error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
- error = hive_key_set_value(subkey, "Answer", REG_DWORD,
- data_blob_talloc(mem_ctx, data, sizeof(data)));
+ error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
error = hive_get_value_by_index(mem_ctx, subkey, 0, &name,
- &type, &value);
+ &type, &data);
torture_assert_werr_ok(tctx, error, "getting value");
torture_assert_str_equal(tctx, name, "Answer", "value name");
- torture_assert_int_equal(tctx, value.length, 4, "value length");
+ torture_assert_int_equal(tctx, data.length, 4, "value length");
torture_assert_int_equal(tctx, type, REG_DWORD, "value type");
+ torture_assert_mem_equal(tctx, data.data, db.data, 4, "value data");
- torture_assert_int_equal(tctx, data_val, IVAL(value.data, 0), "value data");
-
error = hive_get_value_by_index(mem_ctx, subkey, 1, &name,
- &type, &value);
+ &type, &data);
torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
"getting missing value");
@@ -449,8 +435,7 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data)
rmdir(dirname);
- error = reg_create_regf_file(tctx, lp_iconv_convenience(tctx->lp_ctx),
- dirname, 5, &key);
+ error = reg_create_regf_file(tctx, dirname, 5, &key);
if (!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Unable to create new regf file\n");
return false;
@@ -472,7 +457,7 @@ static bool test_dir_refuses_null_location(struct torture_context *tctx)
struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx)
{
struct torture_tcase *tcase;
- struct torture_suite *suite = torture_suite_create(mem_ctx, "HIVE");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "hive");
torture_suite_add_simple_test(suite, "dir-refuses-null-location",
test_dir_refuses_null_location);
diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c
index 7274bf009d..50aefc8786 100644
--- a/source4/lib/registry/tests/registry.c
+++ b/source4/lib/registry/tests/registry.c
@@ -117,22 +117,17 @@ static bool test_create_subkey(struct torture_context *tctx, void *_data)
static bool test_create_nested_subkey(struct torture_context *tctx, void *_data)
{
struct registry_context *rctx = (struct registry_context *)_data;
- struct registry_key *root, *newkey1, *newkey2;
+ struct registry_key *root, *newkey;
WERROR error;
error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
torture_assert_werr_ok(tctx, error,
"getting predefined key failed");
- error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL,
- &newkey1);
- torture_assert_werr_ok(tctx, error, "Creating key return code");
- torture_assert(tctx, newkey1 != NULL, "Creating new key");
-
error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL,
- &newkey2);
+ &newkey);
torture_assert_werr_ok(tctx, error, "Creating key return code");
- torture_assert(tctx, newkey2 != NULL, "Creating new key");
+ torture_assert(tctx, newkey != NULL, "Creating new key");
return true;
}
@@ -200,10 +195,10 @@ static bool test_del_key(struct torture_context *tctx, void *_data)
torture_assert_werr_ok(tctx, error, "Creating key return code");
torture_assert(tctx, newkey != NULL, "Creating new key");
- error = reg_key_del(root, "Polen");
+ error = reg_key_del(tctx, root, "Polen");
torture_assert_werr_ok(tctx, error, "Delete key");
- error = reg_key_del(root, "Polen");
+ error = reg_key_del(tctx, root, "Polen");
torture_assert_werr_equal(tctx, error, WERR_BADFILE,
"Delete missing key");
@@ -464,7 +459,7 @@ static bool test_del_value(struct torture_context *tctx, void *_data)
data_blob_talloc(tctx, value, sizeof(value)));
torture_assert_werr_ok (tctx, error, "setting value");
- error = reg_del_value(subkey, __FUNCTION__);
+ error = reg_del_value(tctx, subkey, __FUNCTION__);
torture_assert_werr_ok (tctx, error, "unsetting value");
error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__,
@@ -584,7 +579,7 @@ static void tcase_add_tests(struct torture_tcase *tcase)
struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)
{
struct torture_tcase *tcase;
- struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "registry");
tcase = torture_suite_add_tcase(suite, "local");
torture_tcase_set_fixture(tcase, setup_local_registry, NULL);
diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c
index 945b472903..bd58f7748f 100644
--- a/source4/lib/registry/tools/regdiff.c
+++ b/source4/lib/registry/tools/regdiff.c
@@ -130,8 +130,7 @@ int main(int argc, const char **argv)
poptFreeContext(pc);
- error = reg_dotreg_diff_save(ctx, outputfile, lp_iconv_convenience(cmdline_lp_ctx), &callbacks,
- &callback_data);
+ error = reg_dotreg_diff_save(ctx, outputfile, &callbacks, &callback_data);
if (!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Problem saving registry diff to '%s': %s\n",
outputfile, win_errstr(error));
diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c
index 3f550e517e..a8c1843116 100644
--- a/source4/lib/registry/tools/regpatch.c
+++ b/source4/lib/registry/tools/regpatch.c
@@ -68,7 +68,7 @@ int main(int argc, char **argv)
poptFreeContext(pc);
- reg_diff_apply(h, lp_iconv_convenience(cmdline_lp_ctx), patch);
+ reg_diff_apply(h, patch);
return 0;
}
diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c
index 314f063891..6bd7fd3b8b 100644
--- a/source4/lib/registry/tools/regshell.c
+++ b/source4/lib/registry/tools/regshell.c
@@ -24,7 +24,7 @@
#include "lib/cmdline/popt_common.h"
#include "lib/events/events.h"
#include "system/time.h"
-#include "lib/smbreadline/smbreadline.h"
+#include "../libcli/smbreadline/smbreadline.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "lib/registry/tools/common.h"
#include "param/param.h"
@@ -125,7 +125,7 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv)
if (classname != NULL)
printf("Key Class: %s\n", classname);
last_mod = nt_time_to_unix(last_change);
- printf("Time Last Modified: %s\n", ctime(&last_mod));
+ printf("Time Last Modified: %s", ctime(&last_mod));
printf("Number of subkeys: %d\n", num_subkeys);
printf("Number of values: %d\n", num_values);
@@ -140,8 +140,8 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv)
error = reg_get_sec_desc(ctx, ctx->current, &sec_desc);
if (!W_ERROR_IS_OK(error)) {
- printf("Error getting security descriptor\n");
- return error;
+ printf("Error getting security descriptor: %s\n", win_errstr(error));
+ return WERR_OK;
}
ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor,
"Security", sec_desc);
@@ -195,9 +195,7 @@ static WERROR cmd_set(struct regshell_context *ctx, int argc, char **argv)
return WERR_INVALID_PARAM;
}
- if (!reg_string_to_val(ctx, lp_iconv_convenience(cmdline_lp_ctx),
- argv[2], argv[3], &val.data_type,
- &val.data)) {
+ if (!reg_string_to_val(ctx, argv[2], argv[3], &val.data_type, &val.data)) {
fprintf(stderr, "Unable to interpret data\n");
return WERR_INVALID_PARAM;
}
@@ -259,14 +257,14 @@ static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv)
}
printf("%s\n%s\n", str_regtype(value_type),
- reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), value_type, value_data));
+ reg_val_data_string(ctx, value_type, value_data));
return WERR_OK;
}
static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv)
{
- int i;
+ unsigned int i;
WERROR error;
uint32_t valuetype;
DATA_BLOB valuedata;
@@ -282,7 +280,7 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv)
}
if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
- fprintf(stderr, "Error occured while browsing thru keys: %s\n",
+ fprintf(stderr, "Error occurred while browsing through keys: %s\n",
win_errstr(error));
return error;
}
@@ -290,7 +288,7 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv)
for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx,
ctx->current, i, &name, &valuetype, &valuedata)); i++)
printf("V \"%s\" %s %s\n", name, str_regtype(valuetype),
- reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), valuetype, valuedata));
+ reg_val_data_string(ctx, valuetype, valuedata));
return WERR_OK;
}
@@ -325,7 +323,7 @@ static WERROR cmd_rmkey(struct regshell_context *ctx,
return WERR_INVALID_PARAM;
}
- error = reg_key_del(ctx->current, argv[1]);
+ error = reg_key_del(ctx, ctx->current, argv[1]);
if(!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Error deleting '%s'\n", argv[1]);
return error;
@@ -345,7 +343,7 @@ static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv)
return WERR_INVALID_PARAM;
}
- error = reg_del_value(ctx->current, argv[1]);
+ error = reg_del_value(ctx, ctx->current, argv[1]);
if(!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Error deleting value '%s'\n", argv[1]);
return error;
@@ -388,7 +386,7 @@ static struct {
static WERROR cmd_help(struct regshell_context *ctx,
int argc, char **argv)
{
- int i;
+ unsigned int i;
printf("Available commands:\n");
for(i = 0; regshell_cmds[i].name; i++) {
printf("%s - %s\n", regshell_cmds[i].name,
@@ -429,7 +427,8 @@ static char **reg_complete_command(const char *text, int start, int end)
{
/* Complete command */
char **matches;
- int i, len, samelen=0, count=1;
+ size_t len, samelen=0;
+ unsigned int i, count=1;
matches = malloc_array_p(char *, MAX_COMPLETIONS);
if (!matches) return NULL;
@@ -477,9 +476,8 @@ static char **reg_complete_key(const char *text, int start, int end)
{
struct registry_key *base;
const char *subkeyname;
- int i, j = 1;
- int samelen = 0;
- int len;
+ unsigned int i, j = 1;
+ size_t len, samelen = 0;
char **matches;
const char *base_n = "";
TALLOC_CTX *mem_ctx;
@@ -593,7 +591,7 @@ int main(int argc, char **argv)
return 1;
if (ctx->current == NULL) {
- int i;
+ unsigned int i;
for (i = 0; (reg_predefined_keys[i].handle != 0) &&
(ctx->current == NULL); i++) {
@@ -616,7 +614,7 @@ int main(int argc, char **argv)
if (ctx->current == NULL) {
fprintf(stderr, "Unable to access any of the predefined keys\n");
- return -1;
+ return 1;
}
poptFreeContext(pc);
@@ -624,7 +622,11 @@ int main(int argc, char **argv)
while (true) {
char *line, *prompt;
- asprintf(&prompt, "%s\\%s> ", ctx->predef?ctx->predef:"", ctx->path);
+ if (asprintf(&prompt, "%s\\%s> ", ctx->predef?ctx->predef:"",
+ ctx->path) < 0) {
+ ret = false;
+ break;
+ }
current_key = ctx->current; /* No way to pass a void * pointer
via readline :-( */
diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c
index 948ed49312..6857940672 100644
--- a/source4/lib/registry/tools/regtree.c
+++ b/source4/lib/registry/tools/regtree.c
@@ -33,7 +33,7 @@
* @param fullpath Whether the full pat hshould be printed or just the last bit
* @param novals Whether values should not be printed
*/
-static void print_tree(int level, struct registry_key *p,
+static void print_tree(unsigned int level, struct registry_key *p,
const char *name,
bool fullpath, bool novals)
{
@@ -43,7 +43,7 @@ static void print_tree(int level, struct registry_key *p,
DATA_BLOB valuedata;
struct security_descriptor *sec_desc;
WERROR error;
- int i;
+ unsigned int i;
TALLOC_CTX *mem_ctx;
for(i = 0; i < level; i++) putchar(' '); puts(name);
@@ -69,7 +69,7 @@ static void print_tree(int level, struct registry_key *p,
talloc_free(mem_ctx);
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
- DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n",
+ DEBUG(0, ("Error occurred while fetching subkeys for '%s': %s\n",
name, win_errstr(error)));
}
@@ -78,16 +78,15 @@ static void print_tree(int level, struct registry_key *p,
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(
mem_ctx, p, i, &valuename, &valuetype, &valuedata));
i++) {
- int j;
+ unsigned int j;
for(j = 0; j < level+1; j++) putchar(' ');
printf("%s\n", reg_val_description(mem_ctx,
- lp_iconv_convenience(cmdline_lp_ctx), valuename,
- valuetype, valuedata));
+ valuename, valuetype, valuedata));
}
talloc_free(mem_ctx);
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
- DEBUG(0, ("Error occured while fetching values for '%s': %s\n",
+ DEBUG(0, ("Error occurred while fetching values for '%s': %s\n",
name, win_errstr(error)));
}
}
@@ -101,7 +100,8 @@ static void print_tree(int level, struct registry_key *p,
int main(int argc, char **argv)
{
- int opt, i;
+ int opt;
+ unsigned int i;
const char *file = NULL;
const char *remote = NULL;
poptContext pc;
diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c
index a1897eff2e..bbcc869e03 100644
--- a/source4/lib/registry/util.c
+++ b/source4/lib/registry/util.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Transparent registry backend handling
Copyright (C) Jelmer Vernooij 2003-2007.
+ Copyright (C) Wilco Baan Hofman 2010.
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
@@ -20,39 +21,9 @@
#include "includes.h"
#include "lib/registry/registry.h"
#include "librpc/gen_ndr/winreg.h"
+#include "lib/util/data_blob.h"
-/**
- * @file
- * @brief Registry utility functions
- */
-
-static const struct {
- uint32_t id;
- const char *name;
-} reg_value_types[] = {
- { REG_SZ, "REG_SZ" },
- { REG_DWORD, "REG_DWORD" },
- { REG_BINARY, "REG_BINARY" },
- { REG_EXPAND_SZ, "REG_EXPAND_SZ" },
- { REG_NONE, "REG_NONE" },
- { 0, NULL }
-};
-
-/** Return string description of registry value type */
-_PUBLIC_ const char *str_regtype(int type)
-{
- int i;
- for (i = 0; reg_value_types[i].name; i++) {
- if (reg_value_types[i].id == type)
- return reg_value_types[i].name;
- }
-
- return "Unknown";
-}
-
-_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx,
- struct smb_iconv_convenience *iconv_convenience,
- uint32_t type,
+_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type,
const DATA_BLOB data)
{
char *ret = NULL;
@@ -63,22 +34,34 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx,
switch (type) {
case REG_EXPAND_SZ:
case REG_SZ:
- convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UTF16, CH_UNIX,
+ convert_string_talloc(mem_ctx,
+ CH_UTF16, CH_UNIX,
data.data, data.length,
(void **)&ret, NULL, false);
- return ret;
- case REG_BINARY:
- ret = data_blob_hex_string(mem_ctx, &data);
- return ret;
+ break;
case REG_DWORD:
- if (*(int *)data.data == 0)
- return talloc_strdup(mem_ctx, "0");
- return talloc_asprintf(mem_ctx, "0x%x",
- *(int *)data.data);
+ case REG_DWORD_BIG_ENDIAN:
+ SMB_ASSERT(data.length == sizeof(uint32_t));
+ ret = talloc_asprintf(mem_ctx, "0x%8.8x",
+ IVAL(data.data, 0));
+ break;
+ case REG_QWORD:
+ SMB_ASSERT(data.length == sizeof(uint64_t));
+ ret = talloc_asprintf(mem_ctx, "0x%16.16llx",
+ (long long)BVAL(data.data, 0));
+ break;
+ case REG_BINARY:
+ ret = data_blob_hex_string_upper(mem_ctx, &data);
+ break;
+ case REG_NONE:
+ /* "NULL" is the right return value */
+ break;
case REG_MULTI_SZ:
- /* FIXME */
+ /* FIXME: We don't support this yet */
break;
default:
+ /* FIXME */
+ /* Other datatypes aren't supported -> return "NULL" */
break;
}
@@ -86,64 +69,127 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx,
}
/** Generate a string that describes a registry value */
-_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx,
- struct smb_iconv_convenience *iconv_convenience,
+_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx,
const char *name,
uint32_t data_type,
const DATA_BLOB data)
{
return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"<No Name>",
str_regtype(data_type),
- reg_val_data_string(mem_ctx, iconv_convenience, data_type, data));
+ reg_val_data_string(mem_ctx, data_type, data));
}
-_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx,
- struct smb_iconv_convenience *iconv_convenience,
- const char *type_str,
- const char *data_str, uint32_t *type,
- DATA_BLOB *data)
+/*
+ * This implements reading hex bytes that include comma's.
+ * It was previously handled by strhex_to_data_blob, but that did not cover
+ * the format used by windows.
+ */
+static DATA_BLOB reg_strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *str)
{
- int i;
- *type = -1;
+ DATA_BLOB ret;
+ const char *HEXCHARS = "0123456789ABCDEF";
+ size_t i, j;
+ char *hi, *lo;
+
+ ret = data_blob_talloc_zero(mem_ctx, (strlen(str)+(strlen(str) % 3))/3);
+ j = 0;
+ for (i = 0; i < strlen(str); i++) {
+ hi = strchr(HEXCHARS, toupper(str[i]));
+ if (hi == NULL)
+ continue;
+
+ i++;
+ lo = strchr(HEXCHARS, toupper(str[i]));
+ if (lo == NULL)
+ break;
- /* Find the correct type */
- for (i = 0; reg_value_types[i].name; i++) {
- if (!strcmp(reg_value_types[i].name, type_str)) {
- *type = reg_value_types[i].id;
+ ret.data[j] = PTR_DIFF(hi, HEXCHARS) << 4;
+ ret.data[j] += PTR_DIFF(lo, HEXCHARS);
+ j++;
+
+ if (j > ret.length) {
+ DEBUG(0, ("Trouble converting hex string to bin\n"));
break;
}
}
+ return ret;
+}
+
+
+_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str,
+ const char *data_str, uint32_t *type, DATA_BLOB *data)
+{
+ char *tmp_type_str, *p, *q;
+ int result;
+
+ *type = regtype_by_string(type_str);
+
+ if (*type == -1) {
+ /* Normal windows format is hex, hex(type int as string),
+ dword or just a string. */
+ if (strncmp(type_str, "hex(", 4) == 0) {
+ /* there is a hex string with the value type between
+ the braces */
+ tmp_type_str = talloc_strdup(mem_ctx, type_str);
+ q = p = tmp_type_str + strlen("hex(");
+
+ /* Go to the closing brace or end of the string */
+ while (*q != ')' && *q != '\0') q++;
+ *q = '\0';
+
+ /* Convert hex string to int, store it in type */
+ result = sscanf(p, "%x", type);
+ if (!result) {
+ DEBUG(0, ("Could not convert hex to int\n"));
+ return false;
+ }
+ talloc_free(tmp_type_str);
+ } else if (strcmp(type_str, "hex") == 0) {
+ *type = REG_BINARY;
+ } else if (strcmp(type_str, "dword") == 0) {
+ *type = REG_DWORD;
+ }
+ }
if (*type == -1)
return false;
/* Convert data appropriately */
- switch (*type)
- {
+ switch (*type) {
case REG_SZ:
+ return convert_string_talloc(mem_ctx,
+ CH_UNIX, CH_UTF16,
+ data_str, strlen(data_str)+1,
+ (void **)&data->data,
+ &data->length, false);
+ break;
+ case REG_MULTI_SZ:
case REG_EXPAND_SZ:
- convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UNIX, CH_UTF16,
- data_str, strlen(data_str),
- (void **)&data->data, &data->length, false);
+ case REG_BINARY:
+ *data = reg_strhex_to_data_blob(mem_ctx, data_str);
break;
-
- case REG_DWORD: {
- uint32_t tmp = strtol(data_str, NULL, 0);
- *data = data_blob_talloc(mem_ctx, &tmp, 4);
+ case REG_DWORD:
+ case REG_DWORD_BIG_ENDIAN: {
+ uint32_t tmp = strtol(data_str, NULL, 16);
+ *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint32_t));
+ if (data->data == NULL) return false;
+ SIVAL(data->data, 0, tmp);
+ }
+ break;
+ case REG_QWORD: {
+ uint64_t tmp = strtoll(data_str, NULL, 16);
+ *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint64_t));
+ if (data->data == NULL) return false;
+ SBVAL(data->data, 0, tmp);
}
break;
-
case REG_NONE:
ZERO_STRUCTP(data);
break;
-
- case REG_BINARY:
- *data = strhex_to_data_blob(mem_ctx, data_str);
- break;
-
default:
/* FIXME */
+ /* Other datatypes aren't supported -> return no success */
return false;
}
return true;
@@ -155,7 +201,7 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle,
{
struct registry_key *predef;
WERROR error;
- int predeflength;
+ size_t predeflength;
char *predefname;
if (strchr(name, '\\') != NULL)
@@ -164,6 +210,7 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle,
predeflength = strlen(name);
predefname = talloc_strndup(mem_ctx, name, predeflength);
+ W_ERROR_HAVE_NO_MEMORY(predefname);
error = reg_get_predefined_key_by_name(handle, predefname, &predef);
talloc_free(predefname);
@@ -192,13 +239,15 @@ static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx,
}
parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path);
-
+ W_ERROR_HAVE_NO_MEMORY(parent_name);
error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent);
+ talloc_free(parent_name);
if (!W_ERROR_IS_OK(error)) {
return error;
}
*name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1);
+ W_ERROR_HAVE_NO_MEMORY(*name);
return WERR_OK;
}
@@ -216,7 +265,7 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path)
error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
if (W_ERROR_IS_OK(error)) {
- error = reg_key_del(parent, n);
+ error = reg_key_del(mem_ctx, parent, n);
}
talloc_free(mem_ctx);
@@ -233,6 +282,8 @@ WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx,
const char *n;
WERROR error;
+ *result = NULL;
+
if (!strchr(path, '\\')) {
return WERR_ALREADY_EXISTS;
}
diff --git a/source4/lib/registry/wscript_build b/source4/lib/registry/wscript_build
new file mode 100644
index 0000000000..2f0372a933
--- /dev/null
+++ b/source4/lib/registry/wscript_build
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+bld.SAMBA_PIDL('PIDL_REG',
+ source='regf.idl',
+ options='--header --tdr-parser')
+
+bld.SAMBA_SUBSYSTEM('TDR_REGF',
+ source='tdr_regf.c',
+ public_deps='TDR'
+ )
+
+
+bld.SAMBA_LIBRARY('registry',
+ source='interface.c util.c samba.c patchfile_dotreg.c patchfile_preg.c patchfile.c regf.c hive.c local.c ldb.c dir.c rpc.c',
+ pc_files='registry.pc',
+ public_deps='samba-util TDR_REGF ldb RPC_NDR_WINREG ldbsamba util_reg',
+ public_headers='registry.h',
+ vnum='0.0.1'
+ )
+
+
+bld.SAMBA_SUBSYSTEM('registry_common',
+ source='tools/common.c',
+ autoproto='tools/common.h',
+ public_deps='registry'
+ )
+
+
+bld.SAMBA_BINARY('regdiff',
+ source='tools/regdiff.c',
+ manpages='man/regdiff.1',
+ deps='samba-hostconfig registry popt POPT_SAMBA POPT_CREDENTIALS'
+ )
+
+
+bld.SAMBA_BINARY('regpatch',
+ source='tools/regpatch.c',
+ manpages='man/regpatch.1',
+ deps='samba-hostconfig registry popt POPT_SAMBA POPT_CREDENTIALS registry_common'
+ )
+
+
+bld.SAMBA_BINARY('regshell',
+ source='tools/regshell.c',
+ manpages='man/regshell.1',
+ deps='samba-hostconfig popt registry POPT_SAMBA POPT_CREDENTIALS SMBREADLINE registry_common'
+ )
+
+
+bld.SAMBA_BINARY('regtree',
+ source='tools/regtree.c',
+ manpages='man/regtree.1',
+ deps='samba-hostconfig popt registry POPT_SAMBA POPT_CREDENTIALS registry_common'
+ )
+
+
+bld.SAMBA_SUBSYSTEM('torture_registry',
+ source='tests/generic.c tests/hive.c tests/diff.c tests/registry.c',
+ autoproto='tests/proto.h',
+ deps='torture registry'
+ )
+
+
+bld.SAMBA_PYTHON('py_registry',
+ source='pyregistry.c',
+ public_deps='registry pytalloc-util pyparam_util',
+ realname='samba/registry.so'
+ )
+
diff --git a/source4/lib/samba3/config.mk b/source4/lib/samba3/config.mk
deleted file mode 100644
index 365347fe21..0000000000
--- a/source4/lib/samba3/config.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-################################################
-# Start SUBSYSTEM LIBSAMBA3
-[SUBSYSTEM::SMBPASSWD]
-PRIVATE_DEPENDENCIES = CHARSET LIBSAMBA-UTIL
-# End SUBSYSTEM LIBSAMBA3
-################################################
-
-SMBPASSWD_OBJ_FILES = $(libsrcdir)/samba3/smbpasswd.o
diff --git a/source4/lib/samba3/wscript_build b/source4/lib/samba3/wscript_build
new file mode 100644
index 0000000000..98248c9e17
--- /dev/null
+++ b/source4/lib/samba3/wscript_build
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+
+bld.SAMBA_LIBRARY('smbpasswdparser',
+ source='smbpasswd.c',
+ deps='samba-util',
+ private_library=True
+ )
+
diff --git a/source4/lib/smbreadline/readline.m4 b/source4/lib/smbreadline/readline.m4
deleted file mode 100644
index df154409ad..0000000000
--- a/source4/lib/smbreadline/readline.m4
+++ /dev/null
@@ -1,91 +0,0 @@
-###############################################
-# Readline included by default unless explicitly asked not to
-test "${with_readline+set}" != "set" && with_readline=yes
-
-EXTERNAL_READLINE=no
-# test for where we get readline() from
-AC_MSG_CHECKING(whether to use readline)
-AC_ARG_WITH(readline,
-[AS_HELP_STRING([--with-readline[=DIR]], [Look for readline include/libs in DIR (default=auto)])],
-[ case "$with_readline" in
- yes)
- AC_MSG_RESULT(yes)
-
- AC_CHECK_HEADERS(readline.h history.h readline/readline.h)
- AC_CHECK_HEADERS(readline/history.h)
-
- AC_CHECK_HEADERS(readline.h readline/readline.h,[
- for termlib in ncurses curses termcap terminfo termlib tinfo; do
- AC_CHECK_LIB(${termlib}, tgetent, [TERMLIBS="-l${termlib}"; break])
- done
- AC_CHECK_LIB(readline, rl_callback_handler_install,
- [TERMLIBS="-lreadline $TERMLIBS"
- EXTERNAL_READLINE=yes
- break], [TERMLIBS=], $TERMLIBS)])
- ;;
- no)
- AC_MSG_RESULT(no)
- ;;
- *)
- AC_MSG_RESULT(yes)
-
- # Needed for AC_CHECK_HEADERS and AC_CHECK_LIB to look at
- # alternate readline path
- _ldflags=${LDFLAGS}
- _cppflags=${CPPFLAGS}
-
- # Add additional search path
- LDFLAGS="-L$with_readline/lib $LDFLAGS"
- CPPFLAGS="-I$with_readline/include $CPPFLAGS"
-
- AC_CHECK_HEADERS(readline.h history.h readline/readline.h)
- AC_CHECK_HEADERS(readline/history.h)
-
- AC_CHECK_HEADERS(readline.h readline/readline.h,[
- for termlib in ncurses curses termcap terminfo termlib; do
- AC_CHECK_LIB(${termlib}, tgetent, [TERMLIBS="-l${termlib}"; break])
- done
- AC_CHECK_LIB(readline, rl_callback_handler_install,
- [TERMLDFLAGS="-L$with_readline/lib"
- TERMCPPFLAGS="-I$with_readline/include"
- LDFLAGS="-L$with_readline/lib $LDFLAGS"
- CPPFLAGS="-I$with_readline/include $CPPFLAGS"
- TERMLIBS="-lreadline $TERMLIBS"
- EXTERNAL_READLINE=yes
- break], [TERMLIBS= CPPFLAGS=$_cppflags], $TERMLIBS)])
-
- ;;
- esac],
- AC_MSG_RESULT(no)
-)
-
-# The readline API changed slightly from readline3 to readline4, so
-# code will generate warnings on one of them unless we have a few
-# special cases.
-AC_CHECK_LIB(readline, rl_completion_matches,
- [AC_DEFINE(HAVE_NEW_LIBREADLINE, 1,
- [Do we have rl_completion_matches?])],
- [],
- [$TERMLIBS])
-
-# not all readline libs have rl_event_hook or history_list
-AC_CHECK_DECLS(rl_event_hook, [], [], [
- #include <stdio.h>
- #include <readline/readline.h>
-])
-AC_CHECK_LIB(readline, history_list,
- [AC_DEFINE(HAVE_HISTORY_LIST, 1, [Do we have history_list?])],
- [],
- [$TERMLIBS])
-
-AC_MSG_CHECKING(whether to use extern readline)
-if test x"$EXTERNAL_READLINE" = x"yes"; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_LIBREADLINE,1,[Whether the system has readline])
- SMB_SUBSYSTEM(SMBREADLINE, [\$(smbreadlinesrcdir)/smbreadline.o], [READLINE])
- SMB_EXT_LIB(READLINE, [${TERMLIBS}])
- SMB_ENABLE(READLINE,YES)
-else
- SMB_SUBSYSTEM(SMBREADLINE, [\$(smbreadlinesrcdir)/smbreadline.o], [])
- AC_MSG_RESULT(no)
-fi
diff --git a/source4/lib/smbreadline/smbreadline.c b/source4/lib/smbreadline/smbreadline.c
deleted file mode 100644
index b07417357f..0000000000
--- a/source4/lib/smbreadline/smbreadline.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba readline wrapper implementation
- Copyright (C) Simo Sorce 2001
- Copyright (C) Andrew Tridgell 2001
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "system/filesys.h"
-#include "system/select.h"
-#include "system/readline.h"
-#include "lib/smbreadline/smbreadline.h"
-
-/*******************************************************************
- Similar to sys_select() but catch EINTR and continue.
- This is what sys_select() used to do in Samba.
-********************************************************************/
-
-static int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
-{
- int ret;
- fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
- struct timeval tval2, *ptval;
-
- readfds2 = (readfds ? &readfds_buf : NULL);
- writefds2 = (writefds ? &writefds_buf : NULL);
- errorfds2 = (errorfds ? &errorfds_buf : NULL);
- ptval = (tval ? &tval2 : NULL);
-
- do {
- if (readfds)
- readfds_buf = *readfds;
- if (writefds)
- writefds_buf = *writefds;
- if (errorfds)
- errorfds_buf = *errorfds;
- if (tval)
- tval2 = *tval;
-
- /* We must use select and not sys_select here. If we use
- sys_select we'd lose the fact a signal occurred when sys_select
- read a byte from the pipe. Fix from Mark Weaver
- <mark-clist@npsl.co.uk>
- */
-
- ret = select(maxfd, readfds2, writefds2, errorfds2, ptval);
- } while (ret == -1 && errno == EINTR);
-
- if (readfds)
- *readfds = readfds_buf;
- if (writefds)
- *writefds = writefds_buf;
- if (errorfds)
- *errorfds = errorfds_buf;
-
- return ret;
-}
-
-/****************************************************************************
- Display the prompt and wait for input. Call callback() regularly
-****************************************************************************/
-
-static char *smb_readline_replacement(const char *prompt, void (*callback)(void),
- char **(completion_fn)(const char *text, int start, int end))
-{
- fd_set fds;
- char *line;
- struct timeval timeout;
- int fd = STDIN_FILENO;
- char *ret;
-
- printf("%s", prompt);
- fflush(stdout);
-
- line = (char *)malloc(BUFSIZ);
- if (!line) {
- return NULL;
- }
-
- while (1) {
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
- ret = x_fgets(line, BUFSIZ, x_stdin);
- return ret;
- }
- if (callback)
- callback();
- }
-}
-
-/****************************************************************************
- Display the prompt and wait for input. Call callback() regularly.
-****************************************************************************/
-
-char *smb_readline(const char *prompt, void (*callback)(void),
- char **(completion_fn)(const char *text, int start, int end))
-{
-#if HAVE_LIBREADLINE
- if (isatty(STDIN_FILENO)) {
- char *ret;
-
- /* Aargh! Readline does bizzare things with the terminal width
- that mucks up expect(1). Set CLI_NO_READLINE in the environment
- to force readline not to be used. */
-
- if (getenv("CLI_NO_READLINE"))
- return smb_readline_replacement(prompt, callback, completion_fn);
-
- if (completion_fn) {
- /* The callback prototype has changed slightly between
- different versions of Readline, so the same function
- works in all of them to date, but we get compiler
- warnings in some. */
- rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
- }
-
-#if HAVE_DECL_RL_EVENT_HOOK
- if (callback)
- rl_event_hook = (Function *)callback;
-#endif
- ret = readline(prompt);
- if (ret && *ret)
- add_history(ret);
- return ret;
- } else
-#endif
- return smb_readline_replacement(prompt, callback, completion_fn);
-}
-
-/****************************************************************************
- * return line buffer text
- ****************************************************************************/
-const char *smb_readline_get_line_buffer(void)
-{
-#if defined(HAVE_LIBREADLINE)
- return rl_line_buffer;
-#else
- return NULL;
-#endif
-}
-
-/****************************************************************************
- * set completion append character
- ***************************************************************************/
-void smb_readline_ca_char(char c)
-{
-#if defined(HAVE_LIBREADLINE)
- rl_completion_append_character = c;
-#endif
-}
-
-
-
diff --git a/source4/lib/smbreadline/smbreadline.h b/source4/lib/smbreadline/smbreadline.h
deleted file mode 100644
index cde2b47a24..0000000000
--- a/source4/lib/smbreadline/smbreadline.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __SMBREADLINE_H__
-#define __SMBREADLINE_H__
-
-char *smb_readline(const char *prompt, void (*callback)(void),
- char **(completion_fn)(const char *text, int start, int end));
-const char *smb_readline_get_line_buffer(void);
-void smb_readline_ca_char(char c);
-
-#endif /* __SMBREADLINE_H__ */
diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c
index 42c42db365..ab39d63ef5 100644
--- a/source4/lib/socket/access.c
+++ b/source4/lib/socket/access.c
@@ -34,6 +34,7 @@
#include "system/network.h"
#include "lib/socket/socket.h"
#include "system/locale.h"
+#include "lib/util/util_net.h"
#define FAIL (-1)
#define ALLONES ((uint32_t)0xFFFFFFFF)
diff --git a/source4/lib/socket/config.m4 b/source4/lib/socket/config.m4
deleted file mode 100644
index fa987a1f46..0000000000
--- a/source4/lib/socket/config.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-AC_CHECK_FUNCS(writev)
-AC_CHECK_FUNCS(readv)
-
-############################################
-# check for unix domain sockets
-# done by AC_LIBREPLACE_NETWORK_CHECKS
-SMB_ENABLE(socket_unix, NO)
-if test x"$libreplace_cv_HAVE_UNIXSOCKET" = x"yes"; then
- SMB_ENABLE(socket_unix, YES)
-fi
-
-############################################
-# check for ipv6
-# done by AC_LIBREPLACE_NETWORK_CHECKS
-SMB_ENABLE(socket_ipv6, NO)
-if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then
- SMB_ENABLE(socket_ipv6, YES)
-fi
diff --git a/source4/lib/socket/config.mk b/source4/lib/socket/config.mk
deleted file mode 100644
index ac515c8f6d..0000000000
--- a/source4/lib/socket/config.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-##############################
-# Start SUBSYSTEM LIBNETIF
-[SUBSYSTEM::LIBNETIF]
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBREPLACE_NETWORK
-# End SUBSYSTEM LIBNETIF
-##############################
-
-LIBNETIF_OBJ_FILES = $(addprefix $(libsocketsrcdir)/, interface.o netif.o)
-
-$(eval $(call proto_header_template,$(libsocketsrcdir)/netif_proto.h,$(LIBNETIF_OBJ_FILES:.o=.c)))
-
-################################################
-# Start MODULE socket_ip
-[MODULE::socket_ip]
-SUBSYSTEM = samba_socket
-OUTPUT_TYPE = MERGED_OBJ
-PRIVATE_DEPENDENCIES = LIBSAMBA-ERRORS LIBREPLACE_NETWORK
-# End MODULE socket_ip
-################################################
-
-socket_ip_OBJ_FILES = $(libsocketsrcdir)/socket_ip.o
-
-################################################
-# Start MODULE socket_unix
-[MODULE::socket_unix]
-SUBSYSTEM = samba_socket
-OUTPUT_TYPE = MERGED_OBJ
-PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
-# End MODULE socket_unix
-################################################
-
-socket_unix_OBJ_FILES = $(libsocketsrcdir)/socket_unix.o
-
-################################################
-# Start SUBSYSTEM SOCKET
-[SUBSYSTEM::samba_socket]
-PUBLIC_DEPENDENCIES = LIBTALLOC
-PRIVATE_DEPENDENCIES = SOCKET_WRAPPER LIBCLI_COMPOSITE LIBCLI_RESOLVE
-# End SUBSYSTEM SOCKET
-################################################
-
-samba_socket_OBJ_FILES = $(addprefix $(libsocketsrcdir)/, socket.o access.o connect_multi.o connect.o)
-
diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c
index 68386ba565..300e5fb1e5 100644
--- a/source4/lib/socket/connect_multi.c
+++ b/source4/lib/socket/connect_multi.c
@@ -33,7 +33,7 @@
overall state
*/
struct connect_multi_state {
- const char *server_address;
+ struct socket_address *server_address;
int num_ports;
uint16_t *ports;
@@ -64,7 +64,7 @@ static void continue_one(struct composite_context *creq);
*/
_PUBLIC_ struct composite_context *socket_connect_multi_send(
TALLOC_CTX *mem_ctx,
- const char *server_address,
+ const char *server_name,
int num_server_ports,
uint16_t *server_ports,
struct resolve_context *resolve_ctx,
@@ -74,6 +74,9 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(
struct connect_multi_state *multi;
int i;
+ struct nbt_name name;
+ struct composite_context *creq;
+
result = talloc_zero(mem_ctx, struct composite_context);
if (result == NULL) return NULL;
result->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -83,9 +86,6 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(
if (composite_nomem(multi, result)) goto failed;
result->private_data = multi;
- multi->server_address = talloc_strdup(multi, server_address);
- if (composite_nomem(multi->server_address, result)) goto failed;
-
multi->num_ports = num_server_ports;
multi->ports = talloc_array(multi, uint16_t, multi->num_ports);
if (composite_nomem(multi->ports, result)) goto failed;
@@ -94,30 +94,21 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(
multi->ports[i] = server_ports[i];
}
- if (!is_ipaddress(server_address)) {
- /*
- we don't want to do the name resolution separately
+ /*
+ we don't want to do the name resolution separately
for each port, so start it now, then only start on
the real sockets once we have an IP
- */
- struct nbt_name name;
- struct composite_context *creq;
- make_nbt_name_server(&name, server_address);
- creq = resolve_name_send(resolve_ctx, multi, &name, result->event_ctx);
- if (composite_nomem(creq, result)) goto failed;
- composite_continue(result, creq, continue_resolve_name, result);
- return result;
- }
+ */
+ make_nbt_name_server(&name, server_name);
- /* now we've setup the state we can process the first socket */
- connect_multi_next_socket(result);
+ creq = resolve_name_all_send(resolve_ctx, multi, 0, multi->ports[0], &name, result->event_ctx);
+ if (composite_nomem(creq, result)) goto failed;
- if (!NT_STATUS_IS_OK(result->status)) {
- goto failed;
- }
+ composite_continue(result, creq, continue_resolve_name, result);
return result;
+
failed:
composite_error(result, result->status);
return result;
@@ -148,11 +139,11 @@ static void connect_multi_next_socket(struct composite_context *result)
result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0);
if (!composite_is_ok(result)) return;
- /* Form up the particular address we are interested in */
- state->addr = socket_address_from_strings(state, state->sock->backend_name,
- multi->server_address, multi->ports[next]);
+ state->addr = socket_address_copy(state, multi->server_address);
if (composite_nomem(state->addr, result)) return;
+ socket_address_set_port(state->addr, multi->ports[next]);
+
talloc_steal(state, state->sock);
creq = socket_connect_send(state->sock, NULL,
@@ -197,12 +188,13 @@ static void continue_resolve_name(struct composite_context *creq)
struct composite_context);
struct connect_multi_state *multi = talloc_get_type(result->private_data,
struct connect_multi_state);
- const char *addr;
+ struct socket_address **addr;
- result->status = resolve_name_recv(creq, multi, &addr);
+ result->status = resolve_name_all_recv(creq, multi, &addr, NULL);
if (!composite_is_ok(result)) return;
- multi->server_address = addr;
+ /* Let's just go for the first for now */
+ multi->server_address = addr[0];
connect_multi_next_socket(result);
}
diff --git a/source4/lib/socket/interface.c b/source4/lib/socket/interface.c
index af81804911..c4411b623c 100644
--- a/source4/lib/socket/interface.c
+++ b/source4/lib/socket/interface.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "system/network.h"
#include "lib/socket/netif.h"
+#include "../lib/util/util_net.h"
#include "../lib/util/dlinklist.h"
/** used for network interfaces */
@@ -93,7 +94,7 @@ static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr
DLIST_ADD_END(*interfaces, iface, struct interface *);
- DEBUG(2,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s));
+ DEBUG(3,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s));
}
diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c
index bf410af441..e36f268bde 100644
--- a/source4/lib/socket/netif.c
+++ b/source4/lib/socket/netif.c
@@ -34,6 +34,7 @@
#include "includes.h"
#include "system/network.h"
#include "netif.h"
+#include "lib/util/tsort.h"
/****************************************************************************
Try the "standard" getifaddrs/freeifaddrs interfaces.
@@ -109,7 +110,7 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
if (total <= 0) return total;
/* now we need to remove duplicates */
- qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp);
+ TYPESAFE_QSORT(ifaces, total, iface_comp);
for (i=1;i<total;) {
if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) {
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index 8e2f1683f2..4b5cecab34 100644
--- a/source4/lib/socket/socket.c
+++ b/source4/lib/socket/socket.c
@@ -24,6 +24,8 @@
#include "system/filesys.h"
#include "system/network.h"
#include "param/param.h"
+#include "../lib/tsocket/tsocket.h"
+#include "lib/util/util_net.h"
/*
auto-close sockets on free
@@ -344,6 +346,88 @@ _PUBLIC_ struct socket_address *socket_get_my_addr(struct socket_context *sock,
return sock->ops->fn_get_my_addr(sock, mem_ctx);
}
+_PUBLIC_ struct tsocket_address *socket_address_to_tsocket_address(TALLOC_CTX *mem_ctx,
+ const struct socket_address *a)
+{
+ struct tsocket_address *r;
+ int ret;
+
+ if (a->sockaddr) {
+ ret = tsocket_address_bsd_from_sockaddr(mem_ctx,
+ a->sockaddr,
+ a->sockaddrlen,
+ &r);
+ } else {
+ ret = tsocket_address_inet_from_strings(mem_ctx,
+ a->family,
+ a->addr,
+ a->port,
+ &r);
+ }
+
+ if (ret != 0) {
+ return NULL;
+ }
+
+ return r;
+}
+
+_PUBLIC_ void socket_address_set_port(struct socket_address *a,
+ uint16_t port)
+{
+ if (a->sockaddr) {
+ set_sockaddr_port(a->sockaddr, port);
+ } else {
+ a->port = port;
+ }
+
+}
+
+_PUBLIC_ struct socket_address *tsocket_address_to_socket_address(TALLOC_CTX *mem_ctx,
+ const struct tsocket_address *a)
+{
+ ssize_t ret;
+ struct sockaddr_storage ss;
+ size_t sslen = sizeof(ss);
+
+ ret = tsocket_address_bsd_sockaddr(a, (struct sockaddr *)(void *)&ss, sslen);
+ if (ret < 0) {
+ return NULL;
+ }
+
+ return socket_address_from_sockaddr(mem_ctx, (struct sockaddr *)(void *)&ss, ret);
+}
+
+_PUBLIC_ struct tsocket_address *socket_get_remote_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+{
+ struct socket_address *a;
+ struct tsocket_address *r;
+
+ a = socket_get_peer_addr(sock, mem_ctx);
+ if (a == NULL) {
+ return NULL;
+ }
+
+ r = socket_address_to_tsocket_address(mem_ctx, a);
+ talloc_free(a);
+ return r;
+}
+
+_PUBLIC_ struct tsocket_address *socket_get_local_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+{
+ struct socket_address *a;
+ struct tsocket_address *r;
+
+ a = socket_get_my_addr(sock, mem_ctx);
+ if (a == NULL) {
+ return NULL;
+ }
+
+ r = socket_address_to_tsocket_address(mem_ctx, a);
+ talloc_free(a);
+ return r;
+}
+
_PUBLIC_ int socket_get_fd(struct socket_context *sock)
{
if (!sock->ops->fn_get_fd) {
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index 0f469e5ceb..4a744797b3 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -127,6 +127,7 @@ struct socket_context {
};
struct resolve_context;
+struct tsocket_address;
/* prototypes */
NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops,
@@ -158,6 +159,12 @@ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, cons
char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx);
struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
+struct tsocket_address *socket_address_to_tsocket_address(TALLOC_CTX *mem_ctx,
+ const struct socket_address *a);
+struct socket_address *tsocket_address_to_socket_address(TALLOC_CTX *mem_ctx,
+ const struct tsocket_address *a);
+struct tsocket_address *socket_get_remote_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
+struct tsocket_address *socket_get_local_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
int socket_get_fd(struct socket_context *sock);
NTSTATUS socket_dup(struct socket_context *sock);
struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
@@ -167,6 +174,8 @@ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx,
struct sockaddr *sockaddr,
size_t addrlen);
+_PUBLIC_ void socket_address_set_port(struct socket_address *a,
+ uint16_t port);
struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx,
const struct socket_address *oaddr);
const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type);
@@ -206,7 +215,7 @@ NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx, const char *server_address,
struct socket_context **result,
uint16_t *port);
void set_socket_options(int fd, const char *options);
-void socket_set_flags(struct socket_context *socket, unsigned flags);
+void socket_set_flags(struct socket_context *sock, unsigned flags);
void socket_tevent_fd_close_fn(struct tevent_context *ev,
struct tevent_fd *fde,
diff --git a/source4/lib/socket/socket_ip.c b/source4/lib/socket/socket_ip.c
index 89b310a23a..9a02f0184c 100644
--- a/source4/lib/socket/socket_ip.c
+++ b/source4/lib/socket/socket_ip.c
@@ -25,6 +25,7 @@
#include "system/filesys.h"
#include "lib/socket/socket.h"
#include "system/network.h"
+#include "lib/util/util_net.h"
static NTSTATUS ipv4_init(struct socket_context *sock)
{
@@ -711,7 +712,7 @@ static NTSTATUS ipv6_listen(struct socket_context *sock,
static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_context **new_sock)
{
- struct sockaddr_in cli_addr;
+ struct sockaddr_in6 cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
int new_fd;
diff --git a/source4/lib/socket/testsuite.c b/source4/lib/socket/testsuite.c
index cba283f558..2489277433 100644
--- a/source4/lib/socket/testsuite.c
+++ b/source4/lib/socket/testsuite.c
@@ -42,7 +42,7 @@ static bool test_udp(struct torture_context *tctx)
TALLOC_CTX *mem_ctx = tctx;
struct interface *ifaces;
- load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
+ load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0);
torture_assert_ntstatus_ok(tctx, status, "creating DGRAM IP socket 1");
@@ -135,7 +135,7 @@ static bool test_tcp(struct torture_context *tctx)
torture_assert_ntstatus_ok(tctx, status, "creating IP stream socket 1");
talloc_steal(mem_ctx, sock2);
- load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
+ load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
localhost = socket_address_from_strings(sock1, sock1->backend_name,
iface_best_ip(ifaces, "127.0.0.1"), 0);
torture_assert(tctx, localhost, "Localhost not found");
@@ -188,8 +188,7 @@ static bool test_tcp(struct torture_context *tctx)
struct torture_suite *torture_local_socket(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx,
- "SOCKET");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "socket");
torture_suite_add_simple_test(suite, "udp", test_udp);
torture_suite_add_simple_test(suite, "tcp", test_tcp);
diff --git a/source4/lib/socket/wscript_build b/source4/lib/socket/wscript_build
new file mode 100644
index 0000000000..e2ff9b078a
--- /dev/null
+++ b/source4/lib/socket/wscript_build
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('netif',
+ source='interface.c netif.c',
+ autoproto='netif_proto.h',
+ deps='samba-util',
+ private_library=True
+ )
+
+bld.SAMBA_MODULE('socket_ip',
+ source='socket_ip.c',
+ subsystem='samba_socket',
+ deps='errors',
+ internal_module=True
+ )
+
+bld.SAMBA_MODULE('socket_unix',
+ source='socket_unix.c',
+ subsystem='samba_socket',
+ deps='talloc',
+ internal_module=True
+ )
+
+bld.SAMBA_SUBSYSTEM('samba_socket',
+ source='socket.c access.c connect_multi.c connect.c',
+ public_deps='talloc LIBTSOCKET',
+ deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE socket_ip socket_unix'
+ )
+
diff --git a/source4/lib/stream/config.mk b/source4/lib/stream/config.mk
deleted file mode 100644
index 56d117e7bd..0000000000
--- a/source4/lib/stream/config.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-[SUBSYSTEM::LIBPACKET]
-PRIVATE_DEPENDENCIES = LIBTLS
-
-LIBPACKET_OBJ_FILES = $(libstreamsrcdir)/packet.o
diff --git a/source4/lib/stream/packet.c b/source4/lib/stream/packet.c
index f5e2b843cd..98343707c1 100644
--- a/source4/lib/stream/packet.c
+++ b/source4/lib/stream/packet.c
@@ -42,6 +42,7 @@ struct packet_context {
bool serialise;
int processing;
bool recv_disable;
+ bool recv_need_enable;
bool nofree;
bool busy;
@@ -256,6 +257,7 @@ _PUBLIC_ void packet_recv(struct packet_context *pc)
}
if (pc->recv_disable) {
+ pc->recv_need_enable = true;
EVENT_FD_NOT_READABLE(pc->fde);
return;
}
@@ -464,7 +466,6 @@ next_partial:
*/
_PUBLIC_ void packet_recv_disable(struct packet_context *pc)
{
- EVENT_FD_NOT_READABLE(pc->fde);
pc->recv_disable = true;
}
@@ -473,7 +474,10 @@ _PUBLIC_ void packet_recv_disable(struct packet_context *pc)
*/
_PUBLIC_ void packet_recv_enable(struct packet_context *pc)
{
- EVENT_FD_READABLE(pc->fde);
+ if (pc->recv_need_enable) {
+ pc->recv_need_enable = false;
+ EVENT_FD_READABLE(pc->fde);
+ }
pc->recv_disable = false;
if (pc->num_read != 0 && pc->packet_size >= pc->num_read) {
event_add_timed(pc->ev, pc, timeval_zero(), packet_next_event, pc);
@@ -526,7 +530,7 @@ _PUBLIC_ void packet_queue_run(struct packet_context *pc)
put a packet in the send queue. When the packet is actually sent,
call send_callback.
- Useful for operations that must occour after sending a message, such
+ Useful for operations that must occur after sending a message, such
as the switch to SASL encryption after as sucessful LDAP bind relpy.
*/
_PUBLIC_ NTSTATUS packet_send_callback(struct packet_context *pc, DATA_BLOB blob,
diff --git a/source4/lib/stream/packet.h b/source4/lib/stream/packet.h
index 85f0f26265..a274bd397c 100644
--- a/source4/lib/stream/packet.h
+++ b/source4/lib/stream/packet.h
@@ -23,6 +23,7 @@
struct packet_context;
struct tevent_context;
struct tevent_fd;
+struct socket_context;
typedef NTSTATUS (*packet_full_request_fn_t)(void *private_data,
DATA_BLOB blob, size_t *packet_size);
diff --git a/source4/lib/stream/wscript_build b/source4/lib/stream/wscript_build
new file mode 100644
index 0000000000..8427c17045
--- /dev/null
+++ b/source4/lib/stream/wscript_build
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+
+bld.SAMBA_SUBSYSTEM('LIBPACKET',
+ source='packet.c',
+ deps='LIBTLS'
+ )
+
diff --git a/source4/lib/tdb_wrap.c b/source4/lib/tdb_wrap.c
deleted file mode 100644
index da27803b06..0000000000
--- a/source4/lib/tdb_wrap.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- TDB wrap functions
-
- Copyright (C) Andrew Tridgell 2004
- Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "../tdb/include/tdb.h"
-#include "../lib/util/dlinklist.h"
-#include "tdb_wrap.h"
-#include "tdb.h"
-
-static struct tdb_wrap *tdb_list;
-
-/* destroy the last connection to a tdb */
-static int tdb_wrap_destructor(struct tdb_wrap *w)
-{
- tdb_close(w->tdb);
- DLIST_REMOVE(tdb_list, w);
- return 0;
-}
-
-/*
- Log tdb messages via DEBUG().
-*/
-static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
- const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-
-static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
- const char *format, ...)
-{
- va_list ap;
- char *ptr = NULL;
- int dl;
-
- va_start(ap, format);
- vasprintf(&ptr, format, ap);
- va_end(ap);
-
- switch (level) {
- case TDB_DEBUG_FATAL:
- dl = 0;
- break;
- case TDB_DEBUG_ERROR:
- dl = 1;
- break;
- case TDB_DEBUG_WARNING:
- dl = 2;
- break;
- case TDB_DEBUG_TRACE:
- dl = 5;
- break;
- default:
- dl = 0;
- }
-
- if (ptr != NULL) {
- const char *name = tdb_name(tdb);
- DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", ptr));
- free(ptr);
- }
-}
-
-
-/*
- wrapped connection to a tdb database
- to close just talloc_free() the tdb_wrap pointer
- */
-struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
- const char *name, int hash_size, int tdb_flags,
- int open_flags, mode_t mode)
-{
- struct tdb_wrap *w;
- struct tdb_logging_context log_ctx;
- log_ctx.log_fn = tdb_wrap_log;
-
- for (w=tdb_list;w;w=w->next) {
- if (strcmp(name, w->name) == 0) {
- return talloc_reference(mem_ctx, w);
- }
- }
-
- w = talloc(mem_ctx, struct tdb_wrap);
- if (w == NULL) {
- return NULL;
- }
-
- w->name = talloc_strdup(w, name);
-
- w->tdb = tdb_open_ex(name, hash_size, tdb_flags,
- open_flags, mode, &log_ctx, NULL);
- if (w->tdb == NULL) {
- talloc_free(w);
- return NULL;
- }
-
- talloc_set_destructor(w, tdb_wrap_destructor);
-
- DLIST_ADD(tdb_list, w);
-
- return w;
-}
diff --git a/source4/lib/tdb_wrap.h b/source4/lib/tdb_wrap.h
deleted file mode 100644
index eb0191fb31..0000000000
--- a/source4/lib/tdb_wrap.h
+++ /dev/null
@@ -1,38 +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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _TDB_WRAP_H_
-#define _TDB_WRAP_H_
-
-#include "../lib/tdb/include/tdb.h"
-
-struct tdb_wrap {
- struct tdb_context *tdb;
-
- const char *name;
- struct tdb_wrap *next, *prev;
-};
-
-struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
- const char *name, int hash_size, int tdb_flags,
- int open_flags, mode_t mode);
-
-#endif /* _TDB_WRAP_H_ */
diff --git a/source4/lib/tls/config.m4 b/source4/lib/tls/config.m4
deleted file mode 100644
index 709a095908..0000000000
--- a/source4/lib/tls/config.m4
+++ /dev/null
@@ -1,45 +0,0 @@
-###############################
-# start SMB_EXT_LIB_GNUTLS
-# check for gnutls/gnutls.h and -lgnutls
-
-use_gnutls=auto
-AC_ARG_ENABLE(gnutls,
-AS_HELP_STRING([--enable-gnutls],[Turn on gnutls support (default=yes)]),
- [if test x$enable_gnutls = xno; then
- use_gnutls=no
- fi])
-
-
-if test x$use_gnutls = xauto && pkg-config --exists gnutls; then
- SMB_EXT_LIB_FROM_PKGCONFIG(GNUTLS, gnutls >= 1.4.0,
- [use_gnutls=yes],
- [use_gnutls=no])
-fi
-
-if test x$use_gnutls = xauto; then
- AC_CHECK_HEADERS(gnutls/gnutls.h)
- AC_CHECK_LIB_EXT(gnutls, GNUTLS_LIBS, gnutls_global_init)
- AC_CHECK_DECL(gnutls_x509_crt_set_version,
- [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_VERSION,1,gnutls set_version)], [], [
- #include <gnutls/gnutls.h>
- #include <gnutls/x509.h>
- ])
- if test x"$ac_cv_header_gnutls_gnutls_h" = x"yes" -a x"$ac_cv_lib_ext_gnutls_gnutls_global_init" = x"yes" -a x"$ac_cv_have_decl_gnutls_x509_crt_set_version" = x"yes";then
- SMB_ENABLE(GNUTLS,YES)
- AC_CHECK_DECL(gnutls_x509_crt_set_subject_key_id,
- [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID,1,gnutls subject_key)], [], [
- #include <gnutls/gnutls.h>
- #include <gnutls/x509.h>
- ])
- fi
- SMB_EXT_LIB(GNUTLS, $GNUTLS_LIBS)
-fi
-if test x$use_gnutls = xyes; then
- #Some older versions have a different type name
- AC_CHECK_TYPES([gnutls_datum],,,[#include "gnutls/gnutls.h"])
- AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"])
- AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)])
- AC_CHECK_HEADERS(gcrypt.h)
- AC_CHECK_LIB_EXT(gcrypt, GCRYPT_LIBS, gcry_control)
- SMB_EXT_LIB(GCRYPT, $GCRYPT_LIBS)
-fi
diff --git a/source4/lib/tls/config.mk b/source4/lib/tls/config.mk
deleted file mode 100644
index 0e1978cc1b..0000000000
--- a/source4/lib/tls/config.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-[SUBSYSTEM::LIBTLS]
-PUBLIC_DEPENDENCIES = \
- LIBTALLOC GNUTLS GCRYPT LIBSAMBA-HOSTCONFIG samba_socket
-
-LIBTLS_OBJ_FILES = $(addprefix $(libtlssrcdir)/, tls.o tlscert.o)
diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c
index ba2e9e431b..63724e9628 100644
--- a/source4/lib/tls/tls.c
+++ b/source4/lib/tls/tls.c
@@ -357,11 +357,11 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *
struct tls_params *params;
int ret;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- const char *keyfile = lp_tls_keyfile(tmp_ctx, lp_ctx);
- const char *certfile = lp_tls_certfile(tmp_ctx, lp_ctx);
- const char *cafile = lp_tls_cafile(tmp_ctx, lp_ctx);
- const char *crlfile = lp_tls_crlfile(tmp_ctx, lp_ctx);
- const char *dhpfile = lp_tls_dhpfile(tmp_ctx, lp_ctx);
+ const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx);
+ const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx);
+ const char *cafile = lpcfg_tls_cafile(tmp_ctx, lp_ctx);
+ const char *crlfile = lpcfg_tls_crlfile(tmp_ctx, lp_ctx);
+ const char *dhpfile = lpcfg_tls_dhpfile(tmp_ctx, lp_ctx);
void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *);
params = talloc(mem_ctx, struct tls_params);
if (params == NULL) {
@@ -369,7 +369,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *
return NULL;
}
- if (!lp_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) {
+ if (!lpcfg_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) {
params->tls_enabled = false;
talloc_free(tmp_ctx);
return params;
@@ -377,7 +377,8 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *
if (!file_exist(cafile)) {
char *hostname = talloc_asprintf(mem_ctx, "%s.%s",
- lp_netbios_name(lp_ctx), lp_realm(lp_ctx));
+ lpcfg_netbios_name(lp_ctx),
+ lpcfg_dnsdomain(lp_ctx));
if (hostname == NULL) {
goto init_failed;
}
diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h
index c5bd5c87cc..e1bd9edb51 100644
--- a/source4/lib/tls/tls.h
+++ b/source4/lib/tls/tls.h
@@ -65,4 +65,50 @@ bool tls_support(struct tls_params *parms);
const struct socket_ops *socket_tls_ops(enum socket_type type);
-#endif
+struct tstream_context;
+struct tstream_tls_params;
+
+NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
+ const char *ca_file,
+ const char *crl_file,
+ struct tstream_tls_params **_tlsp);
+
+NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
+ const char *dns_host_name,
+ bool enabled,
+ const char *key_file,
+ const char *cert_file,
+ const char *ca_file,
+ const char *crl_file,
+ const char *dhp_file,
+ struct tstream_tls_params **_params);
+
+bool tstream_tls_params_enabled(struct tstream_tls_params *params);
+
+struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *plain_stream,
+ struct tstream_tls_params *tls_params,
+ const char *location);
+#define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params); \
+ _tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params, __location__)
+
+int tstream_tls_connect_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ struct tstream_context **tls_stream);
+
+struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *plain_stream,
+ struct tstream_tls_params *tls_params,
+ const char *location);
+#define tstream_tls_accept_send(mem_ctx, ev, plain_stream, tls_params) \
+ _tstream_tls_accept_send(mem_ctx, ev, plain_stream, tls_params, __location__)
+
+int tstream_tls_accept_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ struct tstream_context **tls_stream);
+
+#endif /* _TLS_H_ */
diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c
new file mode 100644
index 0000000000..c64b2eaa49
--- /dev/null
+++ b/source4/lib/tls/tls_tstream.c
@@ -0,0 +1,1354 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Stefan Metzmacher 2010
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "../util/tevent_unix.h"
+#include "../lib/tsocket/tsocket.h"
+#include "../lib/tsocket/tsocket_internal.h"
+#include "lib/tls/tls.h"
+
+#if ENABLE_GNUTLS
+#include "gnutls/gnutls.h"
+
+#define DH_BITS 1024
+
+#if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T)
+typedef gnutls_datum gnutls_datum_t;
+#endif
+
+#endif /* ENABLE_GNUTLS */
+
+static const struct tstream_context_ops tstream_tls_ops;
+
+struct tstream_tls {
+ struct tstream_context *plain_stream;
+ int error;
+
+#if ENABLE_GNUTLS
+ gnutls_session tls_session;
+#endif /* ENABLE_GNUTLS */
+
+ struct tevent_context *current_ev;
+
+ struct tevent_immediate *retry_im;
+
+ struct {
+ uint8_t *buf;
+ off_t ofs;
+ struct iovec iov;
+ struct tevent_req *subreq;
+ struct tevent_immediate *im;
+ } push;
+
+ struct {
+ uint8_t *buf;
+ struct iovec iov;
+ struct tevent_req *subreq;
+ } pull;
+
+ struct {
+ struct tevent_req *req;
+ } handshake;
+
+ struct {
+ off_t ofs;
+ size_t left;
+ uint8_t buffer[1024];
+ struct tevent_req *req;
+ } write;
+
+ struct {
+ off_t ofs;
+ size_t left;
+ uint8_t buffer[1024];
+ struct tevent_req *req;
+ } read;
+
+ struct {
+ struct tevent_req *req;
+ } disconnect;
+};
+
+static void tstream_tls_retry_handshake(struct tstream_context *stream);
+static void tstream_tls_retry_read(struct tstream_context *stream);
+static void tstream_tls_retry_write(struct tstream_context *stream);
+static void tstream_tls_retry_disconnect(struct tstream_context *stream);
+static void tstream_tls_retry_trigger(struct tevent_context *ctx,
+ struct tevent_immediate *im,
+ void *private_data);
+
+static void tstream_tls_retry(struct tstream_context *stream, bool deferred)
+{
+
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+
+ if (tlss->disconnect.req) {
+ tstream_tls_retry_disconnect(stream);
+ return;
+ }
+
+ if (tlss->handshake.req) {
+ tstream_tls_retry_handshake(stream);
+ return;
+ }
+
+ if (tlss->write.req && tlss->read.req && !deferred) {
+ tevent_schedule_immediate(tlss->retry_im, tlss->current_ev,
+ tstream_tls_retry_trigger,
+ stream);
+ }
+
+ if (tlss->write.req) {
+ tstream_tls_retry_write(stream);
+ return;
+ }
+
+ if (tlss->read.req) {
+ tstream_tls_retry_read(stream);
+ return;
+ }
+}
+
+static void tstream_tls_retry_trigger(struct tevent_context *ctx,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct tstream_context *stream =
+ talloc_get_type_abort(private_data,
+ struct tstream_context);
+
+ tstream_tls_retry(stream, true);
+}
+
+#if ENABLE_GNUTLS
+static void tstream_tls_push_trigger_write(struct tevent_context *ev,
+ struct tevent_immediate *im,
+ void *private_data);
+
+static ssize_t tstream_tls_push_function(gnutls_transport_ptr ptr,
+ const void *buf, size_t size)
+{
+ struct tstream_context *stream =
+ talloc_get_type_abort(ptr,
+ struct tstream_context);
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ uint8_t *nbuf;
+ size_t len;
+
+ if (tlss->error != 0) {
+ errno = tlss->error;
+ return -1;
+ }
+
+ if (tlss->push.subreq) {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ len = MIN(size, UINT16_MAX - tlss->push.ofs);
+
+ if (len == 0) {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ nbuf = talloc_realloc(tlss, tlss->push.buf,
+ uint8_t, tlss->push.ofs + len);
+ if (nbuf == NULL) {
+ if (tlss->push.buf) {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ return -1;
+ }
+ tlss->push.buf = nbuf;
+
+ memcpy(tlss->push.buf + tlss->push.ofs, buf, len);
+
+ if (tlss->push.im == NULL) {
+ tlss->push.im = tevent_create_immediate(tlss);
+ if (tlss->push.im == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+
+ if (tlss->push.ofs == 0) {
+ /*
+ * We'll do start the tstream_writev
+ * in the next event cycle.
+ *
+ * This way we can batch all push requests,
+ * if they fit into a UINT16_MAX buffer.
+ *
+ * This is important as gnutls_handshake()
+ * had a bug in some versions e.g. 2.4.1
+ * and others (See bug #7218) and it doesn't
+ * handle EAGAIN.
+ */
+ tevent_schedule_immediate(tlss->push.im,
+ tlss->current_ev,
+ tstream_tls_push_trigger_write,
+ stream);
+ }
+
+ tlss->push.ofs += len;
+ return len;
+}
+
+static void tstream_tls_push_done(struct tevent_req *subreq);
+
+static void tstream_tls_push_trigger_write(struct tevent_context *ev,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct tstream_context *stream =
+ talloc_get_type_abort(private_data,
+ struct tstream_context);
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *subreq;
+
+ if (tlss->push.subreq) {
+ /* nothing todo */
+ return;
+ }
+
+ tlss->push.iov.iov_base = (char *)tlss->push.buf;
+ tlss->push.iov.iov_len = tlss->push.ofs;
+
+ subreq = tstream_writev_send(tlss,
+ tlss->current_ev,
+ tlss->plain_stream,
+ &tlss->push.iov, 1);
+ if (subreq == NULL) {
+ tlss->error = ENOMEM;
+ tstream_tls_retry(stream, false);
+ return;
+ }
+ tevent_req_set_callback(subreq, tstream_tls_push_done, stream);
+
+ tlss->push.subreq = subreq;
+}
+
+static void tstream_tls_push_done(struct tevent_req *subreq)
+{
+ struct tstream_context *stream =
+ tevent_req_callback_data(subreq,
+ struct tstream_context);
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ int ret;
+ int sys_errno;
+
+ tlss->push.subreq = NULL;
+ ZERO_STRUCT(tlss->push.iov);
+ TALLOC_FREE(tlss->push.buf);
+ tlss->push.ofs = 0;
+
+ ret = tstream_writev_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+ if (ret == -1) {
+ tlss->error = sys_errno;
+ tstream_tls_retry(stream, false);
+ return;
+ }
+
+ tstream_tls_retry(stream, false);
+}
+
+static void tstream_tls_pull_done(struct tevent_req *subreq);
+
+static ssize_t tstream_tls_pull_function(gnutls_transport_ptr ptr,
+ void *buf, size_t size)
+{
+ struct tstream_context *stream =
+ talloc_get_type_abort(ptr,
+ struct tstream_context);
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *subreq;
+ size_t len;
+
+ if (tlss->error != 0) {
+ errno = tlss->error;
+ return -1;
+ }
+
+ if (tlss->pull.subreq) {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ if (tlss->pull.iov.iov_base) {
+ uint8_t *b;
+ size_t n;
+
+ b = (uint8_t *)tlss->pull.iov.iov_base;
+
+ n = MIN(tlss->pull.iov.iov_len, size);
+ memcpy(buf, b, n);
+
+ tlss->pull.iov.iov_len -= n;
+ b += n;
+ tlss->pull.iov.iov_base = (char *)b;
+ if (tlss->pull.iov.iov_len == 0) {
+ tlss->pull.iov.iov_base = NULL;
+ TALLOC_FREE(tlss->pull.buf);
+ }
+
+ return n;
+ }
+
+ if (size == 0) {
+ return 0;
+ }
+
+ len = MIN(size, UINT16_MAX);
+
+ tlss->pull.buf = talloc_array(tlss, uint8_t, len);
+ if (tlss->pull.buf == NULL) {
+ return -1;
+ }
+
+ tlss->pull.iov.iov_base = (char *)tlss->pull.buf;
+ tlss->pull.iov.iov_len = len;
+
+ subreq = tstream_readv_send(tlss,
+ tlss->current_ev,
+ tlss->plain_stream,
+ &tlss->pull.iov, 1);
+ if (subreq == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ tevent_req_set_callback(subreq, tstream_tls_pull_done, stream);
+
+ tlss->pull.subreq = subreq;
+ errno = EAGAIN;
+ return -1;
+}
+
+static void tstream_tls_pull_done(struct tevent_req *subreq)
+{
+ struct tstream_context *stream =
+ tevent_req_callback_data(subreq,
+ struct tstream_context);
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ int ret;
+ int sys_errno;
+
+ tlss->pull.subreq = NULL;
+
+ ret = tstream_readv_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+ if (ret == -1) {
+ tlss->error = sys_errno;
+ tstream_tls_retry(stream, false);
+ return;
+ }
+
+ tstream_tls_retry(stream, false);
+}
+#endif /* ENABLE_GNUTLS */
+
+static int tstream_tls_destructor(struct tstream_tls *tlss)
+{
+#if ENABLE_GNUTLS
+ if (tlss->tls_session) {
+ gnutls_deinit(tlss->tls_session);
+ tlss->tls_session = NULL;
+ }
+#endif /* ENABLE_GNUTLS */
+ return 0;
+}
+
+static ssize_t tstream_tls_pending_bytes(struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ size_t ret;
+
+ if (tlss->error != 0) {
+ errno = tlss->error;
+ return -1;
+ }
+
+#if ENABLE_GNUTLS
+ ret = gnutls_record_check_pending(tlss->tls_session);
+ ret += tlss->read.left;
+#else /* ENABLE_GNUTLS */
+ errno = ENOSYS;
+ ret = -1;
+#endif /* ENABLE_GNUTLS */
+ return ret;
+}
+
+struct tstream_tls_readv_state {
+ struct tstream_context *stream;
+
+ struct iovec *vector;
+ int count;
+
+ int ret;
+};
+
+static void tstream_tls_readv_crypt_next(struct tevent_req *req);
+
+static struct tevent_req *tstream_tls_readv_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ struct iovec *vector,
+ size_t count)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req;
+ struct tstream_tls_readv_state *state;
+
+ tlss->read.req = NULL;
+ tlss->current_ev = ev;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct tstream_tls_readv_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->stream = stream;
+ state->ret = 0;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return tevent_req_post(req, ev);
+ }
+
+ /*
+ * we make a copy of the vector so we can change the structure
+ */
+ state->vector = talloc_array(state, struct iovec, count);
+ if (tevent_req_nomem(state->vector, req)) {
+ return tevent_req_post(req, ev);
+ }
+ memcpy(state->vector, vector, sizeof(struct iovec) * count);
+ state->count = count;
+
+ tstream_tls_readv_crypt_next(req);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+}
+
+static void tstream_tls_readv_crypt_next(struct tevent_req *req)
+{
+ struct tstream_tls_readv_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_readv_state);
+ struct tstream_tls *tlss =
+ tstream_context_data(state->stream,
+ struct tstream_tls);
+
+ /*
+ * copy the pending buffer first
+ */
+ while (tlss->read.left > 0 && state->count > 0) {
+ uint8_t *base = (uint8_t *)state->vector[0].iov_base;
+ size_t len = MIN(tlss->read.left, state->vector[0].iov_len);
+
+ memcpy(base, tlss->read.buffer + tlss->read.ofs, len);
+
+ base += len;
+ state->vector[0].iov_base = (char *) base;
+ state->vector[0].iov_len -= len;
+
+ tlss->read.ofs += len;
+ tlss->read.left -= len;
+
+ if (state->vector[0].iov_len == 0) {
+ state->vector += 1;
+ state->count -= 1;
+ }
+
+ state->ret += len;
+ }
+
+ if (state->count == 0) {
+ tevent_req_done(req);
+ return;
+ }
+
+ tlss->read.req = req;
+ tstream_tls_retry_read(state->stream);
+}
+
+static void tstream_tls_retry_read(struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req = tlss->read.req;
+#if ENABLE_GNUTLS
+ int ret;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ tlss->read.left = 0;
+ tlss->read.ofs = 0;
+
+ ret = gnutls_record_recv(tlss->tls_session,
+ tlss->read.buffer,
+ sizeof(tlss->read.buffer));
+ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ return;
+ }
+
+ tlss->read.req = NULL;
+
+ if (gnutls_error_is_fatal(ret) != 0) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ if (ret == 0) {
+ tlss->error = EPIPE;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ tlss->read.left = ret;
+ tstream_tls_readv_crypt_next(req);
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+#endif /* ENABLE_GNUTLS */
+}
+
+static int tstream_tls_readv_recv(struct tevent_req *req,
+ int *perrno)
+{
+ struct tstream_tls_readv_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_readv_state);
+ struct tstream_tls *tlss =
+ tstream_context_data(state->stream,
+ struct tstream_tls);
+ int ret;
+
+ tlss->read.req = NULL;
+
+ ret = tsocket_simple_int_recv(req, perrno);
+ if (ret == 0) {
+ ret = state->ret;
+ }
+
+ tevent_req_received(req);
+ return ret;
+}
+
+struct tstream_tls_writev_state {
+ struct tstream_context *stream;
+
+ struct iovec *vector;
+ int count;
+
+ int ret;
+};
+
+static void tstream_tls_writev_crypt_next(struct tevent_req *req);
+
+static struct tevent_req *tstream_tls_writev_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream,
+ const struct iovec *vector,
+ size_t count)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req;
+ struct tstream_tls_writev_state *state;
+
+ tlss->write.req = NULL;
+ tlss->current_ev = ev;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct tstream_tls_writev_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->stream = stream;
+ state->ret = 0;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return tevent_req_post(req, ev);
+ }
+
+ /*
+ * we make a copy of the vector so we can change the structure
+ */
+ state->vector = talloc_array(state, struct iovec, count);
+ if (tevent_req_nomem(state->vector, req)) {
+ return tevent_req_post(req, ev);
+ }
+ memcpy(state->vector, vector, sizeof(struct iovec) * count);
+ state->count = count;
+
+ tstream_tls_writev_crypt_next(req);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+}
+
+static void tstream_tls_writev_crypt_next(struct tevent_req *req)
+{
+ struct tstream_tls_writev_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_writev_state);
+ struct tstream_tls *tlss =
+ tstream_context_data(state->stream,
+ struct tstream_tls);
+
+ tlss->write.left = sizeof(tlss->write.buffer);
+ tlss->write.ofs = 0;
+
+ /*
+ * first fill our buffer
+ */
+ while (tlss->write.left > 0 && state->count > 0) {
+ uint8_t *base = (uint8_t *)state->vector[0].iov_base;
+ size_t len = MIN(tlss->write.left, state->vector[0].iov_len);
+
+ memcpy(tlss->write.buffer + tlss->write.ofs, base, len);
+
+ base += len;
+ state->vector[0].iov_base = (char *) base;
+ state->vector[0].iov_len -= len;
+
+ tlss->write.ofs += len;
+ tlss->write.left -= len;
+
+ if (state->vector[0].iov_len == 0) {
+ state->vector += 1;
+ state->count -= 1;
+ }
+
+ state->ret += len;
+ }
+
+ if (tlss->write.ofs == 0) {
+ tevent_req_done(req);
+ return;
+ }
+
+ tlss->write.left = tlss->write.ofs;
+ tlss->write.ofs = 0;
+
+ tlss->write.req = req;
+ tstream_tls_retry_write(state->stream);
+}
+
+static void tstream_tls_retry_write(struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req = tlss->write.req;
+#if ENABLE_GNUTLS
+ int ret;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ ret = gnutls_record_send(tlss->tls_session,
+ tlss->write.buffer + tlss->write.ofs,
+ tlss->write.left);
+ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ return;
+ }
+
+ tlss->write.req = NULL;
+
+ if (gnutls_error_is_fatal(ret) != 0) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ if (ret == 0) {
+ tlss->error = EPIPE;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ tlss->write.ofs += ret;
+ tlss->write.left -= ret;
+
+ if (tlss->write.left > 0) {
+ tlss->write.req = req;
+ tstream_tls_retry_write(stream);
+ return;
+ }
+
+ tstream_tls_writev_crypt_next(req);
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+#endif /* ENABLE_GNUTLS */
+}
+
+static int tstream_tls_writev_recv(struct tevent_req *req,
+ int *perrno)
+{
+ struct tstream_tls_writev_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_writev_state);
+ struct tstream_tls *tlss =
+ tstream_context_data(state->stream,
+ struct tstream_tls);
+ int ret;
+
+ tlss->write.req = NULL;
+
+ ret = tsocket_simple_int_recv(req, perrno);
+ if (ret == 0) {
+ ret = state->ret;
+ }
+
+ tevent_req_received(req);
+ return ret;
+}
+
+struct tstream_tls_disconnect_state {
+ uint8_t _dummy;
+};
+
+static struct tevent_req *tstream_tls_disconnect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req;
+ struct tstream_tls_disconnect_state *state;
+
+ tlss->disconnect.req = NULL;
+ tlss->current_ev = ev;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct tstream_tls_disconnect_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return tevent_req_post(req, ev);
+ }
+
+ tlss->disconnect.req = req;
+ tstream_tls_retry_disconnect(stream);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+}
+
+static void tstream_tls_retry_disconnect(struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req = tlss->disconnect.req;
+#if ENABLE_GNUTLS
+ int ret;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ ret = gnutls_bye(tlss->tls_session, GNUTLS_SHUT_WR);
+ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ return;
+ }
+
+ tlss->disconnect.req = NULL;
+
+ if (gnutls_error_is_fatal(ret) != 0) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ tevent_req_done(req);
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+#endif /* ENABLE_GNUTLS */
+}
+
+static int tstream_tls_disconnect_recv(struct tevent_req *req,
+ int *perrno)
+{
+ int ret;
+
+ ret = tsocket_simple_int_recv(req, perrno);
+
+ tevent_req_received(req);
+ return ret;
+}
+
+static const struct tstream_context_ops tstream_tls_ops = {
+ .name = "tls",
+
+ .pending_bytes = tstream_tls_pending_bytes,
+
+ .readv_send = tstream_tls_readv_send,
+ .readv_recv = tstream_tls_readv_recv,
+
+ .writev_send = tstream_tls_writev_send,
+ .writev_recv = tstream_tls_writev_recv,
+
+ .disconnect_send = tstream_tls_disconnect_send,
+ .disconnect_recv = tstream_tls_disconnect_recv,
+};
+
+struct tstream_tls_params {
+#if ENABLE_GNUTLS
+ gnutls_certificate_credentials x509_cred;
+ gnutls_dh_params dh_params;
+#endif /* ENABLE_GNUTLS */
+ bool tls_enabled;
+};
+
+static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp)
+{
+#if ENABLE_GNUTLS
+ if (tlsp->x509_cred) {
+ gnutls_certificate_free_credentials(tlsp->x509_cred);
+ tlsp->x509_cred = NULL;
+ }
+ if (tlsp->dh_params) {
+ gnutls_dh_params_deinit(tlsp->dh_params);
+ tlsp->dh_params = NULL;
+ }
+#endif /* ENABLE_GNUTLS */
+ return 0;
+}
+
+bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp)
+{
+ return tlsp->tls_enabled;
+}
+
+NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
+ const char *ca_file,
+ const char *crl_file,
+ struct tstream_tls_params **_tlsp)
+{
+#if ENABLE_GNUTLS
+ struct tstream_tls_params *tlsp;
+ int ret;
+
+ ret = gnutls_global_init();
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
+ NT_STATUS_HAVE_NO_MEMORY(tlsp);
+
+ talloc_set_destructor(tlsp, tstream_tls_params_destructor);
+
+ ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (ca_file && *ca_file) {
+ ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
+ ca_file,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
+ ca_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ }
+
+ if (crl_file && *crl_file) {
+ ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
+ crl_file,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
+ crl_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ }
+
+ tlsp->tls_enabled = true;
+
+ *_tlsp = tlsp;
+ return NT_STATUS_OK;
+#else /* ENABLE_GNUTLS */
+ return NT_STATUS_NOT_IMPLEMENTED;
+#endif /* ENABLE_GNUTLS */
+}
+
+struct tstream_tls_connect_state {
+ struct tstream_context *tls_stream;
+};
+
+struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *plain_stream,
+ struct tstream_tls_params *tls_params,
+ const char *location)
+{
+ struct tevent_req *req;
+ struct tstream_tls_connect_state *state;
+#if ENABLE_GNUTLS
+ struct tstream_tls *tlss;
+ int ret;
+ static const int cert_type_priority[] = {
+ GNUTLS_CRT_X509,
+ GNUTLS_CRT_OPENPGP,
+ 0
+ };
+#endif /* ENABLE_GNUTLS */
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct tstream_tls_connect_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+#if ENABLE_GNUTLS
+ state->tls_stream = tstream_context_create(state,
+ &tstream_tls_ops,
+ &tlss,
+ struct tstream_tls,
+ location);
+ if (tevent_req_nomem(state->tls_stream, req)) {
+ return tevent_req_post(req, ev);
+ }
+ ZERO_STRUCTP(tlss);
+ talloc_set_destructor(tlss, tstream_tls_destructor);
+
+ tlss->plain_stream = plain_stream;
+
+ tlss->current_ev = ev;
+ tlss->retry_im = tevent_create_immediate(tlss);
+ if (tevent_req_nomem(tlss->retry_im, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ ret = gnutls_init(&tlss->tls_session, GNUTLS_CLIENT);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ ret = gnutls_set_default_priority(tlss->tls_session);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ gnutls_certificate_type_set_priority(tlss->tls_session, cert_type_priority);
+
+ ret = gnutls_credentials_set(tlss->tls_session,
+ GNUTLS_CRD_CERTIFICATE,
+ tls_params->x509_cred);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ gnutls_transport_set_ptr(tlss->tls_session, (gnutls_transport_ptr)state->tls_stream);
+ gnutls_transport_set_pull_function(tlss->tls_session,
+ (gnutls_pull_func)tstream_tls_pull_function);
+ gnutls_transport_set_push_function(tlss->tls_session,
+ (gnutls_push_func)tstream_tls_push_function);
+ gnutls_transport_set_lowat(tlss->tls_session, 0);
+
+ tlss->handshake.req = req;
+ tstream_tls_retry_handshake(state->tls_stream);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+ return tevent_req_post(req, ev);
+#endif /* ENABLE_GNUTLS */
+}
+
+int tstream_tls_connect_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ struct tstream_context **tls_stream)
+{
+ struct tstream_tls_connect_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_connect_state);
+
+ if (tevent_req_is_unix_error(req, perrno)) {
+ tevent_req_received(req);
+ return -1;
+ }
+
+ *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
+ tevent_req_received(req);
+ return 0;
+}
+
+extern void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *);
+
+/*
+ initialise global tls state
+*/
+NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
+ const char *dns_host_name,
+ bool enabled,
+ const char *key_file,
+ const char *cert_file,
+ const char *ca_file,
+ const char *crl_file,
+ const char *dhp_file,
+ struct tstream_tls_params **_tlsp)
+{
+ struct tstream_tls_params *tlsp;
+#if ENABLE_GNUTLS
+ int ret;
+
+ if (!enabled || key_file == NULL || *key_file == 0) {
+ tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
+ NT_STATUS_HAVE_NO_MEMORY(tlsp);
+ talloc_set_destructor(tlsp, tstream_tls_params_destructor);
+ tlsp->tls_enabled = false;
+
+ *_tlsp = tlsp;
+ return NT_STATUS_OK;
+ }
+
+ ret = gnutls_global_init();
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
+ NT_STATUS_HAVE_NO_MEMORY(tlsp);
+
+ talloc_set_destructor(tlsp, tstream_tls_params_destructor);
+
+ if (!file_exist(ca_file)) {
+ tls_cert_generate(tlsp, dns_host_name,
+ key_file, cert_file, ca_file);
+ }
+
+ ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (ca_file && *ca_file) {
+ ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
+ ca_file,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
+ ca_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ }
+
+ if (crl_file && *crl_file) {
+ ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
+ crl_file,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
+ crl_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ }
+
+ ret = gnutls_certificate_set_x509_key_file(tlsp->x509_cred,
+ cert_file, key_file,
+ GNUTLS_X509_FMT_PEM);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s - %s\n",
+ cert_file, key_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ ret = gnutls_dh_params_init(&tlsp->dh_params);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (dhp_file && *dhp_file) {
+ gnutls_datum_t dhparms;
+ size_t size;
+
+ dhparms.data = (uint8_t *)file_load(dhp_file, &size, 0, tlsp);
+
+ if (!dhparms.data) {
+ DEBUG(0,("TLS failed to read DH Parms from %s - %d:%s\n",
+ dhp_file, errno, strerror(errno)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ dhparms.size = size;
+
+ ret = gnutls_dh_params_import_pkcs3(tlsp->dh_params,
+ &dhparms,
+ GNUTLS_X509_FMT_PEM);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS failed to import pkcs3 %s - %s\n",
+ dhp_file, gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ } else {
+ ret = gnutls_dh_params_generate2(tlsp->dh_params, DH_BITS);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS failed to generate dh_params - %s\n",
+ gnutls_strerror(ret)));
+ talloc_free(tlsp);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ }
+
+ gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params);
+
+ tlsp->tls_enabled = true;
+
+#else /* ENABLE_GNUTLS */
+ tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
+ NT_STATUS_HAVE_NO_MEMORY(tlsp);
+ talloc_set_destructor(tlsp, tstream_tls_params_destructor);
+ tlsp->tls_enabled = false;
+#endif /* ENABLE_GNUTLS */
+
+ *_tlsp = tlsp;
+ return NT_STATUS_OK;
+}
+
+struct tstream_tls_accept_state {
+ struct tstream_context *tls_stream;
+};
+
+struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct tstream_context *plain_stream,
+ struct tstream_tls_params *tlsp,
+ const char *location)
+{
+ struct tevent_req *req;
+ struct tstream_tls_accept_state *state;
+ struct tstream_tls *tlss;
+#if ENABLE_GNUTLS
+ int ret;
+#endif /* ENABLE_GNUTLS */
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct tstream_tls_accept_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->tls_stream = tstream_context_create(state,
+ &tstream_tls_ops,
+ &tlss,
+ struct tstream_tls,
+ location);
+ if (tevent_req_nomem(state->tls_stream, req)) {
+ return tevent_req_post(req, ev);
+ }
+ ZERO_STRUCTP(tlss);
+ talloc_set_destructor(tlss, tstream_tls_destructor);
+
+#if ENABLE_GNUTLS
+ tlss->plain_stream = plain_stream;
+
+ tlss->current_ev = ev;
+ tlss->retry_im = tevent_create_immediate(tlss);
+ if (tevent_req_nomem(tlss->retry_im, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ ret = gnutls_init(&tlss->tls_session, GNUTLS_SERVER);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ ret = gnutls_set_default_priority(tlss->tls_session);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ ret = gnutls_credentials_set(tlss->tls_session, GNUTLS_CRD_CERTIFICATE,
+ tlsp->x509_cred);
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
+ gnutls_certificate_server_set_request(tlss->tls_session,
+ GNUTLS_CERT_REQUEST);
+ gnutls_dh_set_prime_bits(tlss->tls_session, DH_BITS);
+
+ gnutls_transport_set_ptr(tlss->tls_session, (gnutls_transport_ptr)state->tls_stream);
+ gnutls_transport_set_pull_function(tlss->tls_session,
+ (gnutls_pull_func)tstream_tls_pull_function);
+ gnutls_transport_set_push_function(tlss->tls_session,
+ (gnutls_push_func)tstream_tls_push_function);
+ gnutls_transport_set_lowat(tlss->tls_session, 0);
+
+ tlss->handshake.req = req;
+ tstream_tls_retry_handshake(state->tls_stream);
+ if (!tevent_req_is_in_progress(req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ return req;
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+ return tevent_req_post(req, ev);
+#endif /* ENABLE_GNUTLS */
+}
+
+static void tstream_tls_retry_handshake(struct tstream_context *stream)
+{
+ struct tstream_tls *tlss =
+ tstream_context_data(stream,
+ struct tstream_tls);
+ struct tevent_req *req = tlss->handshake.req;
+#if ENABLE_GNUTLS
+ int ret;
+
+ if (tlss->error != 0) {
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ ret = gnutls_handshake(tlss->tls_session);
+ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ return;
+ }
+
+ tlss->handshake.req = NULL;
+
+ if (gnutls_error_is_fatal(ret) != 0) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ if (ret != GNUTLS_E_SUCCESS) {
+ DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+ tlss->error = EIO;
+ tevent_req_error(req, tlss->error);
+ return;
+ }
+
+ tevent_req_done(req);
+#else /* ENABLE_GNUTLS */
+ tevent_req_error(req, ENOSYS);
+#endif /* ENABLE_GNUTLS */
+}
+
+int tstream_tls_accept_recv(struct tevent_req *req,
+ int *perrno,
+ TALLOC_CTX *mem_ctx,
+ struct tstream_context **tls_stream)
+{
+ struct tstream_tls_accept_state *state =
+ tevent_req_data(req,
+ struct tstream_tls_accept_state);
+
+ if (tevent_req_is_unix_error(req, perrno)) {
+ tevent_req_received(req);
+ return -1;
+ }
+
+ *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
+ tevent_req_received(req);
+ return 0;
+}
diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c
index 62e7a72240..bef634803a 100644
--- a/source4/lib/tls/tlscert.c
+++ b/source4/lib/tls/tlscert.c
@@ -138,15 +138,24 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx,
bufsize = sizeof(buf);
TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
- file_save(certfile, buf, bufsize);
+ if (!file_save(certfile, buf, bufsize)) {
+ DEBUG(0,("Unable to save certificate in %s parent dir exists ?\n", certfile));
+ goto failed;
+ }
bufsize = sizeof(buf);
TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
- file_save(cafile, buf, bufsize);
+ if (!file_save(cafile, buf, bufsize)) {
+ DEBUG(0,("Unable to save ca cert in %s parent dir exists ?\n", cafile));
+ goto failed;
+ }
bufsize = sizeof(buf);
TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
- file_save(keyfile, buf, bufsize);
+ if (!file_save(keyfile, buf, bufsize)) {
+ DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile));
+ goto failed;
+ }
gnutls_x509_privkey_deinit(key);
gnutls_x509_privkey_deinit(cakey);
diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript
new file mode 100644
index 0000000000..fc6fd8864f
--- /dev/null
+++ b/source4/lib/tls/wscript
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import Options
+from optparse import SUPPRESS_HELP
+
+def set_options(opt):
+ # allow users to disable gnutls
+ opt.add_option('--enable-gnutls',
+ help=("Enable use of gnutls"),
+ action="store_true", dest='enable_gnutls', default=True)
+ opt.add_option('--disable-gnutls', help=SUPPRESS_HELP, action="store_false", dest='enable_gnutls')
+
+
+def configure(conf):
+ conf.env.enable_gnutls = Options.options.enable_gnutls
+ if not conf.env.enable_gnutls:
+ conf.SET_TARGET_TYPE('gnutls', 'DISABLED')
+ conf.SET_TARGET_TYPE('gcrypt', 'DISABLED')
+ conf.SET_TARGET_TYPE('gpg-error', 'DISABLED')
+ return
+
+ conf.check_cfg(package='gnutls',
+ args='"gnutls >= 1.4.0 gnutls != 2.2.4 gnutls != 2.8.0 gnutls != 2.8.1" --cflags --libs',
+ msg='Checking for gnutls >= 1.4.0 and broken versions', mandatory=False)
+
+ if 'HAVE_GNUTLS' in conf.env:
+ conf.DEFINE('ENABLE_GNUTLS', 1)
+
+ conf.CHECK_FUNCS_IN('gnutls_global_init', 'gnutls',
+ headers='gnutls/gnutls.h')
+
+ conf.CHECK_VARIABLE('gnutls_x509_crt_set_version',
+ headers='gnutls/gnutls.h gnutls/x509.h',
+ define='HAVE_GNUTLS_X509_CRT_SET_VERSION',
+ lib='gnutls')
+ conf.CHECK_VARIABLE('gnutls_x509_crt_set_subject_key_id',
+ headers='gnutls/gnutls.h gnutls/x509.h',
+ define='HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID',
+ lib='gnutls')
+
+ # check for gnutls_datum types
+ conf.CHECK_TYPES('gnutls_datum gnutls_datum_t',
+ headers='gnutls/gnutls.h', lib='gnutls')
+
+ conf.CHECK_FUNCS_IN('gcry_control', 'gcrypt', headers='gcrypt.h')
+ conf.CHECK_FUNCS_IN('gpg_err_code_from_errno', 'gpg-error')
+
+
+def build(bld):
+ bld.SAMBA_SUBSYSTEM('LIBTLS',
+ source='tls.c tlscert.c tls_tstream.c',
+ public_deps='talloc gnutls gcrypt samba-hostconfig samba_socket LIBTSOCKET tevent UTIL_TEVENT'
+ )
diff --git a/source4/lib/wmi/config.mk b/source4/lib/wmi/config.mk
deleted file mode 100644
index 3bb1690c7b..0000000000
--- a/source4/lib/wmi/config.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-[SUBSYSTEM::WMI]
-PUBLIC_DEPENDENCIES = RPC_NDR_OXIDRESOLVER \
- NDR_DCOM \
- RPC_NDR_REMACT \
- NDR_TABLE \
- DCOM_PROXY_DCOM \
- DCOM
-
-WMI_OBJ_FILES = $(addprefix $(wmisrcdir)/, wmicore.o wbemdata.o ../../librpc/gen_ndr/dcom_p.o)
-
-#################################
-# Start BINARY wmic
-[BINARY::wmic]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- POPT_SAMBA \
- POPT_CREDENTIALS \
- LIBPOPT \
- WMI
-
-wmic_OBJ_FILES = $(wmisrcdir)/tools/wmic.o
-# End BINARY wmic
-#################################
-
-#################################
-# Start BINARY wmis
-[BINARY::wmis]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- POPT_SAMBA \
- POPT_CREDENTIALS \
- LIBPOPT \
- WMI
-
-wmis_OBJ_FILES = \
- $(wmisrcdir)/tools/wmis.o
-
-# End BINARY wmis
-#################################
-
-librpc/gen_ndr/dcom_p.c: idl
-
-#######################
-# Start LIBRARY swig_dcerpc
-[PYTHON::pywmi]
-PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBNDR LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI
-
-$(eval $(call python_py_module_template,wmi.py,$(wmisrcdir)/wmi.py))
-
-pywmi_OBJ_FILES = $(wmisrcdir)/wmi_wrap.o
-$(pywmi_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
-
-# End LIBRARY swig_dcerpc
-#######################
-
-#################################
-# Start BINARY pdhc
-#[BINARY::pdhc]
-#INSTALLDIR = BINDIR
-#OBJ_FILES = \
-# pdhc.o
-#PRIVATE_DEPENDENCIES = \
-# POPT_SAMBA \
-# POPT_CREDENTIALS \
-# LIBPOPT \
-# NDR_TABLE \
-# RPC_NDR_WINREG
-# End BINARY pdhc
-#################################
diff --git a/source4/lib/wmi/tools/wmic.c b/source4/lib/wmi/tools/wmic.c
index d37e22d44f..bbfe5ed334 100644
--- a/source4/lib/wmi/tools/wmic.c
+++ b/source4/lib/wmi/tools/wmic.c
@@ -35,91 +35,61 @@
#include "lib/wmi/wmi.h"
struct program_args {
- char *hostname;
- char *query;
- char *ns;
+ char *hostname;
+ char *query;
+ char *ns;
};
static void parse_args(int argc, char *argv[], struct program_args *pmyargs)
{
- poptContext pc;
- int opt, i;
-
- int argc_new;
- char **argv_new;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- POPT_COMMON_SAMBA
- POPT_COMMON_CONNECTION
- POPT_COMMON_CREDENTIALS
- POPT_COMMON_VERSION
- {"namespace", 0, POPT_ARG_STRING, &pmyargs->ns, 0,
- "WMI namespace, default to root\\cimv2", 0},
- POPT_TABLEEND
- };
-
- pc = poptGetContext("wmi", argc, (const char **) argv,
- long_options, POPT_CONTEXT_KEEP_FIRST);
-
- poptSetOtherOptionHelp(pc, "//host query\n\nExample: wmic -U [domain/]adminuser%password //host \"select * from Win32_ComputerSystem\"");
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- poptPrintUsage(pc, stdout, 0);
- poptFreeContext(pc);
- exit(1);
- }
-
- argv_new = discard_const_p(char *, poptGetArgs(pc));
-
- argc_new = argc;
- for (i = 0; i < argc; i++) {
- if (argv_new[i] == NULL) {
- argc_new = i;
- break;
- }
- }
-
- if (argc_new != 3 || argv_new[1][0] != '/'
- || argv_new[1][1] != '/') {
- poptPrintUsage(pc, stdout, 0);
- poptFreeContext(pc);
- exit(1);
- }
-
- pmyargs->hostname = argv_new[1] + 2;
- pmyargs->query = argv_new[2];
+ poptContext pc;
+ int opt, i;
+
+ int argc_new;
+ char **argv_new;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_SAMBA
+ POPT_COMMON_CONNECTION
+ POPT_COMMON_CREDENTIALS
+ POPT_COMMON_VERSION
+ {"namespace", 0, POPT_ARG_STRING, &pmyargs->ns, 0,
+ "WMI namespace, default to root\\cimv2", 0},
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext("wmi", argc, (const char **) argv,
+ long_options, POPT_CONTEXT_KEEP_FIRST);
+
+ poptSetOtherOptionHelp(pc, "//host query\n\nExample: wmic -U [domain/]adminuser%password //host \"select * from Win32_ComputerSystem\"");
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ poptPrintUsage(pc, stdout, 0);
poptFreeContext(pc);
-}
+ exit(1);
+ }
-static void escape_string(const char *src, char *dst, int len)
-{
- char *p = dst, *end = dst + len - 1;
- const char *q = src;
+ argv_new = discard_const_p(char *, poptGetArgs(pc));
- if ( q == NULL) {
- strncpy( dst, "(null)", len);
- return;
+ argc_new = argc;
+ for (i = 0; i < argc; i++) {
+ if (argv_new[i] == NULL) {
+ argc_new = i;
+ break;
}
+ }
- while ( *q && p <= end ) {
- if ( strchr( "|\\(),", *q)) {
- *p++ = '\\';
- *p++ = *q++;
- } else if ( *q == '\n' ) {
- *p++ = '\\';
- *p++ = 'n';
- q++;
- } else if ( *q == '\r' ) {
- *p++ = '\\';
- *p++ = 'r';
- q++;
- } else {
- *p++ = *q++;
- }
- }
+ if (argc_new != 3 || argv_new[1][0] != '/'
+ || argv_new[1][1] != '/') {
+ poptPrintUsage(pc, stdout, 0);
+ poptFreeContext(pc);
+ exit(1);
+ }
- *p++ = 0;
+ pmyargs->hostname = argv_new[1] + 2;
+ pmyargs->query = argv_new[2];
+ poptFreeContext(pc);
}
#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
@@ -129,33 +99,20 @@ static void escape_string(const char *src, char *dst, int len)
DEBUG(1, ("OK : %s\n", msg)); \
}
-#define RETURN_CVAR_ARRAY_STR_START(arr) {\
- uint32_t i;\
+#define RETURN_CVAR_ARRAY_STR(fmt, arr) {\
+ uint32_t i;\
char *r;\
\
- if (!arr) {\
- return talloc_strdup(mem_ctx, "(null)");\
- }\
+ if (!arr) {\
+ return talloc_strdup(mem_ctx, "NULL");\
+ }\
r = talloc_strdup(mem_ctx, "(");\
- for (i = 0; i < arr->count; ++i) {
-
-
-#define RETURN_CVAR_ARRAY_STR_END(fmt, arr, item) \
- r = talloc_asprintf_append(r, fmt "%s", item, (i+1 == arr->count)?"":",");\
- }\
- return talloc_asprintf_append(r, ")");\
+ for (i = 0; i < arr->count; ++i) {\
+ r = talloc_asprintf_append(r, fmt "%s", arr->item[i], (i+1 == arr->count)?"":",");\
+ }\
+ return talloc_asprintf_append(r, ")");\
}
-#define RETURN_CVAR_ARRAY_STR(fmt, arr) \
- RETURN_CVAR_ARRAY_STR_START(arr) \
- RETURN_CVAR_ARRAY_STR_END(fmt, arr, arr->item[i])
-
-#define RETURN_CVAR_ARRAY_ESCAPED(fmt, arr) \
- RETURN_CVAR_ARRAY_STR_START(arr) \
- char buf[2048]; \
- escape_string( arr->item[i], buf, 2048); \
- RETURN_CVAR_ARRAY_STR_END(fmt, arr, buf)
-
char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATION cimtype)
{
switch (cimtype) {
@@ -172,11 +129,7 @@ char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATI
case CIM_BOOLEAN: return talloc_asprintf(mem_ctx, "%s", v->v_boolean?"True":"False");
case CIM_STRING:
case CIM_DATETIME:
- case CIM_REFERENCE: {
- char buf[2048];
- escape_string((char*) v-> v_string, buf, 2048);
- return talloc_asprintf(mem_ctx, "%s", buf);
- }
+ case CIM_REFERENCE: return talloc_asprintf(mem_ctx, "%s", v->v_string);
case CIM_CHAR16: return talloc_asprintf(mem_ctx, "Unsupported");
case CIM_OBJECT: return talloc_asprintf(mem_ctx, "Unsupported");
case CIM_ARR_SINT8: RETURN_CVAR_ARRAY_STR("%d", v->a_sint8);
@@ -190,9 +143,9 @@ char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATI
case CIM_ARR_REAL32: RETURN_CVAR_ARRAY_STR("%f", v->a_real32);
case CIM_ARR_REAL64: RETURN_CVAR_ARRAY_STR("%f", v->a_real64);
case CIM_ARR_BOOLEAN: RETURN_CVAR_ARRAY_STR("%d", v->a_boolean);
- case CIM_ARR_STRING: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_string);
- case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_datetime);
- case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_reference);
+ case CIM_ARR_STRING: RETURN_CVAR_ARRAY_STR("%s", v->a_string);
+ case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_STR("%s", v->a_datetime);
+ case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_STR("%s", v->a_reference);
default: return talloc_asprintf(mem_ctx, "Unsupported");
}
}
diff --git a/source4/lib/wmi/wscript_build b/source4/lib/wmi/wscript_build
new file mode 100644
index 0000000000..59e0ce584a
--- /dev/null
+++ b/source4/lib/wmi/wscript_build
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+
+bld.SAMBA_SUBSYSTEM('WMI',
+ source='wmicore.c wbemdata.c ../../../librpc/gen_ndr/dcom_p.c',
+ public_deps='RPC_NDR_OXIDRESOLVER NDR_DCOM RPC_NDR_REMACT ndr_table DCOM_PROXY_DCOM DCOM'
+ )
+
+
+bld.SAMBA_BINARY('wmic',
+ source='tools/wmic.c',
+ deps='POPT_SAMBA POPT_CREDENTIALS popt WMI'
+ )
+
+
+bld.SAMBA_BINARY('wmis',
+ source='tools/wmis.c',
+ deps='POPT_SAMBA POPT_CREDENTIALS popt WMI'
+ )
+
+
+bld.SAMBA_PYTHON('pywmi',
+ source='wmi_wrap.c',
+ public_deps='LIBCLI_SMB ndr samba-util samba-config WMI'
+ )
+
diff --git a/source4/lib/wscript_build b/source4/lib/wscript_build
new file mode 100644
index 0000000000..cf60820da7
--- /dev/null
+++ b/source4/lib/wscript_build
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+bld.SAMBA_SUBSYSTEM('GENCACHE',
+ source='../../source3/lib/gencache.c',
+ enabled=False,
+ deps='tdb-wrap'
+ )
diff --git a/source4/lib/zlib.mk b/source4/lib/zlib.mk
deleted file mode 100644
index 5c5e6e69ba..0000000000
--- a/source4/lib/zlib.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-[SUBSYSTEM::ZLIB]
-CFLAGS = -I$(zlibsrcdir)
-
-ZLIB_OBJ_FILES = \
- $(zlibsrcdir)/adler32.o \
- $(zlibsrcdir)/compress.o \
- $(zlibsrcdir)/crc32.o \
- $(zlibsrcdir)/gzio.o \
- $(zlibsrcdir)/uncompr.o \
- $(zlibsrcdir)/deflate.o \
- $(zlibsrcdir)/trees.o \
- $(zlibsrcdir)/zutil.o \
- $(zlibsrcdir)/inflate.o \
- $(zlibsrcdir)/infback.o \
- $(zlibsrcdir)/inftrees.o \
- $(zlibsrcdir)/inffast.o